length(s) zwraca rozmiar stringa w znakach […]
Nie bardzo – sama nazwa Length
oznacza, że chodzi o długość, nie o rozmiar. To trochę zagmatwane, bo nawet w dokumentacji, wyjaśnienie przeznaczenia tej funkcji nie jest jednoznaczne i może wprowadzać w błąd, jeśli nie czyta się uważnie.
Length
zwraca liczbę znaków – to dotyczy ciągów znaków o stałym rozmiarze code pointów, czyli dla typów AnsiString
(gdzie rezultat określa jednocześnie liczbę znaków oraz rozmiar w bajtach) oraz WideString
(rezultat to liczba znaków/code pointów).
Natomiast jeśli chodzi o typ UTF8String
, funkcja ta zwraca rozmiar w bajtach, a liczba znaków nie jest z góry znana.
[…] tymczasem do WriteProcessMemory trzeba przekazać rozmiar w bajtach, który można pozyskać za pomocą SizeOf(s).
SizeOf(S)
zwróci rozmiar wskaźnika (czyli 4
lub 8
, w zależności m.in. od kompilatora), nie objętość ciągu w bajtach. Nie wiem jakie to Delphi, jednak jeśli typ String
nie jest tożsamy z AnsiString
, to nie można użyć Length
i bajtowy rozmiar ciągu należy policzyć – pomnożyć liczbę znaków przez rozmiar znaku:
var
Text: String = 'text';
begin
// ANSI
WriteString($0A41A392, Text, Length(Text));
// Wide
WriteString($0A41A392, Text, Length(Text) * SizeOf(Char));
Mały tip: ciągi znaków zawsze przekazujemy przez stałą (ze słówkiem const
), jeśli nie potrzebujemy ich kopii wewnątrz podprogramu – jest to najszybszy sposób, więc warto o tym pamiętać.