2009-02-23 62 views
3

到目前爲止,我發現我可以進來BSTRs轉換爲ANSI兩個(很多嗎?)的方式,我很好奇,想知道一個人是否是相對比其他「更好」速度/效率等這是在C/C++轉換BSTR參數以ANSI更好的代碼?

我一直在使用了一段時間的方法是使用USES_CONVERSIONW2A宏,如

BSTR __stdcall F(BSTR p1, BSTR p2) { 
    USES_CONVERSION; 

    LPSTR sNum1 = W2A(p1); 
    LPSTR sNum2 = W2A(p2); 

然而,最近我碰到另一種技術來:

BSTR __stdcall F(BSTR p1, BSTR p2) { 
    long amt = wcstombs(NULL, p1, 1); 
    sNum1 = (char *) malloc(amt); 
    wcstombs(sNum1, p1, amt); 
    *(sNum1 + amt) = '\0'; 

    amt = wcstombs(NULL, p2, 1); 
    sNum2 = (char *) malloc(amt); 
    wcstombs(sNum2, p2, amt); 
    *(sNum2 + amt) = '\0'; 

現在我承認,這是wordier,並有兩個呼叫wcstombs但我認識的USES_CONVERSIONW2A宏可能隱藏各種各樣的樂趣和遊戲。

哪個是更有效的/更快的代碼?或者,我還有另外一種技術可以更好地完成這項工作嗎?

+0

第二個代碼是未定義行爲,因爲它寫超越分配的緩衝區結束。 – 2009-02-23 07:18:19

回答

3

請注意Nick在批准的答案中,雖然正確的共享相同的問題,但MSDN文檔描述了這些宏。

問題是一些宏如@Nick-COLE2A列出的宏實際上並不存在。

然而,進一步在MSDN頁面下方有一些文字可以幫助您瞭解這一事實,並能夠找出正確的宏!

的文本在表格下面的文本中列出:

有上了年紀的字符串轉換宏和新的字符串轉換類之間的一些重要區別:

在新ATL 7.0轉換類列。

它說:

OLE總是等價至W

所以在@尼克的例子宏實際上是CW2A

+0

討厭......感謝那些信息。很有幫助。 – bugmagnet 2010-03-05 03:52:36

6

MSDN

[...]轉換和從BSTR字符串的推薦方法是使用CComBSTR類。要轉換爲BSTR,請將現有字符串傳遞給CComBSTR的構造函數。要從BSTR轉換,請使用COLE2 [C] DestinationType [EX],例如COLE2T。

從頁面的CComBSTR:

[...]的的CComBSTR類提供了許多采取ANSI或Unicode字符串作爲參數的成員(構造函數,賦值運算符和比較運算符)的。這些函數的ANSI版本效率低於其Unicode編碼,因爲臨時Unicode字符串通常是在內部創建的。爲了提高效率,儘可能使用Unicode版本。

3

注:

如果使用ATL宏,如:COLE2 [C] DestinationType [例](你可能應該),一定要使用 'C' 版本的可能,而不是你寫的非const版本。它們對於明確的BSTR-> ASCII轉換(即:COLE2A)可能是等價的,但對於沒有實際轉換所需的轉換(例如:編譯UNICODE時爲COLE2T),'C'版本可擴展爲noops,而非-'C」版本仍將複製如果源字符串是常量(因爲你表達你所需要的結果字符串是非常量)。

值得注意的還有:

新ATL7宏並不總是需要USES_CONVERSION,但它們分配臨時r值對象,而老宏使用_alloca。這可能是也可能不是重要的,這取決於您的使用(例如,不使用舊的宏在其中運行的大量次的循環,可以吹出來的堆棧這樣做)。

1

我已經用COM或BSTR做了很長的一段時間,但我的建議是停止將BSTR視爲特殊的東西。把它們看作一個指向寬字符零終止字符串的指針......如果你這樣做,可能會更容易將它們轉換爲ANSI。檢查Eric's Complete Guide to BSTR Semantics ...