Reputation: 391
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.
Upvotes: 2
Views: 2726
Reputation: 391
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:
Dim file_name_in As String * 256
Dim file_name_out As String * 256
Dim ErrMsg As String * 256
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.
Upvotes: 0
Reputation: 941357
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.
int __stdcall myFunc(BSTR filename_in, BSTR filename_out, BSTR* ErrMsg);
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".
Upvotes: 3
Reputation: 11991
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.
Upvotes: 2