14

为什么 Delphi 变体不能保存对象?更重要的是,这种限制背后的原因是什么?

4

3 回答 3

26

您绝对可以将对象存储在 Variant 变量中 - 只需将其转换为 NativeUInt。无论如何,对象只是一个指针。

obj := TObject.Create;
v := NativeUInt(obj);
obj := TSomeObject(NativeUInt(v));
于 2008-12-14T10:03:53.993 回答
8

根据我对变体可以做什么和不能做什么的经验,这只是一种观点。

如果您将 COM 对象放入其中,它将存储为 IDispatch 引用,因此您在此对象上访问的任何方法调用或属性都将转换为查找方法/属性的内部 DISPID 的一些代码,一个数组将构造带有方法参数的方法,并通过 IDispatch 接口调用该方法。

换句话说,IDispatch 为您处理,您通常必须这样做,但它是由编译器自动完成的。

然而,对于普通的 Delphi 对象,事情变得更加困难。您可以使用 RTTI 来查找和调用已发布的方法和属性,仅此而已。如果您有一个未发布的、非虚拟方法的名称,Delphi 无法在您的方法上找到它的正确地址。

换句话说,你所能做的就是拿着这个物体,你将无法使用它。也许他们可以增加对释放它的支持,但同样,可能就是这样。

我知道一个事实,如果您正确实现 IDispatch,您可以安全地存储,并通过变体使用该对象。我有一个类可以用作您想要执行此操作的 Delphi 对象的基类。它会自动公开发布的方法/属性,如果你想通过一些受保护的方法调用,你可以添加更多。如果对这样的课程感兴趣,我可以将其放在某个地方。

但同样,这是通过 IDispatch,它使用已发布的方法,其余的是手动代码,因此对变体的支持必须由您构建到您的对象中。

这就是为什么我认为他们只是说:这只会产生抱怨,我们可以持有一个对象,但它只是没用。

但这只是我的想法。也许某个官员有一个更好的答案。

于 2008-12-14T09:44:18.510 回答
7

我过去曾使用 Variant 来使用 Variant 内部来保存对象,代码是这样的:

var
  MyObject: TMyObject;
  Value: Variant;
begin
  MyObject:= TMyObject.Create;
  TVarData(Value).VType:= VarByRef or VarUnknown;
  TVarData(Value).VPointer:= MyObject;
于 2008-12-14T14:52:33.770 回答