2

我正在开发一个用 VB6 编写的图形界面,我必须在其中调用某个用 C 编写的 DLL 中包含的函数。由于已知的限制,我必须实现一个技巧,允许我以隐式方式加载此 DLL。

这可以创建一个 IDL 文件,用 MIDL 编译它并在 VB6 项目中引用生成的 .tlb 文件。

问题是 char 的 VB6 字符串和 C 数组不匹配,所以我无法将它们传递(并返回)给 DLL。

C函数的原型是:

int __stdcall myFunc(char filename_in[], char filename_out[], char ErrMsg[]);

我应该在 IDL 文件中写什么以及如何从 VB6 中调用它?

谢谢。

4

3 回答 3

3

您必须使用 BSTR 才能使用 VB6 兼容的字符串。它是标准的 COM 字符串类型,它以 utf-16 编码存储 Unicode 字符串,就像 Win32 api 一样。

 int __stdcall myFunc(BSTR filename_in, BSTR filename_out, BSTR* ErrMsg);

您可以将 in args 直接转换为 WCHAR*,如果需要转换为 char*,请使用 WideCharToMultiByte()(最好避免)。如果不为空,则使用 SysFreeString*ErrMsg在分配现有字符串之前释放它。使用 SysAllocString 分配 ErrMsg 字符串。它也必须是一个 utf-16 字符串,MultiByteToWideChar() 如果需要再次从 char* 转换。或者使用以 L 为前缀的字符串文字,例如 L"Oops"。

于 2011-03-08T14:15:24.347 回答
2

VB6 使用带有 ANSI 字符串参数的 stdcall 函数没有问题。只需[in] LPSTR filename_in在 IDL 中使用,运行时就会自动执行 UNICODE<->ANSI 转换。

“魔法”[out]也适用于参数。

于 2011-03-08T14:15:08.980 回答
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 数组兼容。

希望这对其他人有帮助。

问候,

国标

于 2011-03-08T14:44:30.980 回答