Please excuse the silly question, but I’m confused. Consider the following method (sorry for noisy comments, this is a real code under development):
function HLanguages.GetISO639LangName(Index: Integer): string;
const
MaxIso639LangName = 9; { see msdn.microsoft.com/en-us/library/windows/desktop/dd373848 }
var
LCData: array[0..MaxIso639LangName-1] of Char;
Length: Integer;
begin
{ TODO : GetLocaleStr sucks, write proper implementation }
//Result := GetLocaleStr(LocaleID[Index], LOCALE_SISO639LANGNAME, '??');
Length := GetLocaleInfo(LocaleID[Index], LOCALE_SISO639LANGNAME, @LCData, System.Length(LCData));
Win32Check(Length <> 0);
SetString(Result, @LCData, Length); // "E2008 Incompatible types" here, but why?
end;
If I remove the reference operator then implicit cast from $X+ comes to the rescue and method compiles. Why compiler refuses this code with reference operator is beyond my understanding.
This is Delphi XE2 and this behaviour might be specific to it.
And if I add a test-case dummy with equivalent prototype as intrinsic one within the scope of HLanguages.GetISO639LangName this error will magically go away:
procedure SetString(var s: string; buffer: PChar; len: Integer);
begin
{ test case dummy }
end;
You have to explicitly convert it to
PChar:As you stated,
SetString()is very demanding about the 2nd parameter type. It must be either aPChareither aPWideChareither aPAnsiChar, depending on the string type itself.I suspect this is due to the fact that
SetString()is defined as overloaded with either astring, aWideString, or anAnsiStringas 1st parameter. So in order to validate the right signature, it needs to have exact match of all parameters types:Of course, all those are “intrinsics”, so you won’t find such definition in system.pas, but directly some procedure like
_LStrFromPCharLen() _UStrFromPCharLen() _WStrFromPWCharLen()or such.This behavior is the same since early versions of Delphi, and is not a regression in XE2.