[gelöst] Problem beim DLL-Aufruf

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Latze
Beiträge: 60
Registriert: Sa 4. Jul 2009, 09:11
OS, Lazarus, FPC: Win7 / Linux (Lazarus 1.4.0)
CPU-Target: 32Bit/64Bit

[gelöst] Problem beim DLL-Aufruf

Beitrag von Latze »

Hallo,

ich versuche mich gerade an DLL-Aufrufen. Dazu habe ich mir die CAPI2032.DLL ausgesucht. Mein erster Versuch war:

Code: Alles auswählen

function CAPI_INSTALLED:word; external 'capi2032.dll';
 
.
.
.
 
if CAPI_INSTALLED = 0 then
begin
  label1.caption := 'CAPI installiert';
end else begin
  label1.caption := inttostr(CAPI_INSTALLED);
end;
Das Funktioniert soweit ganz gut, die CAPI scheint installiert zu sein. Als nächstes wollte ich den Hersteller auslesen und habe folgendes hinzugefügt:

Code: Alles auswählen

procedure CAPI_GET_MANUFACTURER(ptr:pointer); external 'capi2032.dll';
Es soll ein Zeiger auf einen 64 Byte Puffer übergeben werden, wo dann der Hersteller als Null-terminierter String zurückgegeben wird. Also:

Code: Alles auswählen

var
  Manufacturer : PChar;
.
.
.
  CAPI_GET_MANUFACTURER(@Manufacturer);
Starte ich diesen Aufruf im Programm, erhalte ich einen SIGSEGV. Ich habe auch schon frustriert mit anderen Typen (string, array [1..64] of byte etc.) rumgespielt aber immer das gleiche Ergebnis.

Wäre schön, wenn mir jemand erklären könnte, was ich falsch mache.
Zuletzt geändert von Latze am Fr 9. Jul 2010, 13:44, insgesamt 1-mal geändert.
Wer glaubt, etwas zu sein, hat aufgehört, etwas zu werden.

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Problem beim DLL-Aufruf

Beitrag von theo »

Viellelicht mal ne Aufrufkonvention setzen. Z.B. stdcall oder cdecl

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Problem beim DLL-Aufruf

Beitrag von mschnell »

Klar stürzt das ab. Manufacturer ist ein Zeiger (pchar), der auf nichts zeigt, weil Du ihm einen Wert zugewiesen hast. Außerdem ist @Manufacturer ein Zeiger auf einen Zeiger, also nicht das, was Du willst.

1) Vermutlich sind die Funktionen in der dll als stdcall implementiert. Das ist aber nicht sicher. Es sollte aus der Dokumentation der DLL hervorgehen.

2) Wenn die DLL einen Text zurückgeben soll, ist im Aufruf vermutlich ein Zeiger auf ein en Speicherbereich zu übergeben, in den der Text von der DLL kopiert werden soll (normale C-Methodik).

Hier solltest Du zunächst einen ANSI-String mit der nötigen Größe anlegen (z.B. mit SetLength(s, 50) ) und dann mit als Parameter pchar(s) übergeben, was einen Zeiger auf das erste Zeichen des Strings produziert.

-Michael
Zuletzt geändert von mschnell am Fr 9. Jul 2010, 14:13, insgesamt 1-mal geändert.

Latze
Beiträge: 60
Registriert: Sa 4. Jul 2009, 09:11
OS, Lazarus, FPC: Win7 / Linux (Lazarus 1.4.0)
CPU-Target: 32Bit/64Bit

Re: Problem beim DLL-Aufruf

Beitrag von Latze »

Danke für die Hilfe,

an stdcall hat es gelegen. Falls noch jemand so ein Problem haben sollte, so muss es aussehen:

Code: Alles auswählen

procedure CAPI_GET_MANUFACTURER(ptr:pointer); stdcall; external 'capi2032.dll';
Mit dem Zeiger habe ich schon einiges herum gespielt, weil ich den Fehler zunächst dort vermutet habe. Die Variante von mschnell hatte ich (glaube bzw. hoffe ich) auch dabei. Es funktioniert jedenfalls, ich werde nun einen Schritt weiter gehen und vielleicht auch gleich die nächste Frage stellen. ;)

Latze
Wer glaubt, etwas zu sein, hat aufgehört, etwas zu werden.

Antworten