Autor Beitrag
pluto-online
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Do 06.10.16 10:19 
Hallo,
wir haben eine Inkjetdrucker der Firma REAJET an einer Produktionslinen.
Ich möchte die Ansteuerung gerne in ein vorhandenes Delphiprojekt integrieren. (Delphi XE7)
Die Firma REAJET stell eine API-DLL zu Verfügung.
Jetzt habe ich das problem, dass ich nur eine Headerdatei für VC++ zu Verfügung habe.
Ich habe jetzt angefangen die Headerdatei für Delphi umzubauen.
Die folgenden 4 Funktionen habe ich auch schon zum Laufen bekommen.

ausblenden Quelltext
1:
2:
3:
4:
5:
VC++
REAPI_DLL const char* REAPI_LibInfo( );
REAPI_DLL const char* REAPI_GetRevision( );
EAPI_DLL TConnectionId REAPI_Connect( const char* connectionString );// Connection address string
REAPI_DLL TErrorCode REAPI_Disconnect( TConnectionId connection );// Connection id returned by REAPI_connect


Jetzt habe ich ein Problem mit der nächsten Funktion:
ausblenden Quelltext
1:
2:
3:
VC++
REAPI_DLL TErrorCode REAPI_RegisterConnectionCallback(    C_connectionCallbackPtr callback,   // Callback for asynchronous mode
   void* context );                              //Helper Context pointer


Hier muss ein Pointer auf eine Callbackfunktion übergeben werden.
In VC++ würde das ganez so aussehen.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
//Die Callbackroutine

void REAPI onConnectionChanged(TConnectionId con, TConStatus
statusID, TErrorCode error, void * context)
{
{
printf("Connected\n");
GlobalConnectionId = con;
}
else
{
printf("Connection failed\n");
}
}
/*Register ConnectionCallback function in asynchronous mode*/
REAPI_RegisterConnectionCallback ( & onConnectionChange,
&mycontext);


ausblenden Quelltext
1:
2:
3:
//Die Registrierung der Callbackroutine

tmperror = REAPI_RegisterConnectionCallback( &onConnectionChanged, 0 );


Wie kann ich das ganze jetzt auf Delphi Portieren?
Vielen Dank schon mal!
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 376
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: Do 06.10.16 23:39 
Hallo,

wenn ich das richtig verstehe, ist das Problem, das man einer Prozedure sagen soll, welche eigene Prozedur sie unter bestimmten Bedingungen aufrufen soll.

Ich mache das z.B. so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
 {Meine Routine, bei Dir die Callback }
 TProcedureStruktur = PROCEDURE(schrittfertig: boolean; VAR abbruch: boolean) OF OBJECT;

 PROCEDURE struktur_schwinger(schrittfertig: boolean; VAR abbruch: boolean);

 {Fremde Routine stellt Funktion zur Mitteilung der Routine zur Verfügung: }
 
 PROCEDURE setze_adressen(vps: TProcedureStruktur; ....);
   ps := vps;


 { Aufruf aus meinem Programm zur Mitteilung der vom anderen Programm aufzurufenden Callback-Procedure }
 setze_adressen(struktur_schwinger,...);


Vielleicht hilft es,

Guaack
pluto-online Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 07.10.16 08:10 
@GuaAck
Ich steige nicht so ganz durch was wie das genau funktioniert.

Das ist mein DLL Interface
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
unit reapi_intf;

interface {--------------------}
type
  myfunc = function : Pointer;

CONST DllName = 'reapi.dll' ;
function REAPI_LibInfo( ) : PChar; stdcall; EXTERNAL DllName;
function REAPI_GetRevision ( ) : PChar; stdcall; EXTERNAL DllName;
function REAPI_Connect (connectionString:PChar) : Integer; stdcall; EXTERNAL DllName;
function REAPI_Disconnect(connection:Integer ) : Integer; stdcall; EXTERNAL DllName;
function REAPI_ProtocolVersion(connection:Integer) : PChar; stdcall; EXTERNAL DllName;
function REAPI_RegisterConnectionCallback( callback:myfunc; context:Pointer) : Integer; stdcall; EXTERNAL DllName;

implementation{--------------------}
end.


Das ist meine Callback Funktion
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
function CallBack(conid:integer; constatus:integer; error:integer; context:Pointer ):integer;
  begin
    if constatus = 1 then showmessage('Connected');
    if constatus = 0 then showmessage('Disconnected');
    if constatus = 2 then showmessage('Error');
  end;


So habe ich die zuweisung versúcht.
ausblenden Quelltext
1:
REAPI_RegisterConnectionCallback(@CallBack,0);					


So hat es nicht funktioniert.
Die Funktion REAPI_RegisterConnectionCallback erwartet ja einen Pointer auf die Callbackfunktion.
Wie muss ich das jetzt deklarieren?
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 376
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: Fr 07.10.16 23:11 
Hallo,

ich denke, es müsste so gehen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
unit reapi_intf;

interface {--------------------}
type
   myfunc = function CallBack(conid:integer; constatus:integer; error:integer; context:Pointer ):integer OF OBJECT;
//  myfunc = function : Pointer;

CONST DllName = 'reapi.dll' ;
function REAPI_LibInfo( ) : PChar; stdcallEXTERNAL DllName;
function REAPI_GetRevision ( ) : PChar; stdcallEXTERNAL DllName;
function REAPI_Connect (connectionString:PChar) : Integer; stdcallEXTERNAL DllName;
function REAPI_Disconnect(connection:Integer ) : Integer; stdcallEXTERNAL DllName;
function REAPI_ProtocolVersion(connection:Integer) : PChar; stdcallEXTERNAL DllName;
function REAPI_RegisterConnectionCallback( callback:myfunc; context:Pointer) : Integer; stdcallEXTERNAL DllName;

implementation{--------------------}
end


// Und in der Zuweisung dann den  @ weg

REAPI_RegisterConnectionCallback(CallBack,0);


Letzlich wird so auch nur ein Pointer übergeben. Das mit dem OF OBJECT bezieht sich darauf, dass Callback eine Methode einer Klasse ist.

Lies mal in der Delphi-Hilfe unter "Prozedurale Typen" nach, da steht das recht ausführlich und verständlich.

Sonst poste noch mal,

Gruß Guaack
pluto-online Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mo 10.10.16 08:00 
Ich denke das geht in die richtige Richtung.


ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
unit reapi_intf;
interface {--------------------}

type
   myfunc = function (conid:integer; constatus:integer; error:integer; context:Pointer ):integer OF OBJECT;

CONST DllName = 'reapi.dll' ;
function REAPI_RegisterConnectionCallback(callback:myfunc; context:Pointer) : Integer; stdcall; EXTERNAL DllName;

implementation{--------------------}
end.


Die CallBack Funktion
ausblenden Quelltext
1:
2:
3:
4:
function CallBack (conid:integer; constatus:integer; error:integer; context:Pointer ):integer;
begin
.........
end;


Hier bekomme ich den Folgenden Fehler [E2009 Inkompatible Typen: 'Methodenzeiger und reguläre Prozedur']
ausblenden Quelltext
1:
error:=REAPI_RegisterConnectionCallback(CallBack,buf);					
pluto-online Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mo 10.10.16 08:36 
Ich habe es jetzt so gelöst.

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
   myfunc = function (conid:integer; constatus:integer; error:integer; context:Pointer ):integer;

function REAPI_RegisterConnectionCallback(callback:myfiunc; context:Pointer) : Integer; stdcall; EXTERNAL DllName;



function ConnectionCallback (sender:TObject; conid:integer; constatus:integer; error:integer; context:Pointer ):integer;
begin
 ....
end;

REAPI_RegisterConnectionCallback(@ConnectionCallback,buf);


Vielen Dank für die Unterstützung!!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 10.10.16 11:16 
Das of object benutzt man, wenn man eine Methode eines Objekts übergeben will. Da wird dann im Hintergrund noch die Instanz der Klasse mitgegeben. Deshalb ist das nicht kompatibel.

Nur falls dir der Hintergrund nicht klar sein sollte.
GuaAck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 376
Erhaltene Danke: 32

Windows 8.1
Delphi 10.4 Comm. Edition
BeitragVerfasst: Mi 12.10.16 22:35 
Hallo,

Entschuldigung, ich hätte sehen müssen, dass "function CallBack(con..." keine Methode ist.

Im Debug-CPU-Fenster kann man schön sehen, dass bei OF OBJECT zwei Zeiger übergeben werden, der für die Funktion (als feste HEX-Zahl, Compiler und Linker wissen ja, wo sie den Code hin packen) und der für das Object, der mit ...create für das Object erst zur Laufzeit generiert wird und somit einer Variablen (z. B. einem Register) entnommen wird.

Gruß
GuaAck