在Delphi中将对象转换为OleVariant

3

有没有一种方法可以在OleVariant中传递和取消包装TObject派生类?我正在尝试在自动化对象之间传递TObject。我知道这不是一个好主意,但我没有更好的选择。

如果对象要在同一自动化dll的对象之间传递,那么是否有所不同。

类似这样:

function GetMyObjAsVariant;
var
  MyObj: TMyObj;
begin
  MyObj := TMyObj.Create;
  result := OleVariant(MyObj);
end;

这将被客户端用作

var
  MyObj: TMyObj;
begin
  MyObj := GetMyObjAsVariant as TMyObj;
end;

这段代码无法通过编译,会返回

E2015 Operator not applicable to this operand type.
3个回答

4
你可以编写并注册自定义的Variant类型;可以参考TSQLTimeStampVariantType进行实例操作。
另一种选择是编写你的类的自动化包装器。双重dispinterface通过IDispatch自动支持后期绑定,而IDispatch又被OleVariant所支持。

2

如果你确实、真正地想要这样做,并且你确定两个对象在同一个进程中,那么你可以将任何TObject转换为整数,然后再转回TObject:

function GetMyObjAsVariant;
var
  MyObj: TMyObj;
begin
  MyObj := TMyObj.Create;
  result := OleVariant(Integer(MyObj));
end;

然后:

var
  anInt: Integer;
  MyObj: TMyObj;
begin
  anInt := GetMyObjAsVariant;
  MyObj := TMyObj(anInt);
end;

如所述:这仅适用于同一进程内。因此,仅适用于进程COM对象(dll)! - Lars Truijens
这就是我一直在寻找的技巧!其他答案也不错,但这个满足了我目前的需求,谢谢。 - Alan Clark
如果它是一个进程内的COM DLL,那么为什么你要在第一时间就限制自己使用OLEVariant呢?只有在提供调度接口(用于自动化客户端)时才需要坚持自动化兼容类型。对于一个进程内的COM DLL,我认为你可以简单地选择退出自动化类型安全并直接传递你的TObject。但是,我已经很久没有在那个层面上做COM了,所以我可能记错了。 - Deltics
该dll包装了一些现有的TObject类。其中一些包装需要共享一个TObject。以前,我只是定义了一个全局实例,并让每个人都访问它。但是当有多个dll实例时,这种方法不起作用。因此,我必须正确地传递对象。另一个解决方案是将公共对象本身重新创建为自动化对象以传递它,但在这种情况下,这是很多工作。我希望我已经清楚地解释了这种情况。 - Alan Clark

2
让您的对象实现一个接口并传递该接口。
function GetMyObjAsVariant: OleVariant;
var
  MyObj: IMyObj;
begin
  MyObj := TMyObj.Create;
  result := MyObj;
end;

var
  MyObj: IMyObj;
begin
  MyObj := GetMyObjAsVariant as IMyObj;
end;

我不能保证这个方法一定有效,你应该采纳TOndrej的建议并为你的类创建自动化封装器。如果你对此比较熟悉,那么这并不难。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接