HOWTO: Call C Functions That Use the _cdecl Calling Convention
ID: Q153586
|
The information in this article applies to:
-
Microsoft Visual Basic Learning, Professional, and Enterprise Editions for Windows, versions 5.0, 6.0
-
Microsoft Visual Basic Standard, Professional, and Enterprise Editions, 32-bit only, for Windows, version 4.0
SUMMARY
It is not possible to directly call a C function in a DLL if that function
uses the _cdecl calling convention. This is because Visual Basic uses the
_stdcall calling convention for calling functions. This is a problem
because if _cdecl is used, the calling function is responsible for cleaning
up the stack. However, if _stdcall is used, the called function is
responsible for cleaning up the stack.
NOTE: An .EXE file created in Visual Basic will allow you to call a DLL
function that has been declared with the _cdecl calling convention without
an error. It is only when you try to call such a function when running a
program from the Visual Basic IDE, that Visual Basic generates the
following error:
Run-time Error '49':
Bad DLL Calling Convention
The fact that the EXE version allows you to call such functions has been
confirmed to be a bug by Microsoft. You should not rely on this behavior as
this might change in future versions of Visual Basic.
MORE INFORMATION
If it is necessary to call functions that use the _cdecl calling convention
(such as the MSTEST DLLs), wrap the _cdecl call inside a _stdcall call that
is exposed or exported to Visual Basic. This is demonstrated in the
following step-by-step example.
Step-by-Step Example
- Create a 32-bit Windows C DLL with the following functions:
long _cdecl PassStr(LPSTR pStr)
{
MessageBox (NULL, pStr, "Test DLL", MB_OK);
return 1;
}
long _stdcall PassStrStdCall(LPSTR pStr)
{
return PassStr(pStr);
}
Export the functions in a .DEF file as follows:
LIBRARY TESTDLL
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD SINGLE
EXPORTS
PassStr @1
PassStrStdCall @2
Name this DLL Testdll.dll, and save the file to the Windows\System
directory in Windows 95 or Windows 98, or the Windows\System32 directory
in Windows NT.
- Create a new project in Visual Basic. Form1 is created by default. Add
the following code to the general declarations portion of Form1:
Private Declare Function PassStrStdCall Lib "testdll.dll" _
(ByVal s As String) As Long
Private Sub Form_Click()
ret& = PassStrStdCall("hello")
Print ret&
End Sub
- Run the Visual Basic program, and click the form. A Msgbox will show the
value of the passed string.
Additional query words:
kbVBp400 kbVBp500 kbVBp600 kbVBp kbdsd kbAPI kbDSupport
Keywords : kbGrpVB
Version :
Platform : NT WINDOWS
Issue type : kbhowto
|