ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NET Interop层和COM之间会发生什么?

2019-12-08 12:07:39  阅读:204  来源: 互联网

标签:com com-interop tlbimp c net


我在C#.NET项目中使用COM.
但是,我调用的方法之一无法正常工作.
所以我很好奇我的.NET代码,Interop层和COM之间发生了什么.
我知道tlbimp.exe会为COM组件生成元数据包装,并且可以在对象浏览器中看到这些生成的方法.
我可以查看/调试这些包装方法之一时会发生什么情况吗?

我将数组传递给下面的方法,并期望将填充该数组,但是不会填充该数组.
我正在调用以下tlbimp.exe生成的方法,结果异常:

int GetTags(System.Array buffer)
    Member of CServer.IUser

方法IDL:

[id(0x000000d5)]
HRESULT GetTags(
                [in] SAFEARRAY(long) buffer, 
                [out, retval] long* retval);  

.NET代码调用此方法:

Array tagsArray = Array.CreateInstance(typeof(int), tagsLength);
userWrapper.GetTags(tagsArray);

我称之为的其他COM方法工作正常.但是,当我调用任何将Array作为参数的方法时,它无法按预期工作.
我假设COM interop编组器会发生一些有趣的事情.
因此,我想知道在调用GetTags()方法后是否可以看到正在发生的情况.

我也阅读了以下here.

“如果您对COM Interop编组器不满意,则可以通过非常大且有用的System :: Runtime :: InteropServices命名空间来“覆盖”它的几乎每个方面”

如何实现以上目标?

编辑:添加一个有效的Delphi测试脚本

procedure TComTestForm.TestUserBtnClick(Sender: TObject);
var
  nCnt :integer;
  User :IUser;
  Persona :IUserPersona;
  ArrayBounds :TSafeArrayBound;
  ArrayData :Pointer;
  TagList :PSafeArray;
  nSize :integer;
begin
  User := Session.GetUser;

  ArrayBounds.lLbound   := 0;
  ArrayBounds.cElements := 0;

  TagList := SafeArrayCreate( varInteger, 1, ArrayBounds );
  User.GetTags( TagList );
  if SafeArrayAccessData( TagList, ArrayData ) = S_OK then
    begin
      nSize := TagList.rgsabound[0].cElements;
      OutLine( '----Available Tags, ' + IntToStr(nSize) + ' tags' );
  for nCnt := 0 to nSize - 1 do
    begin
      OutLine( IntToStr( IntegerArray(ArrayData)[nCnt] ) );
    end;
  OutLine( '----');

  SafeArrayUnAccessData( TagList );
  SafeArrayDestroy( TagList );
    end;

end;

解决方法:

另一个更新:
我只是意识到这可能是您的意思是,GetTags本身应该填充该Array(来自COM代码).但这永远无法工作,因为该参数是[in]参数.

为了使COM组件能够填充该数组,应将其作为[in,out]参数并通过引用(SAFEARRAY *)进行传递.

更新:好的,显然我在将.NET中COM组件的创建与从.NET中调用COM组件混合在一起.

CCW(可调用包装器)确实为COM SafeArray采用了.NET数组.我看到您在问题中的代码中创建了数组,但是没有显示实际填充它的方式.该代码可能有问题吗?你能分享吗?

不知道这是否可以解决您的问题,但过去我在使用COM-interop和SAFEARRAY时遇到过问题.

我从中学到的一件事是,COM SAFEARRAY的.NET等效项应该始终是对象,因此请尝试将数组作为对象而不是作为数组传递.

标签:com,com-interop,tlbimp,c,net
来源: https://codeday.me/bug/20191208/2091436.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有