VB6 - 如何通过.tlb文件将字符串传递给用C编写的DLL

时间:2011-03-08 11:33:12

标签: c windows dll vb6 idl

我正在使用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调用它?

感谢。

3 个答案:

答案 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)

感谢GSergwqw我找到了解决此问题的方法:

在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。