如何通过time_t或简单地通过COM的日期信息
问题描述:
我有一个公开COM接口的Visual C++ ATL项目。如何通过time_t或简单地通过COM的日期信息
从我的界面,我打电话到FlexNet Publisher库。我需要从这些库中返回一个日期,这些库揭示了time_t
对象(我知道它们的库容易受到32位系统上的2038错误的影响)。
我的IDL文件有一个方法需要返回这个日期。
鉴于我可以获取time_t
,我如何通过COM接口边界将它的日期信息传递给使用COM对象的客户端应用程序?我是否应该将time_t
作为__int64
并在我的IDL中将其定义为__int64
?这里有什么是正确的?标准方式是什么?
答
我推荐使用符合oleautomation标准的DATE
类型。
要转换您现有的time_t
类型,请使用ATL提供的COleDateTime类。其中一个constructors接受time_t
值并将其解析为其等效值DATE
的值。
答
正确的方法是使用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
,只是包装的DATE
在VARIANT
结构。
// 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);