Question

I am using COM in my C# .NET project.
However one of the methods I call is not acting as expected.
So I am curious to see what is happening between my .NET code, the Interop layer and COM.
I know the tlbimp.exe generates the metadata wrapper for the COM component and I can see these generated methods in the Object browser.
Am I able to see/debug what happens when one of these wrapper methods is called?

I pass an Array to the method below, and expect that this array will be populated, however the Array does not get populated. I am calling the following tlbimp.exe generated method with unexpected results:

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

Method IDL:

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

.NET code calling this method:

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

Other COM methods I call work fine. However when I call any method which expects an Array as a parameter it does not work as expected.
I am presuming that there is something funny going in with the COM interop marshaller.
So I would like to know if I can see what is happening after I call the GetTags() method.

Also I have read the following here.

"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"

How can I achieve the above?

EDIT: Adding a Delphi test script which works

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;

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top