En Delphi, la cadena es un tipo de referencia que normalmente actúa como un tipo de valor. Se asigna en el montón (no en la pila como la mayoría de los tipos de valor) y cuenta con recuento automático de referencias y semántica de copia con escritura.
Para comprender lo que esto significa, considere cómo los tipos de valores normales, p. Ej. un entero, se comportan cuando se pasa como un parámetro a un procedimiento: parámetro
var
gValue: Integer;
procedure PassByValue(aValue: Integer);
begin
// Here @gValue <> @aValue
aValue := aValue + 2;
// Here @gValue <> @aValue
end;
procedure PassByRefrenceInOut(var aValue: Integer);
begin
// Here @gValue = @aValue
aValue := aValue + 2;
// Here @gValue = @aValue
end;
procedure CallProcedures;
begin
gValue := 0;
PassByValue(gValue);
// gValue is still 0
PassByReferenceInOut(gValue);
// gValue is 2
end;
El var en PassByReferenceInOut es equivalente a la convención C de pasar un puntero a la discusión.
la misma semántica se aplican a la cadena de paso de parámetros, pero hay una sutil diferencia en la representación interna de los valores:
var
gValue: string;
procedure PassByValue(aValue: string);
begin
// Here PChar(gValue) = PChar(aValue) <<<<
aValue := aValue + '2';
// Here PChar(gValue) <> PChar(aValue)
end;
procedure PassByRefrenceInOut(var aValue: string);
begin
// Here PChar(gValue) = PChar(aValue)
aValue := aValue + '2';
// Here PChar(gValue) = PChar(aValue)
end;
procedure CallProcedures;
begin
gValue := '';
PassByValue(gValue);
// gValue is still ''
PassByReferenceInOut(gValue);
// gValue is '2'
end;
Si desea asegurarse de que el procedimiento funciona con su propia copia de la cadena valor, utilice el procedimiento UniqueString, p. ej .:
procedure PassByValue(aValue: string);
begin
// Here PChar(gValue) = PChar(aValue)
UniqueString(aValue);
// Here PChar(gValue) <> PChar(aValue)
aValue := aValue + '2';
// Here PChar(gValue) <> PChar(aValue)
end;
Normalmente, esto no debería dar como resultado un AV. Sospecho que estos códigos se ejecutan desde DLL separadas? Use 'ShareMem' entonces. – NGLN
y 'algún error de violación de acceso' es? – RBA
@NGLN sí, estoy usando un dll escrito en C++, así que escribí un archivo de encabezado pas. Y estoy obteniendo AV en situaciones en las que no puedo entender por qué, probablemente este paso por referencia y no copiar causa AV cuando trabajo con punteros. –