My goal is to call a function written in C++ (with a C interface) from within Delphi (RAD Studio XE6). In the end, the dll will be generated by Visual Studio 2013, but I've tried to start with generating the Dll from RAD Studio XE6.
So, I have created a Dll project in Rad Studio (Using VC++ style Dll). The file is here
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
extern "C" int next(int n) {
return n + 1;
}
It compiles as a Dll. On the Delphi side, the code is as below:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, Windows;
function next(a: Int32): Int32; cdecl;
external 'Project3.dll';
var
a: Int32;
begin
try
a := 3;
Writeln('Hello world!', next(a));
sleep(3000);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
The project does compile but does not run. It gives the following error:
*** A stack buffer overrun occurred in "C:\...\Debug\Project1.exe"
It fails on the following assembly line
mov eax,[edi]
I have tried to change cdecl to std call, pascal or register. But nothing works.
Solution: Thanks to Rudy, the following code does work. First the C++ side:
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
extern "C" __declspec(dllexport) int __stdcall next(int n) {
return n + 1;
}
and then the Delphi side.
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, Windows;
function next(a: Int32): Int32; stdcall;
external 'Project3.dll';
var
a: Int32;
begin
try
a := 3;
Writeln('Hello world!', next(a));
sleep(3000);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
extern "C"
? C++ is not likely to be supported by Delphi, usually plain C functions are the lowest common denominator that can be imported by any other language.LONG
,DWORD
, etc., and not C++ types such asint
. There is no guarantee thatint
will be 32 bits, as C++ makes no such guarantees. In addition, the name you exported is mangled -- as the other comment suggested, take a look at your exported function using Dependency Walker.