2017-07-06 65 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);