First of all, I am using Mingw 4.8 as the compiler of the C++ DLL in Code:blocks 13.12 and Lazarus 1.4.2 for working with the FreePascal code. (Windows 7).
I need to generate a DLL in C++ or C that can be called from a FreePascal program.
The problem is that my knowledge about FreePascal is null. It doesn’t look really complicated to make a simple program but I can’t find good information about how to import and use a C/C++ DLL.
The only thing that more or less worked was Using C DLLs with Delphi. My real code:
FreePascal:
function hello():Integer; external 'function' index 1;
…
Label1.Caption:=IntToStr(hello());
C++ DLL header:
#ifndef function_H
#define function_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL hello( );
#ifdef __cplusplus
}
#endif
#endif
C++ file:
#include <stdio.h>
#include "function.h"
__stdcall int hello( )
{
return 8;
}
But when I try to pass any argument or do something complicated with the function, it starts to give random numbers.
This is the new code:
function function1(t1:Integer):Integer; external 'function' index 1;
…
entero:=8;
Label1.Caption:=IntToStr(function1(entero2));
Also I updated the C++ code to this:
#include <stdio.h>
#include "function.h"
__stdcall int function1(int t1)
{
return t1*2;
}
#ifndef funtion_H
#define funtion_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef BUILDING_DLL
#define FUNCTION_DLL __declspec(dllexport)
#else
#define FUNCTION_DLL __declspec(dllimport)
#endif
int __stdcall FUNCTION_DLL function1(int t1);
#ifdef __cplusplus
}
#endif
#endif
I also read Pascal Scripting: Using DLLs and .NET assemblies and tried to implement the DLL call like this:
function function1(t1: Integer): Integer; external 'function1@files:function.dll';
But I receive an error saying that:
The procedure entry point function1 could not be located in the dynamic link library function.dll
I’m looking for an example that works or an online tutorial or something to continue working because I am very stuck with this.
You need to make the calling conventions match. Your C++ code uses __stdcall
. The Pascal code does not specify a calling convention and so defaults to register
.
Declare the Pascal import like this:
function function1(t1:Integer):Integer; stdcall; external 'function' index 1;
Are you quite sure that you need to use an index when importing? It is much more common to import by name than by ordinal. I'd expect to see the import looking like this:
function function1(t1:Integer):Integer; stdcall; external 'function';
The reason why the function with no parameters succeeds is that for a parameterless function, the differences between calling convention do not matter. Once you start passing an argument, stdcall
means that the argument is passed via the stack, and register
means it is passed in a register. This mismatch explains the behaviour you observe.