我在我的 C# .NET 项目中使用 COM。
但是,我调用的其中一种方法没有按预期运行。
所以我很想知道我的 .NET 代码、互操作层和 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 互操作编组器有一些有趣的地方。
所以我想知道我打电话后是否能看到发生了什么GetTags()
方法后是否可以看到发生了什么。
我也在这里阅读了以下内容。
"if you are not satisified with the COM Interop marshaller, you can "override" just about every aspect of it through the very large and useful System::Runtime::InteropServices namespace"
我怎样才能实现上述目标?
编辑:添加一个有效的 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;