2 Stimmen

Delphi - Problem bei der Verwendung einer existierenden DLL

Ich muss eine vorhandene DLL verwenden, habe aber ein Problem damit.

So versuche ich es zu benutzen:

unit u_main;

...
implementation

procedure getUserData(var User, Pass: string); stdcall; external 'Common5.dll';

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  u, p: string;
begin
   getUserData(u,p);
end;
...
end.

Wenn ich den Button drücke, um die Benutzerdaten zu erhalten, erhalte ich eine EInvalidPointer-Ausnahme. Die DLL ist registriert und wird in anderen Projekten verwendet und funktioniert. Irgendwelche Ideen?

EDIT: Die DLL wurde in Delphi7 erstellt und wird jetzt in einem Delphi 2009-Projekt verwendet. Vielleicht gibt es ein Problem mit Unicode-Zeichenfolgen oder ähnlichem?

4voto

Cosmin Prund Punkte 25218

Sie müssen die Delphi 7 DLL neu erstellen und sie nach dem WinApi-Standard mit den Parametern PChar und BufferLen versehen. Sie haben mehrere Probleme mit der aktuellen Implementierung:

  1. string ist plattformspezifisch, seine Implementierung kann sich zwischen Delphi-Versionen ändern (und hat sich geändert). Sie sollen den string-Typ außerhalb der Plattform nicht verwenden!
  2. Sie übergeben die Parameter als "var", was darauf hindeutet, dass die DLL den Wert des Benutzers und/oder des Parameters ändern könnte. String ist ein spezieller, verwalteter Typ, dessen Änderung das Allokieren von Speicher für den neuen String erfordert. Dies wiederum erfordert, dass Sie den Speichermanager zwischen der DLL und der EXE teilen (unter Verwendung von sharemem.pas und BorlandMM.dll - oder Varianten). Das Problem dabei ist, dass das Teilen des Speichermanagers zwischen verschiedenen Delphi-Versionen eine nicht unterstützte Konfiguration ist! (aus den Embarcadero-Foren)
  3. Die Delphi 7 erwartet eine einfache AnsiString (1 Byte Zeichen), während die Delphi 2009-EXE Unicode-Strings sendet (2 Bytes pro Zeichen).

1voto

Chris Thornton Punkte 15410

Zusätzlich zur Verwendung von PChar sollten Sie darauf achten, den Speicherplatz vor dem Aufruf von GetUserData vorab zuzuweisen. Wenn Sie z.B. 'foo' einem leeren PChar zuweisen, wird es explodieren. Verwenden Sie also entweder PChar/PAnsiChar-Arrays mit statischer Länge oder verwenden Sie diese Technik:

var
  s : AnsiString;
begin
  setlength(s,256);
  MyDLLProc(PAnsiChar(s));
end;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X