1

我的 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"");
    }
}

Pathtypedef 的位置在哪里LPCSTR。该论点完美地进入了我的 DLL,但无论我试图传回什么,VB6 应用程序都只显示垃圾。我尝试了几种不同的方法SysAllocStringByteLength,将SysAllocString参数转换为LPCWSTR和其他变体。要么,我只看到字符串的第一个字母,要么只看到带点的 Y,而不是真正的字符串。有谁知道从 C++ 创建和传递有效 BSTR 到 VB6 的真正方法是什么?

4

2 回答 2

2

希望这将为您指明正确的方向。从记忆里...

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

VB 进行这种隐式转换似乎有点奇怪,但事实就是这样。(就目前我所记得的。)

于 2011-05-26T07:00:18.857 回答
2

如果您坚持使用函数签名,那么您必须为 VB6 准备一个自定义类型库,其中包括

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

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

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

于 2011-05-26T08:21:55.353 回答