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