为什么Delphi变体不能保存对象?更重要的是,这种限制背后的原因是什么?
答案 0 :(得分:25)
你绝对可以存储 Variant变量中的对象 - 只需将其转换为NativeUInt即可。无论如何,对象只是一个指针。
obj := TObject.Create;
v := NativeUInt(obj);
obj := TSomeObject(NativeUInt(v));
答案 1 :(得分:8)
根据我对变体可以做什么和不能做什么的经验,这只是一个意见。
如果将COM对象放入其中,它将作为IDispatch引用存储,因此您在此对象上访问的任何方法调用或属性都将转换为查找方法/属性的内部DISPID的某些代码,将构造一个带有方法参数的数组,并通过IDispatch接口调用该方法。
换句话说,IDispatch是按照您通常必须的方式为您处理的,但它是由编译器自动完成的。
然而,对于普通的Delphi对象,事情会变得更难。您可以使用RTTI查找并调用已发布的方法和属性,但这就是它。如果你有一个非发布的非虚方法的名称,Delphi无法在你的方法上找到它的正确地址。
换句话说,您所能做的只是 hold 该对象,您将无法使用它。也许他们可以增加对释放它的支持,但同样可能就是它。
我知道如果您正确实现IDispatch,您可以安全地存储,并通过变体使用该对象。我有一个类可以用作你想要执行此操作的Delphi对象的基类。它将自动公开已发布的方法/属性,如果需要通过某些受保护的方法调用,则可以添加更多。如果对这样的课程感兴趣,我可以把它放在某个地方。
但同样,这是通过IDispatch,它使用已发布的方法,其余是手动代码,因此您必须在对象中内置对变体的支持。
这就是为什么我认为他们只是说:这只会产生抱怨,我们可以持有一个对象,但它只是没用。
但这只是我的想法。也许某位官员有更好的答案。
答案 2 :(得分:7)
过去使用变量内部使用Variants来保存对象,代码是这样的:
var
MyObject: TMyObject;
Value: Variant;
begin
MyObject:= TMyObject.Create;
TVarData(Value).VType:= VarByRef or VarUnknown;
TVarData(Value).VPointer:= MyObject;