![]() |
Aufruf DLL: Wie nur das Array?
Hallo zusammen,
ich muss hier eine DLL einbinden, was bis jetzt problemlos funktioniert hat. Folgende Gegebenheiten: Ich habe die DLL und eine API dazu. Hinzu ein funktionierendes C++ Beispiel. Dazu eine Delphi-Unit mit den StdCalls, die meiner Meinung nach aber nicht immer 100% richtig ist. Vom Hersteller fehlt leider der Support, die sind der Meinung, dass man mit C++ doch viel besser zurecht kommt... Mein Problem: Es gibt einen Record (C++ struct). Folgende C++ und Delphi Umsetzung, die soweit an vielen Stellen problemlos funktioniert:
Code:
Nun gibt es Aufrufe, die laut Doku Funktionen mit Input Parameter: FAPIRef* - im StdCall sieht das dann so aus:
typedef struct {
long dLength; BYTE* dpRef; } FAPIMem; FAPIMem = record dLength: LongInt; dpRef: PBYTE; end;
Code:
Wenn ich die Funktion nun ausführen will, funktioniert folgender Code auch wieder problemlos:
function XY(var pRef: FAPIMem): LongInt stdcall; external 'my.dll' name '_FAPIXY@4';
Code:
Und jetzt kommt das eigentliche Problem: Eine Funktion YZ mit Input FAPIMem** - FAPIMem Reference Array (beachtet den Doppelstern!). Dazu noch ein Integer-Parameter length. Das ganz sieht für mich nun so aus, als wenn ich ein Array of FApiMem übergeben soll. Die (vorgegebene) Umsetzung des Delpi StdCalls sieht nun so aus:
var
apiMem: FAPIMem; begin XY(apiMem); end;
Code:
Also bin ich wie folgt vorgegangen:
function YZ(var pRef: FApiMem; length: LongInt): LongInt stdcall; external 'my.dll' name '_FAPIXY@40';
Code:
Leider kommt dann der Fehler, dass die Daten ungültig wären. Ich gehe an der Stelle davon aus, dass meine Initalisierung korrekt funktioniert, denn wenn ich anstatt YZ die Funktion XY mit einem apiMem[0] aufrufe, klappt alles.
var
apiMem: arry of FApiMem; begin SetLength(apiMem, 2); // ... hier jetzt Initialisierung ... YZ(apiMem[0], 2); end; Der (angeblich) funktionierende C++ Code lautet in etwa:
Code:
Ich hätte ja fast behauptet, dass meine Umsetzung in Delphi korrekt ist, oder aber dass ich bei der Datenerzeugung wirklich irgendwo daneben greife. Allerdings komme ich keinen Zentimeter weiter und würde von euch gerne wissen, was ihr denke: Ist mein Ansatz falsch oder soll ich den Fehler woanders suchen?
FAPIMem **reqTest;
reqTest = (FAPIMem**) malloc (sizeof(FAPIMem*)*2); reqTest[0] = malloc(sizeof(FAPIMem)); reqTest[1] = malloc(sizeof(FAPIMem)); // -- Hier dann die Intialisierung der eigentlichen Daten NumberOfRef = 2; YZ(reqTest, NumberOfRef); Vielen Dank, Markus PS: Die DLL heißt natürlich nicht my.dll und die Funktionen nicht XY, YZ. Allerdings darf ich die Daten hier aus Lizenzgründen nicht weitergeben. Sorry! |
AW: Aufruf DLL: Wie nur das Array?
malloc .... das sieht für mich eher so aus, als wenn es ein array of PFApiMem sein soll.
** = Zeiger auf eine Liste von Zeigern auf deinen Record PS: FApiMem ... in Delphi würde ich das eher TFApiMem nennen. Und welche Delphi-Version war das jetzt nochmal? |
AW: Aufruf DLL: Wie nur das Array?
Ich würde das auch so übersetzen:
Delphi-Quellcode:
TApiMem = ^PApiMem;
PApiMem = record dLength: LongInt; dpRef: PBYTE; end; function YZ(var pRef: FApiMem; length: LongInt): LongInt stdcall; external 'my.dll' name '_FAPIXY@40'; var apiMem: array of PApiMem; begin SetLength(apiMem, 2); New(apiMem[0]); // Initialisierung apiMem[0] New(apiMem[1]); // Initialisierung apiMem[1] YZ(apiMem[0], 2); end; |
AW: Aufruf DLL: Wie nur das Array?
Hallo ihr zwei,
vielen Dank für eure Hilfe - hätte man auch selbst darauf kommen können, aber das Brett vor dem Kopf ist eher größer als kleiner geworden. Das Beispiel von Blup funktioniert einwandfrei! Die Namen sind natürlich nicht ideal, die werden noch angepasst... Vielen Dank Markus |
AW: Aufruf DLL: Wie nur das Array?
Und nicht das Dispose zum New vergessen.
Man könnte auch 2 Arrays verwenden, eines mit TFApiMem für den Inhalt und eines mit PFApiMem für die Übergabe ... darum auch die Frage nach der Delphiversion, denn da könnte man z.B. über Class Helper das Pointerarray ganz nett im anderen array verstecken oder gar eine automatische Umwandlung einbauen. |
AW: Aufruf DLL: Wie nur das Array?
Sorry für die späte Antwort. Wir sprechen von Delphi 2007 Pro. Das mit dem Dispose war klar, außer ich hätte Speicher "sammeln" wollen :-D
Grüße Markus |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 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