其他分享
首页 > 其他分享> > NET Interop层和COM之间会发生什么?

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

作者:互联网

我在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