我正在使用VB6编写的图形界面,我必须调用用C编写的某个DLL中包含的函数。由于known limitation我必须实现允许的trick我以隐式的方式加载这个DLL。
这可以创建一个IDL文件,使用MIDL编译它并在VB6项目中引用生成的.tlb文件。
问题是VB6的字符串和C的char数组不匹配,所以我无法将它们传递给DLL(并将其取回)。
C函数的原型是:
int __stdcall myFunc(char filename_in[], char filename_out[], char ErrMsg[]);
我应该在IDL文件中写什么以及如何从VB6调用它?
感谢。
答案 0 :(得分:3)
您必须使用BSTR来使用VB6兼容字符串。它是标准的COM字符串类型,它以utf-16编码存储Unicode字符串,就像Win32 api一样。
int __stdcall myFunc(BSTR filename_in, BSTR filename_out, BSTR* ErrMsg);
您可以直接将args转换为WCHAR *,如果需要转换为char *(最好避免使用),请使用WideCharToMultiByte()。如果*ErrMsg
不为null,则在分配现有字符串之前使用SysFreeString释放现有字符串。使用SysAllocString分配ErrMsg字符串。它必须是一个utf-16字符串,MultiByteToWideChar()如果需要再次从char *转换。或者使用以L为前缀的字符串文字,如L“Oops”。
答案 1 :(得分:2)
VB6使用ANSI字符串参数消耗stdcall函数没有问题。只需在IDL中使用[in] LPSTR filename_in
,运行时就可以自动执行UNICODE< - > ANSI转换。
“魔法”也适用于[out]
参数。
答案 2 :(得分:0)
在IDL文件中,char数组应声明为LPSTR,因此该函数的原型如下所示:
int _stdcall myFunc(LPSTR file_name_in, LPSTR file_name_out, LPSTR ErrMsg)
请注意,ErrMsg
的声明与其他数组完全相同,即使它包含输出消息(在VB6端可读)。
在VB6端,字符串应分配为:
Dim file_name_in As String * 256
Dim file_name_out As String * 256
Dim ErrMsg As String * 256
这样做这些字符串的大小有限256
,因此与C DLL中的char数组兼容。
希望这会帮助别人。
此致
G.B。