【问题标题】:Interface Marshalling in DelphiDelphi中的接口编组
【发布时间】:2011-01-28 03:37:21
【问题描述】:

我想将 IVApplication 的接口引用从 Visio 加载项发送到我的另一台 COM 服务器。但我有 Ole 例外。现在我这样做了:

Visio 加载项中的代码:

var 
  IStrm: IStream;
  hres: HResult;
  rhglobal: HGLOBAL;
  VisioAppl: IVApplication; 
begin

   hres := CreateStreamOnHGlobal(0, TRUE, IStrm);
      if Succeeded(hres) then
        hres := CoMarshalInterface(IStrm, IID_IVApplication, VisioAppl,
                            MSHCTX_LOCAL, 0,
                            MSHLFLAGS_NORMAL);
      if (Succeeded(hres)) then
      begin
          hres := GetHGlobalFromStream(IStrm, rhglobal);
          if Succeeded(hres)  then
             Result := rhglobal;
          IStrm := nil;
      end;
 end;

之后,我创建了我的 COM 服务器实例并将 rhglobal 传递给他。

我的 COM 服务器代码:

procedure (AHGlobal: HGlobal);
var
  VisioAppl: Visio_TLB.IVApplication;
  iStrm: IStream;
  hres: HResult;
begin

      iStrm := Nil;
      VisioAppl:= nil;
      hres := CreateStreamOnHGlobal(AHGlobal, FALSE, iStrm);
      if (SUCCEEDED(hres)) then
      begin

        hres := CoUnmarshalInterface(iStrm, Visio_TLB.IVApplication, VisioAppl);
        iStrm := nil;
        ShowMessage('Result:' + BoolToStr(SUCCEEDED(hres)));  <-- result 0 
        ShowMessage(VisioAppl.ProductName); <----  Error
      end;

end;

【问题讨论】:

  • 欢迎来到 Stack Overflow。你在问什么“结果为0”?如果你在谈论“hres”,它在你的两个代码示例中被分配了 5 次。你问的是哪一个?如果你真的问了一个问题,你就有更好的机会得到答案。
  • 我认为这是显而易见的。在代码中放置不良结果已用注释“
  • 如何实际计算在这种情况下设置的 hres 并推动它通过一些东西来计算错误代码,只是有时他们实际上会告诉你你是如何搞砸的 :) 我个人的猜测是可能您的特定 visio 界面没有代理。

标签: delphi com interface marshalling ole


【解决方案1】:

你为什么不在你的 COM 服务器中定义一个方法并创建一个 VARIANT 参数呢? (或 IDispatch* 或 IUknown*)。

然后您可以将 VisioApplication 传递给您的 COM 服务器,并在服务器端将其转换回 Visio_TLB.IVApplication 接口。

所以它看起来像这样:

插件:

procedure SendAppToComServer(aIntf: Visio_TLB.IVApplication);
begin
  MyComServer.PassVisioApp(aIntf);
end;

通讯服务器:

procedure TMyComServer.PassVisioApp(VisioApp: OleVariant);
var
  VisioAppIntf: Visio_TLB.IVApplication;
begin
  VisioAppIntf := VisioApp;
  ShowMessage(VisioAppIntf.ProductName);
end;

【讨论】:

  • COM 没关系。我自动化了 OpenOffice.org,我可以毫无问题地将接口传递给侦听器到 OpenOffice.org 的进程外 COM 服务器。当然,当 Visio 和您的插件关闭并且您的 COM 服务器想要访问 Visio 应用程序时会出现问题,但这是您必须注意的事情。
  • 哦,谢谢!真的很管用!当我将参数作为 IDispatch 而不是 OleVariant 传递时。但我不明白为什么它会起作用。
猜你喜欢
  • 2014-12-11
  • 2015-11-06
  • 2011-10-01
  • 2010-11-28
  • 2013-05-17
  • 2014-02-27
  • 2013-04-19
  • 1970-01-01
  • 2017-10-22
相关资源
最近更新 更多