none
Discovering COM object parameters (late binding) RRS feed

  • Question

  • I am trying to write a generic wrapper to some legacy COM objects using C#.  The objects are numerous and support a large number of methods, so I don't want to have to hand craft proxies.

    The root problem is VB6's inability to preserve Binary Compatibility, and the problems that generates.  By using this wrapper to late bind to the objects, we should be able to get away without referencing the objects directly, and avoid the compatibility issues.

    However, in order for this to work, I need to discover the parameter types for any method call, so I can correctly set the 'byval/byref' flags in the Invoke call.  To date I have failed in this.  Reflection only gives me the names in the RCW, not the underlying object (e.g. Type.GetMember will not return a name that works with Type.InvokeMember - different interpretations on the word Member?).

    I can do this in C++ if that will work, by getting the ITypeInfo objects, but again I cannot see how to get the Parameter metadata (only the parameter counts).

    Any help etc.

    Tony
    Thursday, June 26, 2008 1:35 PM

Answers

  • You'd use the IDispatch::GetTypeInfo() method.  That gives you an ITypeInfo interface pointer on which you can call GetFuncDesc() to the get the FUNCDESC method description.  Before you go there, ask yourself if you can make this flexible enough to deal with a VB6 interface that has a completely new method.  Or a method whose arguments have changed.  And beware of the large amount of overhead you'll add to each method invocaton.

    Also, VB.NET has the ability to call late-bound interfaces built into the language.  Writing a VB.NET assembly that wraps the VB6 interfaces can save you a tremendous amount of time hacking obscure and errorprone IDispatch code.
    Hans Passant.
    • Marked as answer by Bruno Yu Wednesday, July 2, 2008 6:37 AM
    Thursday, June 26, 2008 5:56 PM
    Moderator

All replies

  • You'd use the IDispatch::GetTypeInfo() method.  That gives you an ITypeInfo interface pointer on which you can call GetFuncDesc() to the get the FUNCDESC method description.  Before you go there, ask yourself if you can make this flexible enough to deal with a VB6 interface that has a completely new method.  Or a method whose arguments have changed.  And beware of the large amount of overhead you'll add to each method invocaton.

    Also, VB.NET has the ability to call late-bound interfaces built into the language.  Writing a VB.NET assembly that wraps the VB6 interfaces can save you a tremendous amount of time hacking obscure and errorprone IDispatch code.
    Hans Passant.
    • Marked as answer by Bruno Yu Wednesday, July 2, 2008 6:37 AM
    Thursday, June 26, 2008 5:56 PM
    Moderator
  • Thanks for your reply.

    That is what I have been trying to do.  However, I keep getting "Object must be visible to COM" errors.  It is visible to COM, as an InvokeMember call on it works in the same way as an early bound implementation.  All I am trying to do is get the byref/byval attributes (why is it so hard).

    I will look at the VB.NET route to see if that helps.
    Friday, June 27, 2008 10:26 AM
  • TonyCapps,

    As far as I've knwon, the best thread on unmanaged COM interface and .NET objects is the thread with the answer by TaylorMichaelL:

    COM Interop: Base class properties not exposed to COM

    Actually I've learned from nobugz and TaylorMichaelL, too. I hope this can help you to understand your "Object must be visible to COM" errors better.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Wednesday, July 2, 2008 6:37 AM
  • Thanks for all your replies.   I gave up trying to discover the parameter types, and am now using a generic wrapper, and some specific overloads for the cases I have probems with, and then calling NewLateBinding.LateCall (in Visual Basic library) to make the call, as this handles ByRef.

    I'll continue to try to make the discovery work, but in the meantime a job has to be done!

    Tony
    Wednesday, July 2, 2008 7:44 AM