Ihr S7
Parameter als out
Parameter deklariert wird, so wird der Compiler die übergebene Variable auf eine leere Zeichenfolge gesetzt, wenn die Funktion aufgerufen wird. Sie übergeben dieselbe S
Variable für alle Parameter, einschließlich des Ausgabeparameters, sodass der Wert S
aus dem Speicher gelöscht wird, bevor die Parameterwerte in der Funktion verwendet werden.
erarbeiten weiter, wird das Verfahren der register
Aufrufkonvention verwenden, wo S1
.. S3
werden in CPU-Register übergeben (EAX, EDX und ECX, respectively) und S4
.. S6
statt auf dem Stack übergeben werden. Die Eingabe string
Variable wird gelöscht gelöscht, nachdem der aktuelle Wert auf dem Stapel für S4
und S5
(S3
und S6
sind nur Zeiger auf die Variable) und bevor der Wert S1
und S2
zugewiesen wird. Also, S1
und S2
Ende bis null, S4
und S5
enthalten Zeiger auf die ursprünglichen 'S'
Daten vor dem Wischen und S3
und S6
zeigen auf dem string
Variable, die abgewischt wurde.
Der Debugger kann Ihnen alles in Aktion zeigen. Wenn Sie einen Haltepunkt an der Linie setzen, wo MyProcedure()
genannt wird, und dann die CPU-Ansicht öffnen, sehen Sie die folgende Montageanleitung finden Sie unter:
StringTest.dpr.17: MyProcedure(S, S, S, S, S, S, S);
00405A6C 8B45FC mov eax,[ebp-$04] // [ebp-$04] is the current value of S
00405A6F 50 push eax // <-- assign S4
00405A70 8B45FC mov eax,[ebp-$04]
00405A73 50 push eax // <-- assign S5
00405A74 8D45FC lea eax,[ebp-$04]
00405A77 50 push eax // <-- assign S6
00405A78 8D45FC lea eax,[ebp-$04]
00405A7B E8B0EDFFFF call @UStrClr // <-- 'out' wipes out S!
00405A80 50 push eax // <-- assign S7
00405A81 8D4DFC lea ecx,[ebp-$04] // <-- assign S3
00405A84 8B55FC mov edx,[ebp-$04] // <-- assign S2
00405A87 8B45FC mov eax,[ebp-$04] // <-- assign S1
00405A8A E8B9FEFFFF call MyProcedure
Um dies zu beheben, müssen Sie eine andere Variable verwenden, um die Ausgabe zu erhalten :
procedure Work;
var
S, Res: String;
begin
S := 'S';
Proc(S, S, S, S, S, S, Res);
WriteLn(Res);
end;
Alternativ ändern, das Verfahren in eine Funktion, die eine neue String
über seine Result
anstelle der Verwendung eines out
Parameter liefert:
function MyFunction(S1: String; const S2: String; var S3: String;
S4: String; const S5: String; var S6: String): String;
begin
Result := '1' + S1 + '2' + S2 + '3' + S3 + '4' + S4 + '5' + S5 + '6' + S6;
end;
procedure Work;
var
S: String;
begin
S := 'S';
WriteLn(MyFunction(S, S, S, S, S, S));
end;
Vorsicht: Wenn Sie einen Parameter mit 'const' deklarieren, sagen Sie dem Compiler, dass er nicht erwarten sollte, dass sich der Parameter für die Dauer dieser Funktion ändert. Es liegt in Ihrer Verantwortung sicherzustellen, dass Sie dieses Versprechen einhalten; Der Compiler kann es nicht für Sie überprüfen. In diesem Fall modifizieren Sie 'S' durch' S7', während Sie gleichzeitig 'S2' und' S5' nicht ändern. –