![]() |
Zeiger auf Proceduren
Hallo,
ich habe folgendes Problem: Ich muss eine DLL welche in C++ geschrieben wurde in Delphi einbinden, welches im Grunde genommen problemlos funktioniert. Wenn ich aber den Schalter für Typüberprüfung bei Zeigern einschalte {$TYPEDADDRESS ON} meldet mir der Compiler einen Fehler: Folgender Quelltext liegt dabei zugrunde:
Delphi-Quellcode:
Folgende Fehlermeldung tritt bei der procedure FormCreate auf:(* Callbacks *) type Callbacktyp1 = Procedure(); Callbacktyp2 = Procedure(ID : pUInt64); Callbacktyp3 = Procedure(ID : pUInt64; New : WordBool); Callbacktyp4 = Procedure(ID : pUInt64; Error : Integer); Callbacktyp5 = Procedure(LogClass : Word; LogMessage : pAnsiChar); type pCallbacktyp1 = ^Callbacktyp1; pCallbacktyp2 = ^Callbacktyp2; pCallbacktyp3 = ^Callbacktyp3; pCallbacktyp4 = ^Callbacktyp4; pCallbacktyp5 = ^Callbacktyp5; Procedure RegisterConnectCallback(Proc : pCallbacktyp1); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterConnectCallback$qqspqqsv$v'; Procedure RegisterDisconnectCallback(Proc : pCallbacktyp1); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterDisconnectCallback$qqspqqsv$v'; Procedure RegisterNewServerCallback(Proc : pCallbacktyp3); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterNewServerCallback$qqspqqsrxujxus$v'; Procedure RegisterDelServerCallback(Proc : pCallbacktyp2); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterDelServerCallback$qqspqqsrxuj$v'; Procedure RegisterNewDeviceCallback(Proc : pCallbacktyp3); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterNewDeviceCallback$qqspqqsrxujxus$v'; Procedure RegisterDelDeviceCallback(Proc : pCallbacktyp2); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterDelDeviceCallback$qqspqqsrxuj$v'; Procedure RegisterNewChannelCallback(Proc : pCallbacktyp3); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterNewChannelCallback$qqspqqsrxujxus$v'; Procedure RegisterDelChannelCallback(Proc : pCallbacktyp2); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterDelChannelCallback$qqspqqsrxuj$v'; Procedure RegisterNewDatabaseCallback(Proc : pCallbacktyp3); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterNewDatabaseCallback$qqspqqsrxujxus$v'; Procedure RegisterDelDatabaseCallback(Proc : pCallbacktyp2); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterDelDatabaseCallback$qqspqqsrxuj$v'; Procedure RegisterNewDataCallback(Proc : pCallbacktyp2); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterNewDataCallback$qqspqqsrxuj$v'; Procedure RegisterDataEndCallback(Proc : pCallbacktyp2); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterDataEndCallback$qqspqqsrxuj$v'; Procedure RegisterWriteBlockCompleteCallback(Proc : pCallbacktyp4); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterWriteBlockCompleteCallback$qqspqqsrxujxl$v'; Procedure RegisterLogCallback(Proc : pCallbacktyp5); stdcall; external 'DataServiceClientDLL.dll' name '@RegisterLogCallback$qqspqqsxuspxc$v'; implementation . . . procedure OnConnect; var i,j : integer; begin (* Unfug zum test *) i := 6; j:= 1+i; end; . . . procedure TForm1.FormCreate(Sender: TObject); begin Initialisation('testapplication'); RegisterConnectCallback(@OnConnect); RegisterNewDatabaseCallback(@OnNewDatabase); RegisterNewDataCallback(@tform1.OnNewData); StartLocalDataService(true); connect; end; [Fehler] zugriff.pas(643): Inkompatible Typen: 'Procedure' und 'Callbacktyp1' Ist ja eigentlich auch klar aber ich weis nicht was ich machen kann damit diese Typen Kompatibel zueinander sind. Bitte jetzt nicht den Vorschlag vor dem Create wieder die Typüberprüfung ausschalten. (ist völlig klar das das Funktioniert) Vielen Dank für eure Hilfe LG heiko |
Re: Zeiger auf Proceduren
Du hast TCallbackTyp1 als Zeigertyp auf Procedure, und PCallbackTyp1 als Zeiger auf einen Zeiger vom Typ TCallbackTyp1, ist das so gewollt oder bereits der erste Fehler?
Bei
Delphi-Quellcode:
übergibst du einen Zeiger auf einen Zeiger auf eine Prozedur, deklariert ist aber ein Zeiger auf einen Zeiger des Typs TCallbackTyp1. Damit das kompatibel wird, brauchst du m.E. eine Variable vom Typ TCallBackTyp1, deren Adresse du an RegisterConnectCallback übergeben kannst.
RegisterConnectCallback(@OnConnect);
Delphi-Quellcode:
Ich hoffe, mich damit richtig geirrt zu haben. :stupid:
procedure TForm1.FormCreate(Sender: TObject);
var pOnConnect:TCallbackTyp1; begin Initialisation('testapplication'); pOnConnect := OnConnect; RegisterConnectCallback(@pOnConnect); RegisterNewDatabaseCallback(@OnNewDatabase); RegisterNewDataCallback(@tform1.OnNewData); StartLocalDataService(true); connect; end; |
Re: Zeiger auf Proceduren
Hallo Tomsel,
zuerst einmal vielen Dank für deine rasche Antwort. Es funktioniert jetzt einwandfrei. Wie sollte ich den den Zeigertyp Callbacktyp1 sonst deklarieren, damit ich ihn auf eine Procedure zeigen lassen kann? LG heiko |
Re: Zeiger auf Proceduren
Delphi-Quellcode:
Das sind schon Pointertypen. Eine weitere Indirektion ist nicht noetig.
type
Callbacktyp1 = Procedure() stdcall; Callbacktyp2 = Procedure(ID : pUInt64) stdcall; Sind das C Funktionen oder C++ Methoden die da exportiert werden? C++ Methoden sind praktisch nicht von Delphi aus aufzurufen. Sind die Funktionen in der DLL wirklich mit stdcall Aufrufkonvention? Wenn es __fastcall ist, dann wird es vollends unmoeglich. Sollte es stdcall sein, dann sind auch die Delphi-Callbacktypen alle mit stdcall zu deklarieren (siehe oben). |
Re: Zeiger auf Proceduren
Zitat:
|
Re: Zeiger auf Proceduren
Hallo Tomsel,
also die funktionen in der DLL sind mit stdcall übersetzt worden. Ich habe gerade versucht den Delphi Typen ein stdcall anzuhängen worauf sich der Compiler mit einem Fehler meldet. Die Callbacks werden auf jeden Fall zum richtigen Zeitpunkt aufgerufen. Was noch nicht funktioniert ist die Übergabe der Parameter (z.B. ID) Habe gerade den Fehler gefunden. Lag in der Beschreibung der DLL ist kein Zeiger der zuückgeliefert wird. Habe folgendes geändert
Delphi-Quellcode:
jetz meckert der Compiler nicht und die Callbacks werden richtig aufgerufen also alles bestens
Callbacktyp2 = Procedure(ID : UInt64);
Procedure RegisterNewDataCallback(Proc : Callbacktyp2); . . . RegisterConnectCallback(OnConnect); Waren echt prima deine Infos haben mir sehr geholfen vielen Dank LG heiko |
Re: Zeiger auf Proceduren
Ist OnConnect eine Methode oder eine Funktion?
"Ich habe gerade versucht den Delphi Typen ein stdcall anzuhängen worauf sich der Compiler mit einem Fehler meldet." Sorry mein Fehler. Vermutlich fehlt ihm ein Semikolon.
Delphi-Quellcode:
Ohne stdcall an den Callbacks kann es nicht mit der Parametern funktionieren.
type
Callbacktyp1 = Procedure(); stdcall; Callbacktyp2 = Procedure(ID : pUInt64); stdcall; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz