将BSTR从C ++ DLL函数传递给VB6应用程序

时间:2011-05-26 06:39:32

标签: c++ vb6 bstr

我在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 个答案:

答案 0 :(得分:2)

希望这会指出你正确的方向。从记忆......

VB6在内部使用COM BSTR(2字节宽字符串),但在与外部DLL通信时,它使用单字节或多字节字符串。 (可能是UTF-8,但我不记得了。)你对LPCSTR的路径类型是一个ANSI字符串,这就是你能正确接收它的原因。您生成的返回值是一个宽字符串,但VB期望一个ANSI字符串。在返回之前,您需要使用WideCharToMultiByte转换返回值。

VB做这种隐式转换似乎有点奇怪,但就是这样。 (据我记得。)

答案 1 :(得分:2)

如果你坚持使用函数签名,那么你必须为VB6准备一个包含这个的自定义类型库

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

Declare中,参数类型As String自动转换为ANSI字符串,即LPSTR。传递/接收unicode字符串(LPWSTRBSTR)的唯一方法是使用typelib API函数声明。

除此之外,你总是可以在声明中使用As Long参数并期望LPWSTR但是消费者必须在每次调用API函数时在StrPtr中包装字符串。