これはライブラリに問題があるようです。の実装CreateNamed
は次のとおりです。
constructor TOmniValue.CreateNamed(const values: array of const;
const cppDupConWorkaround: boolean);
var
i : integer;
name: string;
ovc : TOmniValueContainer;
begin
ovc := TOmniValueContainer.Create;
Assert(not Odd(Low(values)));
name := '';
for i := Low(values) to High(values) do begin
with values[i] do begin
if not Odd(i) then
case VType of
vtChar: name := string(VChar);
vtString: name := string(VString^);
vtPChar: name := string(StrPasA(VPChar));
vtAnsiString: name := string(VAnsiString);
vtVariant: name := string(VVariant^);
vtWideString: name := WideString(VWideString);
{$IFDEF UNICODE}
vtUnicodeString: name := string(VUnicodeString);
{$ENDIF UNICODE}
else
raise Exception.Create ('TOmniValue.CreateNamed: invalid name type')
end //case
else
case VType of
vtInteger: ovc.Add(VInteger, name);
vtBoolean: ovc.Add(VBoolean, name);
vtChar: ovc.Add(string(VChar), name);
vtExtended: ovc.Add(VExtended^, name);
vtString: ovc.Add(string(VString^), name);
vtPointer: ovc.Add(VPointer, name);
vtPChar: ovc.Add(string(StrPasA(VPChar)), name);
vtAnsiString: ovc.Add(AnsiString(VAnsiString), name);
vtCurrency: ovc.Add(VCurrency^, name);
vtVariant: ovc.Add(VVariant^, name);
vtObject: ovc.Add(VObject, name);
vtInterface: ovc.Add(IInterface(VInterface), name);
vtWideString: ovc.Add(WideString(VWideString), name);
vtInt64: ovc.Add(VInt64^, name);
{$IFDEF UNICODE}
vtUnicodeString: ovc.Add(string(VUnicodeString), name);
{$ENDIF UNICODE}
else
raise Exception.Create ('TOmniValue.CreateNamed: invalid data type')
end; //case
end; //with
end; //for i
SetAsArray(ovc);
end; { TOmniValue.CreateNamed }
例外は、raise
上記の 2 つのステートメントの最初のステートメントによって発生します。例外は、処理できないタイプの値が指定されたことを示すために使用されます。結局のところ、長さ 1 の文字列リテラルを指定した場合の値の型は ですvtWideChar
。実際、このタイプはまったく処理されません。
CreateNamed
したがって、単一の文字ではなく文字列を受け取るように呼び出しを強制することで、この問題を回避できます。
Value := TOmniValue.CreateNamed([
string('a'), 42,
string('b'), 666
]);
私の見解では、単一の文字を受け入れるようにライブラリを変更する方がよいでしょう。すでに処理されており、処理されAnsiChar
ないのは単純な省略であると思われWideChar
ます。コードは次のように読むべきだと思います:
constructor TOmniValue.CreateNamed(const values: array of const;
const cppDupConWorkaround: boolean);
var
i : integer;
name: string;
ovc : TOmniValueContainer;
begin
ovc := TOmniValueContainer.Create;
Assert(not Odd(Low(values)));
name := '';
for i := Low(values) to High(values) do begin
with values[i] do begin
if not Odd(i) then
case VType of
vtChar: name := string(VChar);
vtString: name := string(VString^);
vtPChar: name := string(StrPasA(VPChar));
vtAnsiString: name := string(VAnsiString);
vtVariant: name := string(VVariant^);
vtWideString: name := WideString(VWideString);
vtWideChar: name := string(VWideChar);
{$IFDEF UNICODE}
vtUnicodeString: name := string(VUnicodeString);
{$ENDIF UNICODE}
else
raise Exception.Create ('TOmniValue.CreateNamed: invalid name type')
end //case
else
case VType of
vtInteger: ovc.Add(VInteger, name);
vtBoolean: ovc.Add(VBoolean, name);
vtChar: ovc.Add(string(VChar), name);
vtExtended: ovc.Add(VExtended^, name);
vtString: ovc.Add(string(VString^), name);
vtPointer: ovc.Add(VPointer, name);
vtPChar: ovc.Add(string(StrPasA(VPChar)), name);
vtAnsiString: ovc.Add(AnsiString(VAnsiString), name);
vtCurrency: ovc.Add(VCurrency^, name);
vtVariant: ovc.Add(VVariant^, name);
vtObject: ovc.Add(VObject, name);
vtInterface: ovc.Add(IInterface(VInterface), name);
vtWideString: ovc.Add(WideString(VWideString), name);
vtWideChar: ovc.Add(string(VWideChar), name);
vtInt64: ovc.Add(VInt64^, name);
{$IFDEF UNICODE}
vtUnicodeString: ovc.Add(string(VUnicodeString), name);
{$ENDIF UNICODE}
else
raise Exception.Create ('TOmniValue.CreateNamed: invalid data type')
end; //case
end; //with
end; //for i
SetAsArray(ovc);
end; { TOmniValue.CreateNamed }
報告: OTL issue #64