2017-07-06 46 views
1

我有一个公开COM接口的Visual C++ ATL项目。如何通过time_t或简单地通过COM的日期信息

从我的界面,我打电话到FlexNet Publisher库。我需要从这些库中返回一个日期,这些库揭示了time_t对象(我知道它们的库容易受到32位系统上的2038错误的影响)。

我的IDL文件有一个方法需要返回这个日期。

鉴于我可以获取time_t,我如何通过COM接口边界将它的日期信息传递给使用COM对象的客户端应用程序?我是否应该将time_t作为__int64并在我的IDL中将其定义为__int64?这里有什么是正确的?标准方式是什么?

回答

2

我推荐使用符合oleautomation标准的DATE类型。

要转换您现有的time_t类型,请使用ATL提供的COleDateTime类。其中一个constructors接受time_t值并将其解析为其等效值DATE的值。

1

正确的方法是使用DATE类型或VARIANT。要从time_t到达那里,需要进行一些转换。

标头下面的代码:

#include <windows.h> 
#include <comdef.h> 
#include <oleauto.h> 
#include <time.h> 
#include <exception> 

首先,拿到C++ time_t要转换。

// get the time_t to convert 
time_t cpp_time = ...; 

然后,转换C++ time_t到Windows FILETIME。 (这部分已从here中解除)。

// convert C++ time_t to Windows FILETIME 
FILETIME windows_file_time; 
{ 
    auto ll = Int32x32To64(cpp_time, 10000000) + 116444736000000000; 
    windows_file_time.dwLowDateTime = (DWORD)ll; 
    windows_file_time.dwHighDateTime = ll >> 32; 
} 

然后,在Windows FILETIME转换到Windows SYSTEMTIME

// convert Windows FILETIME to Windows SYSTEMTIME 
SYSTEMTIME windows_system_time; 
if (!FileTimeToSystemTime(&windows_file_time, &windows_system_time)) 
    throw new std::exception(); 

最后,在Windows SYSTEMTIME转换为VARIANT DATE

// convert Windows FILETIME to VARIANT DATE 
DATE variant_date; 
if (SystemTimeToVariantTime(&windows_system_time, &variant_date) != TRUE) 
    throw new std::exception(); 

如果你想验证以上的作品,您可以将DATE转换为字符串(BSTR)。

// convert DATE to string (for verification purposes) 
bstr_t variant_date_string; 
if (FAILED(VarBstrFromDate(variant_date, 0, 0, variant_date_string.GetAddress()))) 
    throw new std::exception(); 
OutputDebugStringW(variant_date_string); 

如果您需要/想使用VARIANT代替DATE,只是包装的DATEVARIANT结构。

// wrap DATE in a VARIANT 
VARIANT v_variant_date; 
v_variant_date.date = variant_date; 
v_variant_date.vt = VT_DATE; 

为了验证这部分的工作,你可以说VARIANT转换为字符串(BSTR)。

// convert VARIANT to string (for verification purposes) 
variant_t v_variant_date_string; 
v_variant_date_string.ChangeType(VT_BSTR, &v_variant_date); 
OutputDebugStringW(v_variant_date_string.bstrVal);