C/C++ DLLs for use with VB in 32-bits
Posted on 1997-08-27
I have a bunch of DLLs with exported functions (basically it's an API) for use by other people using, for example, VB, or C/C++, or PowerBuilder, etc. The DLLs are written in C/C++, and the exported functions are just C functions. So, for example, I might have some functions like these:
short MyAPIDoSomething(LPCSTR buff, short bufflen)
BOOL MyAPIShutDown(WORD handle)
etc., exported from the DLL.
In 16-bits, I had these declared using the WINAPI and EXPORT macros, which are equivalent to __far __pascal and __export respectively. When I built my DLL, I then got these functions exported, and the __pascal bit meant that
(a) they were callable from VB, etc., with left-to-right parameter passing, and
(b) the names of the exported functions got made into uppercase, since the pascal calling convention is case-insensitive.
Note that I also had extern "C" in front of the declarations and definitions, and did *not* put any of the functions in the def file, since the EXPORT macro has the same effect and saves me updating both the functions and the def file all the time.
All worked fine up until I moved to 32-bits. Now I have a bunch of 32-bit DLLs, and so instead of my previous:
extern "C" BOOL WINAPI EXPORT MyAPIShutDown(WORD handle)
I now have
extern "C" EXPORT BOOL WINAPI MyAPIShutDown(WORD handle)
because 32-bits needs the EXPORT in a different place.
However, WINAPI now means, not __pascal, but __stdcall. And from reading the VB help (what little there is on this topic) I find that VB requires DLL functions to use the __stdcall calling convention.
Unfortunately, when I build my DLL, all the exported functions get name decorated, with a preceding underscore, and an "@n" tacked on the end, where n is the number of bytes the parameters take up. Standard Windows DLLs (which can be called from VB and so presumably use the __stdcall convention) are not so decorated, so how do I get rid of this decoration so that people can use my 32-bit DLL as they did the 16-bit one? On the odd occasions I have got the functions to work (by using the Alias keyword in VB), I get "Bad DLL Calling Convention" followed by a VB crash. It is possible that I have not specified the function correctly in VB for this, or it is possible that my calling convention is incorrect.
What this boils down to is how should I declare and define an exported function in a DLL so that it can be used by VB and C, and is exported with a particular name (rather than a decorated one) in 32-bits compared to 16-bits.
Any help will be much appreciated.