如何使用RTTI分配OleVariant?//将OleVariant或Variant转换为考虑了特定TTypeKind或



我有一个OleVariantVariant值,例如,它是用IXMLNode.GetAttributeNS读取的,使其成为"字符串"(varOleStrvarString(,我想用TRTTIField.SetValue写入该值,例如需要与TRTTIField.FieldType: TRTTIType兼容的TValue赋值。

对于基本类型(沿着TVarTypeTRTTIType.TypeKind: TTypeKind(,我正在寻找一种从OleVariantVariant转换为TValue的通用方法,而不是将每种类型都设为一个单独的情况:case VarType(Value) and varTypeMask of varXXXX: ... end,然后将其与特定的TRTTIType进行分配兼容。

如何在Variant和RTTI世界之间转换值?

此外,Spring4D库也是该项目的一部分,以防有帮助。


更新:

从技术上讲,我正在以下代码中寻找Convert(在变体世界中转换(:

var
Left: TRTTIField;
Right: OleVariant;
Temp: TValue;
Instance: Pointer;
begin
{ Examples: varOleStr --> varXXXX --> assignment-compatible TValue }
Right := 'False'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varBoolean
Temp := TValue.FromVariant(Right); // tkEnumeration, like Left.FieldType.TypeKind
Right := '2'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varInteger
Temp := TValue.FromVariant(Right); // tkInteger, like Left.FieldType.TypeKind
Right := '3.1415'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varDoiuble
Temp := TValue.FromVariant(Right); // tkFloat, like Left.FieldType.TypeKind
Right := 'Hello!'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varOleStr
Temp := TValue.FromVariant(Right); // tkUString, like Left.FieldType.TypeKind
{ ... and an assignment: }
Left.SetValue(Instance, Temp);
end;

我已经找到了VariantChangeTypeEx,但我不知道如何将Left.FieldType与之联系起来,以使后续代码正常工作。——我也不介意在RTTI世界中转换,而是从Temp := TValue.FromVariant(Right)(tkUString(开始,然后以某种方式达到分配兼容性;因此Temp.Kind将变为tkEnumeration/布尔,tkFloat,。。。如CCD_ 24所给出的。

如何使用RTTI分配变量?或者,如何将变量转换为T值,然后进行赋值?

注意:如果字段类型和值类型的性质不同,则RTTIField.SetValue将以EInvalidCast失败,因为RTTI不会尝试更改值的性质。我在这里的困难是达到分配兼容性。


更新:给出答案后,以下代码勾勒出我的解决方案:

procedure (const Value: Pointer; const RTTIField: TRTTIField; const XMLNode: IXMLNode);
var
Temp1: OLEVariant;
Temp2: TValue;
begin
Assert(XMLNode.HasAttribute(Ref, Namespace));
Temp1 := XMLNode.GetAttributeNS(Ref, Namespace);
Temp2 := TValue.FromVariant(Temp1);
Temp2 := Temp2.Convert(RTTIField.FieldType.Handle{, FormatSettings}); // in Spring.TValueHelper
RTTIField.SetValue(Value, Temp2);
end;

TValue中的内置类型转换在这里对您没有帮助,因为它们只允许显式兼容(即可赋值(的类型。从技术上讲,如果您将Variant存储在TValue中而不"拆包"它(FromVariant在内部所做的(,它应该能够将Variant强制转换为通常可以强制转换/转换为的任何类型。但是,将持有"True"或"False"的Variant强制为布尔值至少有一个问题(请参阅https://quality.embarcadero.com/browse/RSP-20160)

然而,由于您已经在使用Spring4D,您可以使用其改进的TValue类型转换功能。

只需使用Spring.pasTValueHelperConvert方法。

在那里,您可以传递一个PTypeInfo(在代码中为Left.FieldType.Handle(和一个可选的TFormatSettings——默认情况下,它将使用当前区域设置。

在Variant和RTTI世界之间转换值的方法是什么?

在System中使用内置的类函数转换。RTTI。T值:

myTValue := TValue.FromVariant(myVariant);

从Variant值构建新的TValue记录。

FromVariant是一种静态方法,可用于使用存储的Variant值构建TValue记录。Value参数包含将存储在构建的TValue记录中的Variant。

相关内容

  • 没有找到相关文章

最新更新