Einzelnen Beitrag anzeigen

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