从 C++ 传递 BSTR DLL 函数到 VB6 应用程序
我的 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
的类型定义为 LPCSTR
。该参数完美地进入我的 DLL,但无论我尝试传回什么,VB6 应用程序都只显示垃圾。我使用 SysAllocStringByteLength
尝试了几种不同的方法,将 SysAllocString
参数转换为 LPCWSTR
和其他变体。要么我只看到字符串的第一个字母,要么我只看到带点的 Y,而不是真正的字符串。有谁知道创建有效 BSTR 并将其从 C++ 传递到 VB6 的真正方法是什么?
I have this code in my VB6 app:
Private Declare Function FileGetParentFolder Lib "Z-FileIO.dll" _
(ByVal path As String) As String
Output.AddItem FileGetParentFolder(FileText.Text)
Output is a list, FileText is a text field containing a file path. My C++ DLL contains this function:
extern "C" BSTR ZFILEIO_API FileGetParentFolder(Path p)
{
try {
return SysAllocString(boost::filesystem::path(p).parent_path().c_str());
} catch (...) {
return SysAllocString(L"");
}
}
where Path
is typedef'd as LPCSTR
. The argument comes into my DLL perfectly, but whatever I try to pass back, the VB6 app shows only garbage. I tried several different methods with SysAllocStringByteLength
, casting the SysAllocString
argument to LPCWSTR
and other variants. Either, I only see the first letter of the string, or I see only Y's with dots, just not the real string. Does anyone know what the real method is for creating and passing valid BSTRs from C++ to VB6?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
希望这将为您指明正确的方向。根据记忆...
VB6 在内部使用 COM BSTR(2 字节宽字符串),但在与外部 DLL 通信时,它使用单字节或多字节字符串。 (可能是 UTF-8,但我不太记得了。)您的 LPCSTR 的 Path typedef 是一个 ANSI 字符串,这就是您可以正确接收它的原因。您生成的返回值是一个宽字符字符串,但 VB 需要一个 ANSI 字符串。在返回之前,您需要使用 WideCharToMultiByte 来转换返回值。
VB 执行这种隐式转换似乎有点奇怪,但事实就是如此。 (据我所知。)
Hopefully this will point you in the right direction. From memory...
VB6 uses COM BSTRs (2-byte wide character strings) internally, but when communicating with external DLLs it uses single- or multi-byte strings. (Probably UTF-8, but I don't remember for sure.) Your Path typedef to LPCSTR is an ANSI string, and that's why you can receive it correctly. The return value you generate is a wide-character string, but VB is expecting an ANSI string. You'll need to use WideCharToMultiByte to convert your return value before returning it.
Seems a little odd that VB does this implicit conversion, but that's the way it is. (As far as I remember.)
如果您坚持使用函数签名,那么您必须为 VB6 准备一个自定义类型库,其中包含此
在
Declare
的参数类型As String
中自动转换为 ANSI 字符串,即LPSTR
。传递/接收 unicode 字符串(LPWSTR
或BSTR
)的唯一方法是使用 typelib API 函数声明。除此之外,您始终可以在声明中使用
As Long
参数并期望LPWSTR
,但消费者必须将字符串包装在StrPtr
中每次调用 API 函数。If you insist on using the function signature then you have to prepare a custom typelib for VB6 that includes this
In
Declare
s param-typesAs String
are automagically converted to ANSI string, i.e.LPSTR
. The only way to pass/receive a unicode string (LPWSTR
orBSTR
) is by using typelib API function declaration.Other than that you can always use
As Long
params in the declaration and expectLPWSTR
s but then the consumer will have to wrap strings inStrPtr
on every call to the API function.