Calling functions from a C ++ DLL in Delphi

I created a new C ++ DLL project in VS2010 that provides 1 function

#include "stdafx.h" #define DllImport extern "C" __declspec( dllimport ) #define DllExport extern "C" __declspec( dllexport ) DllExport int DoMath( int a, int b) { return a + b ; } 

Then I created a C ++ application with VS2010 to test this DLL. Building a test application in VS2010 can call the C ++ DLL and get the expected result.

 #include "stdafx.h" #include <windows.h> typedef int (*DoMath)(int, int) ; int _tmain(int argc, _TCHAR* argv[]) { HMODULE hMod = LoadLibrary ("exampleDLL.dll"); if (NULL != hMod) { DoMath mf1 = (DoMath) GetProcAddress(hMod,"DoMath"); if( mf1 != NULL ) { printf ("DoMath(8,7)==%d \n", mf1(8,7) ); } else { printf ("GetProcAddress Failed \n"); } FreeLibrary(hMod); } else { printf ("LoadLibrary failed\n"); return 1; } return 0; } 

Then I tried to build a new project in Delphi 7 to call this C ++ DLL. I used this tutorial to help me build a new project.

 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TmyFunction = function(X,Y: Integer):Integer; TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; procedure FormShow(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } hDll: THandle; end; var Form1: TForm1; fDoMath : TmyFunction; implementation {$R *.dfm} procedure TForm1.FormShow(Sender: TObject); begin hDll := LoadLibrary('exampleDLL.dll'); if HDll >= 32 then { success } begin fDoMath := GetProcAddress(hDll, 'DoMath'); end else MessageDlg('Error: could not find exampleDLL.DLL', mtError, [mbOk], 0) end; procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin i := fDoMath(2,3); edit1.Text := IntToStr(i); end; end. 

The Delphi 7 project result is 6155731. When I was expecting 5. I checked the binary result code, thinking that it might have something to do with the data type, but it looks random to me. When I recompile / restart the application, it gets the same result every time.

I don’t know much about Delphi, this is the first time I do this and I find it confusing.

Any suggestion on what to check next?

+8
c ++ dll delphi delphi-7
source share
2 answers

You need to specify a calling convention, which in this case is equal to cdecl :

 TMyFunction = function(X, Y: Integer): Integer; cdecl; 

Your code uses the standard Delphi calling convention, which is register and passes parameters through registers. The calling convention cdecl passes parameters on the stack, and therefore this incorrect match explains why the connection between the two modules fails.


A few more comments:

The failure mode for LoadLibrary should return NULL , i.e. 0 . Check that instead of the return value there is >=32 .

It is easier to use implicit binding to import this function. Replace all LoadLibrary and GetProcAddress codes with the following simple declaration:

 function DoMath(X, Y: Integer): Integer; cdecl; external 'exampleDLL.dll'; 

The bootloader will allow this import when your executable starts, so you don’t have to worry about the details of the link.

+16
source share

In RAD Studio Berlin, using the CLANG compiler for the C ++ part, the cdecl function, which is extern "C", will have its name added with an underline, the traditional Unix style is "C". The above code does not work in this case, but to fix the problem, use the name attribute of the external declaration:

function DoMath (X, Y: integer): integer; Cdecl; external 'exampleDLL.dll' name '_DoMath';

Have not tried this with other compilers, so this may be a common problem with cdecl. The Windows API does not use cdecl, but uses the same calling convention as Delphi, therefore, for example, underscores in Winapi.Windows declarations do not add underscores.

The same is true when using GetProcAddress, the correct call is GetProcAddress (hDLL, '_DoMath'); otherwise nil is returned.

Hope this helps anyone trying to get Delphi to talk to C ++.

0
source share

All Articles