我在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的真正方法是什么?
答案 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字符串(LPWSTR
或BSTR
)的唯一方法是使用typelib API函数声明。
除此之外,你总是可以在声明中使用As Long
参数并期望LPWSTR
但是消费者必须在每次调用API函数时在StrPtr
中包装字符串。