VB6 - 如何通过 .tlb 文件将字符串传递到用 C 编写的 DLL
我正在开发一个用 VB6 编写的图形界面,我必须调用用 C 编写的某个 DLL 中包含的函数。由于 已知限制 我必须实施一个技巧 允许我以隐式方式加载这个 DLL。
可以创建一个 IDL 文件,使用 MIDL 对其进行编译,并在 VB6 项目中引用生成的 .tlb 文件。
问题是 VB6 字符串和 C 字符数组不匹配,因此我无法将它们传递(并返回)到 DLL。
C函数的原型是:
int __stdcall myFunc(char filename_in[], char filename_out[], char ErrMsg[]);
我应该在IDL文件中写什么以及如何调用它VB6?
谢谢。
I'm working on a graphical interface written in VB6, where I have to call function contained in a certain DLL written in C. Because of a known limitation I had to implement a trick that allows me to load this DLL in a implicit way.
This is possible creating an IDL file, compile it with MIDL and reference the resulting .tlb file in the VB6 project.
The problem is that VB6 strings and C arrays of char do not match, so I can't pass (and get back) them to the DLL.
The prototype of the C function is:
int __stdcall myFunc(char filename_in[], char filename_out[], char ErrMsg[]);
What should I write in the IDL file and how should I call it from VB6?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须使用 BSTR 才能使用 VB6 兼容字符串。它是标准的COM字符串类型,它以utf-16编码存储Unicode字符串,就像Win32 api一样。
您可以将 in args 直接转换为 WCHAR*,如果需要转换为 char*(最好避免),请使用 WideCharToMultiByte()。如果
*ErrMsg
不为 null,请使用 SysFreeString 在分配现有字符串之前将其释放。使用SysAllocString 分配ErrMsg 字符串。它也必须是 utf-16 字符串,如果需要再次从 char* 转换,可以使用 MultiByteToWideChar()。或者使用以 L 为前缀的字符串文字,例如 L"Oops"。You must use BSTR to use VB6 compatible strings. It is the standard COM string type, it stores Unicode strings in utf-16 encoding, just like the Win32 api.
You can cast the in args to WCHAR* directly, use WideCharToMultiByte() if you need to convert to char* (best avoided). Use SysFreeString if
*ErrMsg
is not null to release an existing string before assigning it. Use SysAllocString to allocate the ErrMsg string. It must be a utf-16 string as well, MultiByteToWideChar() if necessary again to convert from char*. Or use a string literal that's prefixed with L, like L"Oops".VB6 使用带有 ANSI 字符串参数的 stdcall 函数没有问题。只需在 IDL 中使用
[in] LPSTR filename_in
,运行时就会自动进行 UNICODE<->ANSI 转换。“魔法”也适用于
[out]
参数。VB6 has no problems consuming stdcall functions with ANSI strings params. Just use
[in] LPSTR filename_in
in IDL and the run-time does the UNICODE<->ANSI conversion automagically.The "magic" works for
[out]
params too.感谢 GSerg 和 wqw< /a> 我找到了这个问题的解决方案:
在 IDL 文件中,字符数组应声明为 LPSTR,因此函数的原型如下所示:
int _stdcall myFunc(LPSTR file_name_in, LPSTR file_name_out, LPSTR ErrMsg)< /code>
请注意,
ErrMsg
的声明与其他数组完全相同,即使它包含输出消息(在 VB6 端可读)。在 VB6 端,字符串应分配为:
这样做,这些字符串的分配大小有限为 256,从而与 C DLL 中的字符数组兼容。
希望这会帮助别人。
问候,
GB
Thanks to GSerg and wqw I found the solution to this problem:
In the IDL file the char arrays should be declared as LPSTR, so the prototype of the function looks like:
int _stdcall myFunc(LPSTR file_name_in, LPSTR file_name_out, LPSTR ErrMsg)
note that
ErrMsg
is declared exactly as the other arrays, even if it will contains an output message (readable on the VB6 side).On the VB6 side the strings should be allocated as:
Doing so these strings are allocated with a limited size of
256
, thus being compatible with the char arrays in the C DLL.Hope this will help someone else.
Regards,
G.B.