From: glitteringsounds on
Hello,

I need to determin the COM component(unmanaged code) type and invoke
the exposed interface's methods using reflection in C#.NET at
runtime.

1 -- First What member of "Type" tells that type is COM component and
we can take CLSID at runtime? Is Type.COMObject?
2 -- I need to call methods of exposed interfaces as they called in
unmanaged code using CoCreateInstance by passing CLSID and REFID ... I
am using InvokeMember but it returns null or 0 as out parameter.

How to pass out parameter in this case.? Is there any need to pass out
parameter? As all my COM unamanged code suppose to take las parameter
as an OUT parameter and after executing it puts the result into that
out param. But I've converted all my unmanged COM code to .NET managed
assemblies using tlbimp.exe.

Regards
Usman
From: Peter Duniho on
glitteringsounds wrote:
> Hello,
>
> I need to determin the COM component(unmanaged code) type and invoke
> the exposed interface's methods using reflection in C#.NET at
> runtime.

Taken literally, the above is impossible. COM is designed in a way
that, unless you implement IDispatch, the client code is required to
already know the types it's using. Even if the object implements
IDispatch, you still need to find out it implements IDispatch (i.e. by
calling QueryInterface()) and then use IDispatch to access the object
members.

> 1 -- First What member of "Type" tells that type is COM component and
> we can take CLSID at runtime? Is Type.COMObject?

I don't recall the exact type, but yes�the default RCW type is a special
type that has "ComObject" in the name (the name is actually something
longer, with underscores and maybe some other stuff�I don't recall off
the top of my head the exact type, but it's easy enough to look and find
out if you've already got some COM interop working).

> 2 -- I need to call methods of exposed interfaces as they called in
> unmanaged code using CoCreateInstance by passing CLSID and REFID ... I
> am using InvokeMember but it returns null or 0 as out parameter.

You use CoCreateInstance() to create instances of COM objects, not to
call methods of those COM objects. In unmanaged code, you simply call
the methods by using an appropriately-typed pointer variable.

In managed code, ideally you should be using the .NET COM interop
features (e.g. the [ComImport] attribute and related).

> How to pass out parameter in this case.? Is there any need to pass out
> parameter? As all my COM unamanged code suppose to take las parameter
> as an OUT parameter and after executing it puts the result into that
> out param. But I've converted all my unmanged COM code to .NET managed
> assemblies using tlbimp.exe.

If you've used tlbimp.exe, there should be no need for you mess around
with Type.InvokeMember(). You can just "new" the co-class that
implements the interface of interest, using either that class or just
the interface itself (tlbimp.exe will generate both).

See also the System.Runtime.InteropServices.Marshal class for a number
of methods useful for going back and forth between RCW objects and
native IntPtr values for the unmanaged interface, as well as managing
reference counts (if you don't want to rely on the GC to release your
COM objects).

As for the 'out' arguments, it depends on how they are declared. If in
the TLB they are declared as 'retval' in addition to 'out', then
tlbimp.exe will map that to an actual return value by removing the
argument from the method signature and marshaling the last argument as
the return value of the method.

If the arguments are just simple 'out', then you'll have to use them as
'out' arguments in C#.

Whether the argument is mapped as an 'out' argument or a return value,
the [MarshalAs] attribute will allow you to control how the data being
returned from the COM interface is marshaled to a managed type.

Pete