I created a new c++ DLL project in VS2010 that exposes 1 function
#include \"stdafx.h\"
#define DllImport extern \"C\" __declspec( dllimport )
#define
You need to specify the calling convention, which in this case is cdecl
:
TMyFunction = function(X, Y: Integer): Integer; cdecl;
Your code uses the default Delphi calling convention which is register
and passes parameters through registers. The cdecl
calling convention passes parameters on the stack and so this mis-match explains why communications between the two modules fail.
Some more comments:
The failure mode for LoadLibrary
is to return NULL
, that is 0
. Check that rather than the return value being >=32
.
It's simpler to use implicit linking to import this function. Replace all the LoadLibrary
and GetProcAddress
code with this simple declaration:
function DoMath(X, Y: Integer): Integer; cdecl; external 'exampleDLL.dll';
The system loader will resolve this import when your executable starts so you don't have to worry about the details of linking.
On RAD Studio Berlin, using CLANG compiler for the C++ part, a cdecl function which is extern "C" will have its name prepended with an underscore, traditional unix "C" style. The above code doesn't work in this case, but use the name attribute of the external declaration to fix the problem:
function DoMath(X, Y: Integer): Integer; cdecl; external 'exampleDLL.dll' name '_DoMath';
Not tried it with other compilers, so it might be a general issue with cdecl. The Windows API does not use cdecl, but uses same calling convention as Delphi so, for example, the Winapi.Windows declarations of DLL functions do not have the underscore added.
Same true if using GetProcAddress, the correct call is GetProcAddress(hDLL, '_DoMath'); otherwise nil is returned.
Hope this helps anyone struggling to get Delphi talking to C++.