AW: DLL mit Strings von D10 nach Delphi 6
Thinking more :gruebel:
We don't need a string, just a copy of the string in the memory adjusted to look like a string and let the DLL clear its string nicely and orderly meaning return the pointer with 8 bytes increase, as long the return fake string have refcount = -1 the application will copy its content as string from constant with the right length, this will simplify the Garbage collector from restoring the string then force to clear, or to have to save original refcount and restore it. |
AW: DLL mit Strings von D10 nach Delphi 6
@kmma ,
Have you tested the proposed constant hack ? Please try this
Code:
Would love to know if this works ?
// these for single thread
function BuiltOldAnsiString(const aString: AnsiString): Pointer; overload; function BuiltOldAnsiString(const aString: string): Pointer; overload; // these for multi thread application // these might leave one memory leak per thread as worse case, just one leak that can be registered function BuiltOldAnsiStringMt(const aString: AnsiString): Pointer; overload; function BuiltOldAnsiStringMt(const aString: string): Pointer; overload; implementation var gTempBufferForEmulatedOldAnsi: array of byte; threadvar gTempBufferForEmulatedOldAnsiThreadSafe: array of byte; function BuiltOldAnsiString(const aString: AnsiString): Pointer; overload; var Len: Integer; Mem: PCardinal; begin Len := Length(aString); if Len = 0 then begin Result := nil; Exit; end; SetLength(gTempBufferForEmulatedOldAnsi, Len + 8 + 1); // header + 1 null ansi char Mem := @gTempBufferForEmulatedOldAnsi[0]; Mem^ := $FFFFFFFF; // refcount =(-1) emulating constant string Inc(Mem, 1); Mem^ := Len; Inc(Mem, 1); Move(aString[1], Mem^, Len); PByte(Mem)[Len + 1] := 0; // make sure it is null terminated Result := Mem; end; function BuiltOldAnsiString(const aString: string): Pointer; overload; begin Result := BuiltOldAnsiString(AnsiString(aString)); end; function BuiltOldAnsiStringMt(const aString: AnsiString): Pointer; overload; var Len: Integer; Mem: PCardinal; begin Len := Length(aString); if Len = 0 then begin Result := nil; Exit; end; SetLength(gTempBufferForEmulatedOldAnsiThreadSafe, Len + 8 + 1); // header + 1 null ansi char Mem := @gTempBufferForEmulatedOldAnsiThreadSafe[0]; Mem^ := $FFFFFFFF; // refcount =(-1) emulating constant string Inc(Mem, 1); Mem^ := Len; Inc(Mem, 1); Move(aString[1], Mem^, Len); PByte(Mem)[Len + 1] := 0; // make sure it is null terminated Result := Mem; end; function BuiltOldAnsiStringMt(const aString: string): Pointer; overload; begin Result := BuiltOldAnsiString(AnsiString(aString)); end; |
AW: DLL mit Strings von D10 nach Delphi 6
Man könnte den StrRec-Record aus der System.pas benutzen, um sich die Stringkonstante zu bauen, wenn Emba sich nicht vehement weigern würde ihn öffentlich zu machen.
Ja, Wenn RefCount = -1, dann wird es als Konstante behandelt, also Funktionen, welche die Variable kopieren oder freiheben würden, würden es entsprechend beachten.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:34 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