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] ='Short1' then 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] ='short2' then 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] ='Short3' then 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] = 'Datei5' then 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] ='Short4' then 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.gcf' then 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