Delphi 中的接口编组

发布于 2024-08-25 12:15:20 字数 1287 浏览 13 评论 0原文

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

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;

I want to send Interface Ref of IVApplication from Visio Add-in to my other one COM server. But I have Ole exception. Now i do that:

Code in Visio Add-in:

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;

After this I create instance of my COM server and pass rhglobal to him.

Code of my COM server:

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尘曦 2024-09-01 12:15:20

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

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

所以它看起来像这样:

Addin:

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

Comserver:

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

Why don't you just define a method in your COM server and make a VARIANT parameter? (or IDispatch* or IUknown*).

Then you can just pass the VisioApplication to your COM server and at the serverside cast it back to the Visio_TLB.IVApplication interface.

So it will look like this:

Addin:

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

Comserver:

procedure TMyComServer.PassVisioApp(VisioApp: OleVariant);
var
  VisioAppIntf: Visio_TLB.IVApplication;
begin
  VisioAppIntf := VisioApp;
  ShowMessage(VisioAppIntf.ProductName);
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文