2011-05-26 95 views
1

我有這樣的代碼在我的VB6應用程序:通BSTR從C++ DLL函數VB6應用

Private Declare Function FileGetParentFolder Lib "Z-FileIO.dll" _ 
(ByVal path As String) As String 

Output.AddItem FileGetParentFolder(FileText.Text) 

輸出是一個列表,FILETEXT是包含一個文件路徑文本字段。我的C++ DLL包含此功能:

extern "C" BSTR ZFILEIO_API FileGetParentFolder(Path p) 
{ 
    try { 
     return SysAllocString(boost::filesystem::path(p).parent_path().c_str()); 
    } catch (...) { 
     return SysAllocString(L""); 
    } 
} 

其中Path被typedef爲LPCSTR。該參數完美地進入我的DLL,但無論我嘗試傳回,VB6應用程序只顯示垃圾。我用SysAllocStringByteLength嘗試了幾種不同的方法,將SysAllocString的參數投射到LPCWSTR和其他變體。或者,我只看到字符串的第一個字母,或者我只看到帶點的Y,而不是真正的字符串。有沒有人知道真正的方法是什麼創建和傳遞有效的BSTR從C++到VB6?

回答

2

希望這會指出你在正確的方向。從內存中...

VB6在內部使用COM BSTR(2字節寬的字符串),但是當與外部DLL通信時,它使用單字節或多字節字符串。 (可能是UTF-8,但我不確定。)LPCSTR的Path typedef是ANSI字符串,這就是爲什麼您可以正確接收它。您生成的返回值是一個寬字符的字符串,但VB期待ANSI字符串。在返回之前,您需要使用WideCharToMultiByte來轉換您的返回值。

似乎有點奇怪,VB做這種隱式轉換,但這是它的方式。 (據我記得)。

+0

+1另請參見[Microsoft關於從VB調用C DLls的注意事項](http://vb.mvps.org/tips/vb5dll.asp)。寫爲VB5,但從未更新爲VB6。但是它與VB6相關的是99.9%。所有在主持這個文件的[美妙的VB6站點](http://vb.mvps.org/) – MarkJ 2011-05-26 11:17:37

2

如果你堅持使用函數簽名,那麼你必須準備VB6的自定義類型庫包括該

[dllname("Z-FileIO.dll")] 
module ZFileIO 
{ 
    [entry("FileGetParentFolder")] 
    BSTR FileGetParentFolder ([in] LPWSTR path); 
}; 

Declare小號PARAM類型As String被自動轉換爲ANSI字符串,即LPSTR。傳遞/接收一個unicode字符串(LPWSTRBSTR)的唯一方法是使用typelib API函數聲明。

以外,你可以隨時使用在聲明As Long PARAMS和期待LPWSTR秒,但隨後消費者將必須包裝在每次調用API函數的字符串StrPtr