Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Aufrufparameter für C-Funktionen in DLL's (https://www.delphipraxis.net/88485-aufrufparameter-fuer-c-funktionen-dlls.html)

r_kerber 16. Mär 2007 07:19


Aufrufparameter für C-Funktionen in DLL's
 
Moin moin,

aus einer DLL möchte ich diverse C-Funktionen aufrufen. Das funktioniert aber leider nur zum Teil.
Delphi-Quellcode:
  TOpenSession       = function (strArgs: pchar; lngSession: pointer): longint; stdcall;
  TGetErrorMsg       = function (lngSession: longint; lngResult: longint;
                                     strLanguage, strMessage: PChar;
                                     lngMessageLength: int64): longint; stdcall;
  TGetLicense       = function (lngSession: longint; strLanguage : pchar; lngLength : pointer) : longint; stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var
  DLLHandle       : THandle;        
  pOpenSession : TOpenSession;          
  pGetErrorMsg : TGetErrorMsg;
  pGetLicense  : TGetLicense;
  lngLength, lngResultCode, lngSession, lngRetCode, i : longint;

  arChar, arChar1 : Array [1..255] of char;

begin
  DLLHandle := LoadLibrary (PAnsiChar ('blablubb.dll'));
  @pOpenSession := GetProcAddress (DLLHandle, 'open_session');
  @pGetErrorMsg := GetProcAddress (DLLHandle, 'get_error_msg');
  @pGetLicense := GetProcAddress (DLLHandle, 'get_license');

  lngResultCode := pOpenSession (
                   pchar ('service=''blabla'', servicehost=''localhost'''),
                   @lngSession);

  fillchar (archar1, 2, 0);
  arChar1[1] := 'D';

  FillChar (arChar, 255, 0); lngLength := 254;
  lngResultCode := pGetLicense (lngSession, @arChar, @lngLength);

  FillChar (arChar, 255, 0);
  lngResultCode := pGetErrorMsg (lngSession, 11, @archar1, @arChar, 255);

end;
Das Problem tritt beim Aufruf von pGetErrorMsg auf. Ich erhalte eine Zugriffsverletzung beim Lesen auf einem Speicherbereich. Hier die Definitionen dieser C-Funktionen:
Code:
long open_session (const char * args, long * session);
long get_license (long session, char * license, unsigned int * length);
long get_error_msg (long session, long result, const char * lang, char * buf, size_t len);
In einem mitgeliefertem Demo-Programm wird get_error_msg wie folgt aufgerufen:
Code:
static char  language[64] = "D";
long session;
long rc;
char msg[80];
urc = get_error_msg(session, rc, language, &msg[0], sizeof msg);
Wie muß nun der korrekte Delphi-Aufruf dieser Funktion aussehen?
PS: Ich hoffe, ich habe alle wesentlichen Programmzeilen aus den Beispielen übernommen...

ste_ett 16. Mär 2007 07:28

Re: Aufrufparameter für C-Funktionen in DLL's
 
Delphi-Quellcode:
function open_session(args: PChar; session: PLongint): Longint; (*"stdcall;" oder "cdelcl;"*)
function get_license (session: Longint; license: PChar; length: PUINT): Longint; (*"stdcall;" oder "cdelcl;"*)
function get_error_msg (session, res: Longint; lang, buf: PChar; len: UINT): Longint; (*"stdcall;" oder "cdelcl;"*)

// result -> res
// Result kann nicht nochmal definiert werden in einer Funktion und muss deshalb umbenannt werden.

---

var
  session, rc, Res: Longint;
  msg: array[0..79] of Char;
  language: array[0..63] of Char;
begin
  ZeroMemory(@msg, sizeof(msg));
  ZeroMemory(@language, sizeof(language));
  language[0] := 'D';

  Res := get_error_msg(session, rc, language, msg, sizeof(msg));

Muetze1 16. Mär 2007 08:09

Re: Aufrufparameter für C-Funktionen in DLL's
 
Zitat:

Zitat von ste_ett
// result -> res
// Result kann nicht nochmal definiert werden in einer Funktion und muss deshalb umbenannt werden.

Das ist nicht Fehler, schliesslich hat er dies schon beachtet und bei den Prototypen den Parameter "lngResult" genannt...

r_kerber 16. Mär 2007 08:43

Re: Aufrufparameter für C-Funktionen in DLL's
 
Moin Stefan,

das behebt den Fehler leider nicht. :cry:

ste_ett 16. Mär 2007 09:12

Re: Aufrufparameter für C-Funktionen in DLL's
 
Zitat:

Zitat von r_kerber
Delphi-Quellcode:
TGetErrorMsg = function (lngSession: longint; lngResult: longint;
                         strLanguage, strMessage: PChar;
                         lngMessageLength: int64): longint; stdcall;

Du hast für "size_t" "int64" benutzt.
"size_t" ist vier Byte groß, "int64" ist acht Byte groß.

Besser ist "UINT"/ "Cardinal"/ "DWORD".

r_kerber 16. Mär 2007 09:19

Re: Aufrufparameter für C-Funktionen in DLL's
 
Zitat:

Zitat von ste_ett
Du hast für "size_t" "int64" benutzt.
"size_t" ist vier Byte groß, "int64" ist acht Byte groß.

Besser ist "UINT"/ "Cardinal"/ "DWORD".

Hatte ich auch schon geändert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:40 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-2025 by Thomas Breitkreuz