AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Speicherzugriffsverletzung bei Parameterübergabe aus DLL!

Speicherzugriffsverletzung bei Parameterübergabe aus DLL!

Offene Frage von "Sillium"
Ein Thema von Sillium · begonnen am 1. Apr 2006 · letzter Beitrag vom 21. Mai 2006
Antwort Antwort
Sillium

Registriert seit: 9. Jul 2005
24 Beiträge
 
#1

Speicherzugriffsverletzung bei Parameterübergabe aus DLL!

  Alt 1. Apr 2006, 10:17
Hallo,

ich habe für ein Projekt von mir einige Funktionen zwecks einfacherer Updates in eine Dll ausgelagert! Prinzipiell kenne ich mich mit DLLs aus und bis auf eine Funktion läuft auch alles, wie gewollt!

Heir die Prozedur, die mir Probleme macht:

Delphi-Quellcode:
procedure checkFiles(DirP :PChar; GShortP : Array of PChar;var AResultStr : Pchar);stdcall;
var
  Dir, List, GameMiss :String;
  GShort : Array of String;
  MissingShort : Array of String;
  i,a,b,GNum : Integer;
  evenAdded, MainMiss : boolean;
begin
  MainMiss := FALSE;
  Dir := String(DirP);
  setlength(GShort,length(GShortP));
  For i := 0 to length(GShortP)-1 do
    GShort[i] := String(GShortP[i]);
  For i := 0 to length(GShort)-1 do begin
      GNum := 1;
      If GShort[i] ='Short1then begin
        If not FileExists(Dir+'Datei1') then begin
            setlength(MissinGShort,length(MissinGShort)+1);
            MissinGShort[length(MissinGShort)-1] := 'Datei1';
          GameMiss := 'True';
        end
        else begin
          GameMiss := 'False';
        end;
      end;
      If GShort[i] ='short2then begin
        If not FileExists(Dir+'Datei2') then begin
          setlength(MissinGShort,length(MissinGShort)+1);
          MissinGShort[length(MissinGShort)-1] := 'Datei2';
          GameMiss := 'True';
        end
        else begin
          GameMiss := 'False';
        end;
      end;
      If GShort[i] ='Short3then begin
        If not FileExists(Dir+'Datei3') then begin
          setlength(MissinGShort,length(MissinGShort)+1);
          MissinGShort[length(MissinGShort)-1] := 'Datei3';
          GameMiss := 'True';
        end
        else begin
          GameMiss := 'False';
        end;
        If not FileExists(Dir+'Datei4') then begin
          setlength(MissinGShort,length(MissinGShort)+1);
          MissinGShort[length(MissinGShort)-1] := 'Datei4';
         GameMiss := 'True';
        end
        else begin
          If GameMiss <> 'True'then
          GameMiss := 'False';
        end;
      end;
     .
     . //Und
     . //so
     . //weiter
     .
      If not FileExists(Dir+'Datei5') then begin
          For b := 0 to length(MissinGShort)-1 do
            If MissinGshort[b] = 'Datei5then evenadded := true;
          if not evenadded then begin
            setlength(MissinGShort,length(MissinGShort)+1);
            MissinGShort[length(MissinGShort)-1] := 'Datei5';
          end;
          MainMiss := True;
         end;
      If GameMiss <> 'then
          If (GameMiss = 'False') and (not MainMiss) then
            If i = 0 then
              List := GShort[i]+'*T*' + IntToStr(Gnum) + Chr(13)
            else
              List := List + GShort[i]+'*T*' + IntToStr(Gnum) + Chr(13)
          else if (GameMiss = 'True') or (MainMiss) then
            If i = 0 then
              List := GShort[i]+'*F*' + IntToStr(Gnum) + Chr(13)
            else
              List := List + GShort[i]+'*F*' + IntToStr(Gnum) + Chr(13) ;
          GameMiss := '';
          MainMiss := False;
      end;
    For i := 0 to length(GShort)-1 do begin
    GNum := 2;
        If GShort[i] ='Short4then begin
        If not FileExists(Dir+'Datei6') then begin
          setlength(MissinGShort,length(MissinGShort)+1);
          MissinGShort[length(MissinGShort)-1] := 'datei6';
           GameMiss := 'True';
        end
        else begin
          GameMiss := 'False';
        end;
        .
        . //Und
        . //so
        . //weiter
        .
        If not FileExists(GCFDir+'Source Dedicated Server.gcf') then begin
          For b := 0 to length(MissinGShort)-1 do
            If MissinGshort[b] = 'Source Dedicated Server.gcfthen evenadded := true;
          if not evenadded then begin
            setlength(MissinGShort,length(MissinGShort)+1);
            MissinGShort[length(MissinGShort)-1] := 'Source Dedicated Server.gcf';
          end;
          MainMiss := True;
        end;
      If GameMiss <> 'then
          If (GameMiss = 'False') and (not MainMiss) then
            If List ='then
              List := GShort[i]+'*T*' + IntToStr(Gnum) + Chr(13)
            else
              List := List + GShort[i]+'*T*' + IntToStr(Gnum) + Chr(13)
          else if (GameMiss = 'True') or (MainMiss) then
            If List =''  then
              List := GShort[i]+'*F*' + IntToStr(Gnum) + Chr(13)
            else
              List := List + GShort[i]+'*F*' + IntToStr(Gnum) + Chr(13) ;
          GameMiss := '';
          MainMiss := False;
    end;
      For a:=0 to length(MissinGShort)-1 do
        List := List + Chr(13) + '\' + MissinGShort[a];
      //i := length(List); <--------Wenn ich mir zum debuggen diese Zeilen auskommentiere,
      //messagedlg(IntToStr(i),mtWarning ,mbYesNoCancel ,1); <--------Und mir z.B. die Länge von List ausgeben lass, bekomme
      //messagedlg(List,mtWarning ,mbYesNoCancel ,1); <--------ich später keine Zugriffsverletzung mehr!
    AResultStr := nil;
    AResultStr := PChar(List);
end;
Ich checke abhängig von gewissen Parameter (als Array übergeben) ob die dazugehörigen Dateien vorhanden sind oder nicht! Insgesamt sammele ich alle Informationen in einem String (List), den ich dann als PChar in AResultStr kopiere!

Ich habe versucht AResultStr zum einen als Rückgabewert einer Funktion zu übergeben:
Delphi-Quellcode:
function checkFiles(DirP :PChar; GShortP : Array of PChar): Pchar;stdcall;
.
.
.
AResultStr := PChar(List);
result := AResultStr;
Oder eben wie oben als Var-Parameter!

Beides mal bekomme ich eine Speicherzugriffsverletzung!

Aber ich komme nicht auf den Grund des Problems, weil:

1.

Wenn ich mir zur Laufzeit in Delphi die Variable List anschaue, ist alles ok!

Sieht so aus:
List := 'datei1*T*1'#$D'datei2*T*1'#$D'datei3*T*1'...... Doch beim übergeben an AResultStr mit:
AResultStr := PChar(List); bleibt AResultStr unbestimmt!

Und ich bekomme die Zugriffsverletzung beim nächsten Schritt!


2.

Wenn ich mir zur Laufzeit, z.B die Läbge von List als MessageDlg anzeigen lass funktioniert später die übergabe von List auf AResultStr ohne Probleme und ich bekomme keine Speicherzugriffsverletzung!

3.

Wenn ich die gleiche Procedure nehme, Alles weglasse und nur einen String von Hand eingebe und an AResulStr übergeben lasse funktioniert auch alles!
Beispiel:
Delphi-Quellcode:
procedure checkFiless(GCFDirP :PChar; GShortP : Array of PChar;var AResultStr : Pchar);stdcall;
var
   Astr :String;
begin
   Astr := 'Short1*T*1' + Chr(13) + 'Short1*T*1' + Chr(13) +'Short1*T*1' + Chr(13) +'Short1*T*1' + Chr(13) +'Short1*T*1' + Chr(13) +'Short1*T*1' + Chr(13) + '\' + 'Datei1'   + Chr(13) + '\' + 'Datei1'+ Chr(13) + '\' + 'Datei1';
   AResultStr := Pchar(Astr);
end;
Danke, dass ihr bis hier durchgehalten habt!

Sillium
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#2

Re: Speicherzugriffsverletzung bei Parameterübergabe aus DLL

  Alt 21. Mai 2006, 12:53
Wie sieht die USES-Liste der DLL aus?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Speicherzugriffsverletzung bei Parameterübergabe aus DLL

  Alt 21. Mai 2006, 13:25
nach dem aus deiner Funktion zurück gekehrt wurde ist "List" nicht mehr definiert sondern freigegeben. Das heißt dein Pointer auf "List" (also dein Result) zeigt auf eine Stelle im Speicher die nicht mehr da ist.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#4

Re: Speicherzugriffsverletzung bei Parameterübergabe aus DLL

  Alt 21. Mai 2006, 13:33
Das vermute ich auch. Wenn er allerding den Delphi-MM benutzen würde, dann könnte er direkt Strings benutzen (deswegen die Frage nach der USES-Liste). Ist allerdings auch ein gewisser Overhead

Am besten ist es, wenn Aufrufer und Aufgerufener eine gemeinsame Funktion zum Allozieren und Deallizieren des Speichers haben ... dann kann der eine einen Pointer des anderen freigeben.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#5

Re: Speicherzugriffsverletzung bei Parameterübergabe aus DLL

  Alt 21. Mai 2006, 13:34
Jupp
Das AResultStr := nil; vor AResultStr := PChar(List); kannst'e erstmal weglassen ist "unnötiger" Code.

So könnte man dafür sorgen, das List nicht freigegeben wird.
Wie oben schon gesagt wurde, werden lockale Variablen am Ende der Prozedur freigeben (das Gilt zwar nicht für Objekte/Pointer..., wo nur de Zeiger "gelöscht" wird, aber bei Strings und dynamischen Arrays wird auch der Inhalt mit freigegeben.
Delphi-Quellcode:
AResultStr := PChar(List);
Pointer(AResultStr) := nil; // ändert nur den Pointer auf den String und läßt den Inhalt reserviert
Aber dann musß du dann später den String an der Stelle natürlich auch selber freigeben


[add]
DelphiMM
der DelphiMM shared den Speicher nicht und da dann in jedem Modul ein eigener MM aktiv ist, kann man die Strings "nicht" in ein anders Modul übergeben,
jedenfalls wenn dort dann der Sringinhalt geändert wird, wozu in vielen Fällen auch nur das ändern des Referenzzählers zählt...
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:52 Uhr.
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