Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the proper way of calling COM enumerators in .NET?

I am calling an externally provided COM DLL for which I have generated a COM interop wrapper. For the sake of argument, let's call the interface I want to call IEnumFoo.

IEnumFoo has the typical COM enumerator pattern:

HRESULT Next ( 
   ULONG        celt,
   IFoo**       rgelt,
   ULONG*       pceltFetched
);

where the first parameter is the number of desired results, the second parameter is a buffer to which results are written, and the last parameter describes the number of results actually written.

When I choose "Add Reference" and point Visual Studio at this DLL, it generates a COM Interop Assembly with the following signature:

void Next(uint, out IFoo, out uint)

This only allows the .NET code to request a single object at a time, which can add a significant amount of overhead to using these APIs.

Is there some mechanism I can use to generate a version of Next which would allow me to provide more IFoo "slots" above which would make the marshaler happy? (I'm not averse to editing the IL in the interop assembly by hand :) )

like image 579
Billy ONeal Avatar asked Mar 07 '14 03:03

Billy ONeal


1 Answers

The proper signature for this would be like so:

void Next(
    uint celt,
    [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] IFoo[] rgelt,
    out uint pceltFetched);

According to MSDN, at least, there's no mechanism to generate this automatically. Even if the original IDL for the interface had length_is applied to rgelt, that information is lost in the typelib. So you'll need to edit the interop assembly manually.

One other option is to define this particular interface entirely by hand in your main assembly, and simply ignore the generated interop version. Remember that when doing casts on RCWs, any interface with a matching GUID (i.e. the one for which QueryInterface is successful) will work, so you can actually have several different managed interfaces that present differing views of the same COM interface.

like image 98
Pavel Minaev Avatar answered Sep 25 '22 14:09

Pavel Minaev