Calling Conventions and VB
Suppose you have written some functions in C/C++ and you exported them to a DLL.
If not explicitly changed, they will have the calling convetion "cdecl".
A calling convention specifies in which order arguments
are pushed on the stack and who removes them from it after the called function returns, either the caller or the callee.
VB only supports the calling convention "stdcall" (actually, cdecl too, we will get back to that), so how would you call these functions,
if they aren't compatible to VB?
If you have the source code to the C functions, you change the calling convention, look into the manual of your compiler, or search for
something like "stdcall C++".
But what to do if you do not? In this case you have various options.
- Write a Wrapper DLL in C/C++, where each function has the calling convention stdcall and internally calls the cdecl function.
- Write a Wrapper DLL in VB!
- Use some precompiled machine code to call the functions.
1. Writing a Wrapper DLL in C/C++
This is a trivial task if you know some C.
2. Writing a Wrapper DLL in VB
Yes, this is actually possible. VB also supports cdecl!
But only compiled to native code.
You can create a new Active-X DLL with an empty class, write your declares, and add some functions which call these functions.
Private Declare Function my_c_function Lib "my_c.dll" (ByVal param1 As Long, ByVal param2 As Long) As Long
Public Function my_c_function_wrapper(ByVal param1 As Long, ByVal param2 As Long) As Long
my_c_function_wrapper = my_c_function(param1, param2)
After you're finished, compile the DLL (make sure you compile to Native Code, as P-Code won't work!) and reference it
in a new Standard Exe project. Now you can call the functions without any problems.
But beware! VB does not support cdecl callbacks!
This can be solved with:
3. Assembler for cdecl calls and callbacks
The way of of including machine code I used is pretty easy. You reserve executable memory with VirtualAlloc,
write your machine code into it, and call it using some function which allows the execution of a function pointer,
The bad thing about this way is, you have to know how your arguments look on the stack.
The good thing is, you don't need additional components.
Anyways, you can also combine my function CreateCdeclCbWrap() with method #2 (writing a Wrapper DLL in VB)
and just ignore CallCdecl(). For some code look at the attachment (the example shows how to use the function "qsort"
of the Microsoft Visual C Runtime (msvcrt.dll)).