2010-01-18 57 views
6

我需要一個CString實例轉換爲正確分配BSTR並傳遞BSTR到COM方法。要使編碼和ANSI和Unicode統一工作的代碼我使用CString::AllocSysString()將任何格式CString轉換爲Unicode BSTR。如何最好地將CString轉換爲BSTR以將它作爲「in」參數傳遞給COM方法?

因爲沒有人擁有返回BSTR我需要照顧它,並釋放該呼叫在最異常安全的方式更多鈔票,用盡可能少的代碼可能完成之後。

目前我使用ATL::CComBSTR的生命週期管理:

ATL::CComBSTR converted; 
converted.Attach(sourceString.AllocSysString()); //simply attaches to BSTR, doesn't reallocate it 
interface->CallMethod(converted); 

什麼,我不喜歡這裏,我需要兩個單獨的語句,只是構建綁定到皈依結果ATL::CComBSTR

有沒有更好的方法來完成同樣的任務?

回答

14

CComBSTR重載了兩個char*wchar_t*構造,這代表您調用SysAllocString()。所以你的代碼片段中的顯式分配實際上是不必要的。下面將工作一樣好:

ATL::CComBSTR converted = sourceString; 
interface->CallMethod(converted); 

此外,如果您有沒有必要在你的代碼中使用的轉換BSTR其他地方,你可以在方法調用執行就地對象結構,像這樣:

interface->CallMethod(ATL::CComBSTR(sourceString)); 

這同樣適用於_bstr_t類,它可以被用來代替CComBSTR如果你不想在ATL的依賴也。

+0

這肯定會工作,除了使用CComBSTR構造函數,我將不得不檢查BSTR分配是否成功(CString :: AllocSysString()執行檢查並引發異常),並且使用_bstr_t我必須處理_com_issue_error()函數 - 覆蓋它或捕獲拋出的_com_error。 – sharptooth 2010-01-19 14:08:00

+0

爲什麼不讓被調用的方法負責檢查自己的參數的有效性呢?如果分配失敗,「CComBSTR :: m_str」將爲空。所以無論是被調用的方法都會檢查null並返回'E_INVALIDARG',或者它不會和你已經擁有的'CString :: AllocSysString()'相同的'catch'可以爲你處理異常。這是一個更清潔的成語,而不是明確地執行自己的檢查,恕我直言。 – 2010-01-19 14:56:17

+1

@Phil Booth:被調用的方法可能將空BSTR解釋爲特例。例如,含義可以是「指定文件名,如果傳遞空字符串,則使用默認文件名」。所以被調用的方法可能沒有機會知道存在問題。 – sharptooth 2010-01-25 11:24:47

2

Windows編程令人困惑的一個方面是管理Visual Basic樣式字符串到C語言樣式字符串的轉換。這並非如此困難,只是難以記住細節。它通常不會經常進行,MSDN文檔非常龐大,很難找到您的問題的答案。但是,最糟糕的部分是你可以執行一些編譯好的類型轉換,但是不能按照你期望的方式工作。這會導致代碼無法正常工作,並且很難追蹤錯誤。經過一些經驗後,您將學會確保您的字符串轉換符合您的期望。

C字符串是由NULL字符終止的字符數組。 Visual Basic字符串的不同之處在於字符串的長度在字符串中的字符之前。所以,一個VB字符串知道它自己的長度。另外,所有VB字符串都是Unicode(每個字符16位)。

You are doing COM programming in C/C++ 
You are writing multiple language applications, such as C++ DLL's accessed by Visual Basic applications. 
1

一個_bstr_t構造,您只需連接到現有BSTR,這樣你可以有不同的是,你從CString::AllocSysString希望在BSTR分配: 字符串類型

BSTR/C字符串的轉換如果需要的話失敗。

// _bstr_t simply attaches to BSTR, doesn't reallocate it 
interface->CallMethod(_bstr_t(sourceString.AllocSysString(), false)); 

_bstr_t constructor documentation說:

_bstr_t(
    BSTR bstr, 
    bool fCopy 
); 

fCopy
如果爲false,bstr參數附加到新的對象,而無需通過調用SysAllocString製作副本。

另一方面,CComBSTR constructor似乎沒有相應的簽名;儘管如果BSTR分配失敗異常不是真的需要,也可以使用它,如his answer中的Phil Booth所述。

相關問題