Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Programm stürzt bei Zugriff auf DLL ab (https://www.delphipraxis.net/121878-programm-stuerzt-bei-zugriff-auf-dll-ab.html)

WorstNightmare 6. Okt 2008 12:37


Programm stürzt bei Zugriff auf DLL ab
 
Hi,

ich habe eine DLL geschrieben, die mir einfachen Zugriff auf die Grundfunktionen von RegExpr.pas gibt, da ich noch viele andere Libraries habe, die Reguläre Ausdrücke verwenden, und diese nicht wegen RegExpr.pas 100 KB größer werden sollen.
Bei mir funktioniert die DLL auch (Vista Ultimate SP1), nur bei einem Kollegen (Windows XP SP3) stürzt das Programm, welches auf die DLL zugreift, ab.

Dies ist der Code in der DLL:
Delphi-Quellcode:
library RegExp;

{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muss sich in der
  ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt-
  Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die
  Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle
  Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die
  sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur
  Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL.
  Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String-
  Informationen als PChar- oder ShortString-Parameter übergeben. }

uses
  RegExpr;

{$R *.res}

function RegEx(Mask, Source: PChar): PChar; stdcall;
var
  RE: TRegExpr;
begin
  RE := TRegExpr.Create;
  RE.Expression := Mask;
  try
    if RE.Exec(Source) then
      Result := PChar(RE.Match[0])
    else
      Result := 'kein Treffer';
  finally
    RE.Free;
  end;
end;

exports
  RegEx;

begin
end.
Und so sieht die Zugriffs-Unit aus:
Delphi-Quellcode:
unit RegExp;

interface

const
  LIB = 'Plugins\RegExp.dll';
  NOT_MATCHED = 'kein Treffer';

function RegExProc(Mask, Source: PChar): PChar; stdcall; external LIB name 'RegEx';
function RegEx(Mask, Source: string): string;

implementation

function RegEx(Mask, Source: string): string;
begin
  Result := RegExProc(PChar(Mask), PChar(Source));
end;

end.
Ein Aufruf sieht z.B. so aus:
Delphi-Quellcode:
var
  s: string;
begin
  s := RegEx('\d+', 'asd123dsa');
end;
Beides wurde mit Delphi 2009 kompiliert.
Liegt der Fehler in meinem Code, oder kann es auch an etwas anderem liegen?

Bernhard Geyer 6. Okt 2008 12:39

Re: Programm stürzt bei Zugriff auf DLL ab
 
PChar(RE.Match[0]) ist nach verlassen der DLL-Funktion nicht mehr gültig. Du gibst es ja mit RE.Free den Speicher frei.

Apollonius 6. Okt 2008 12:49

Re: Programm stürzt bei Zugriff auf DLL ab
 
Am einfachsten wäre es wohl, von PChar auf Widestring umzustellen. Der Speicher von Widestrings wird nämlich von einer Windows-DLL verwaltet, also sollte es keine Probleme geben.

WorstNightmare 6. Okt 2008 13:02

Re: Programm stürzt bei Zugriff auf DLL ab
 
Ich habe es jetzt so abgeändert:
Delphi-Quellcode:
function RegEx(Mask, Source: PChar): PChar; stdcall;
var
  RE: TRegExpr;
  M: string;
begin
  RE := TRegExpr.Create;
  RE.Expression := Mask;
  try
    if RE.Exec(Source) then
    begin
      M := RE.Match[0];
      Result := PChar(M)
    end
    else
      Result := 'kein Treffer';
  finally
    RE.Free;
  end;
end;
Das Problem mit dem ungültigen PChar wäre somit doch gelöst, oder?
Der Fehler tritt bei meinem Kollegen jedoch immer noch auf :?

Apollonius 6. Okt 2008 13:04

Re: Programm stürzt bei Zugriff auf DLL ab
 
Beim verlassen der Routine wird bei allen referenzierten Strings der Referenzzähler dekrementiert. Somit ist der zurückgegebene String immer noch ungültig.

WorstNightmare 6. Okt 2008 14:07

Re: Programm stürzt bei Zugriff auf DLL ab
 
Hm, mir ist gerade auch eingefallen, dass es eigentlich noch nicht einmal daran liegt. Das Programm stürzt direkt beim Eintritt in die Routine ab (ich weiß nicht ob es überhaupt soweit kommt).

Woran kann das nur liegen? :x

Luckie 6. Okt 2008 14:19

Re: Programm stürzt bei Zugriff auf DLL ab
 
Du übergibst da mit deinen PChar Zeiger auf Speicherbereiche, aber ist der dahinter liegende Speicher überhaupt reserviert oder greift die DLL ins Leere? Siehe dazu auch hier: Rückgabe von Strings aus DLLs

gispos 6. Okt 2008 16:48

Re: Programm stürzt bei Zugriff auf DLL ab
 
Versuchs mal so:
Delphi-Quellcode:
function RegEx(Mask, Source: PChar; out P : PChar): Integer; stdcall;
var
  RE: TRegExpr;
  A: AnsiString;
begin
  Result:= 0;
  RE := TRegExpr.Create;
  RE.Expression := Mask;

  try
    if RE.Exec(Source) then
      A := RE.Match[0]
    else
      A := 'kein Treffer';

    GetMem(P, Length(A) + 1);
    Result:= Length(A) + 1;
    MoveMemory(P, @A[1], Result);
  finally
    RE.Free;
  end;

end;

exports
  RegEx;

begin
end.
Aufruf
Delphi-Quellcode:
var
  P: PChar;
  I: Integer;
begin
   I:= 0;
  I:= RegEx('\d+', 'asd123dsa', P);
  If I > 0 then
  begin
    Caption:= P;
    FreeMem(P, I);
  end;
end;
Gruß gispos

Apollonius 6. Okt 2008 16:52

Re: Programm stürzt bei Zugriff auf DLL ab
 
Du gibst mit einem Speichermanager frei, was du mit dem anderen allozierst. Das kann nicht funktionieren. Du müsstest eine weitere Funktion FreeString exportieren, in der du den PChar dann freigibst.

gispos 6. Okt 2008 17:07

Re: Programm stürzt bei Zugriff auf DLL ab
 
Zitat:

Zitat von Apollonius
Du gibst mit einem Speichermanager frei, was du mit dem anderen allozierst.

Hmm… ich denke der Speicherbereich liegt auf der aufrufenden Anwendung, und kann auch von dieser frei gegeben werden. P ist als out deklariert.
Oder sehe ich da etwas falsch, bei mir laufen diese Routinen ohne Probleme. Könntest Du das genauer Erklären?

Gruß gispos


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:07 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz