C DLL Funktion einbinden - eary binding vs. late binding

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
PeterS
Beiträge: 184
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 4.4
CPU-Target: win32, win64

C DLL Funktion einbinden - eary binding vs. late binding

Beitrag von PeterS »

Hallo,

ich verstehe noch nicht genau, warum der Compiler einen Unterschied macht
wenn ich eine Funktion aus einer DLL "early" oder "late" einbinde.

Folgendes Beispiel:

Code: Alles auswählen

int Pa_GetVersion( void );
Für early binding ist das hier deklariert

Code: Alles auswählen

function Pa_GetVersion(): cInt; cdecl; external LibName;
Damit funktioniert in Lazarus das hier (=> early binding), mit 32 bit Lazarus / 32 bit Compiler.

Code: Alles auswählen

  Result:= 'PA version int:   ' +IntToStr( Pa_GetVersion);

Für late binding ist das hier deklariert

Code: Alles auswählen

var Pa_GetVersion: function():cInt ; cdecl;
..

function Pa_Load( const libfilename:string):boolean;
..
          Pointer( Pa_GetVersion):= DynLibs.GetProcedureAddress( PA_Handle, pAnsiChar( 'Pa_GetVersion'));
Das heißt für mich, das Programm kennt (nach Aufruf von Pa_Load) die Adresse der Funktion in der externen C DLL.
Und auch den Ergebnis-Typ der Funktion, denn der ist ja deklariert als cInt. Oder ?

Damit funktioniert das hier aber nicht ..

Code: Alles auswählen

  Result:= 'PA version int:   ' +IntToStr( Pa_GetVersion);
und der Compiler meckert:

Error: Incompatible type for arg no. 1: Got "<procedure variable type of function:LongInt;CDecl>", expected "QWord"
sysstr.inc(861,10) Hint: Found declaration: IntToStr(QWord):AnsiString;
sysstr.inc(856,10) Hint: Found declaration: IntToStr(Int64):AnsiString;
sysstr.inc(850,10) Hint: Found declaration: IntToStr(LongInt):AnsiString;


Der Compiler ruft also IntToStr(QWord) auf statt IntToStr(LongInt) - und das geht natürlich nicht.
Eigentlich müßte der Compiler doch wissen daß function result von Pa_GetVersion = Typ cInt ist ??
Und daher IntToStr(LongInt) anwenden ?

PeterS
Beiträge: 184
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 4.4
CPU-Target: win32, win64

Re: C DLL Funktion einbinden - eary binding vs. late binding

Beitrag von PeterS »

Beim "Fehler" beschreiben habe ich es jetzt endlich selber herausgefunden. :roll:

Code: Alles auswählen

  Result:= 'PA version int:   ' +IntToStr( Pa_GetVersion);
ist nicht dasselbe wie

Code: Alles auswählen

  Result:= 'PA version int:   ' +IntToStr( Pa_GetVersion() );
:shock:

Mathias
Beiträge: 7137
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: C DLL Funktion einbinden - eary binding vs. late binding

Beitrag von Mathias »

Hast du auch Herausgefunden, wieso es verschiedene Werte gibt ?
Oder hast du einfach nur den Fehler gefunden ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PeterS
Beiträge: 184
Registriert: So 22. Feb 2015, 11:36
OS, Lazarus, FPC: L 4.4
CPU-Target: win32, win64

Re: C DLL Funktion einbinden - eary binding vs. late binding

Beitrag von PeterS »

Mathias hat geschrieben: Fr 5. Dez 2025, 20:12 Hast du auch Herausgefunden, wieso es verschiedene Werte gibt ?
Oder hast du einfach nur den Fehler gefunden ?
Ich gehe davon aus daß das Programm mit "late binding" und dem folgenden Code ..

Code: Alles auswählen

  Result:= 'PA version int:   ' +IntToStr( Pa_GetVersion);
die Adresse der Funktion "Pa_GetVersion" anzeigt, aber nicht die Funktion aufruft.
Also die Adresse, die mit DynLibs.GetProcedureAddress() an die VAR Pa_GetVersion zugewiesen wurde
=>

Code: Alles auswählen

var Pa_GetVersion: function():cInt ; cdecl; 

Antworten