4

I have a library that exports an unmanaged C routine that returns pointers to COM IUnknown-based objects. The DLL is not registered, and is not server. I would like to use the COM types from C#.

I have already written C# interfaces for the COM types. What is the C# equivalent of calling LoadLibrary() and GetProcAddress()? How would I call the result of GetProcAddress() and then call it to load a COM interface pointer?

Here is a snippet of C++ that illustrates what I am after:

// Assume I have previously declared IMyType
HANDLE mylib = ::LoadLibrary("myfakecom.dll");
IUnknown* (*GetterFunc) getter;
getter = (GetterFunc)::GetProcAddress(mylib, "GetFactory");
IUnknown *unk = getter();
IMyType *mytype = unk->QueryInterface(IID_MYTYPE);

My gut says "Do it with C++/CLI", though I am unsure of how I would do this for any generic type, and how I would coerce the raw IUnknown pointers into the manager pointer types I would declare using the [Guid] attributes on a managed interface.

1
  • You should make a new question rather than trying to re-use this one to ask a follow up. New question means new eyes. Commented Jan 31, 2010 at 20:27

1 Answer 1

2

You just need to use interop to describe your GetFactory function, something like this

[DllImport("myfakecom.dll")]
[return: MarshalAs(UnmanagedType.IUnknown)]
static extern object GetFactory();

Then once you have the object in managed code. A cast is the equivalent of QueryInterface

void Foo(Object unk)
{
    IMyType mytype = (IMyType)unk;
} 

You will need to duplicate your C++ interface definitions as C# interface definitions, possibly with [marshalas] attributes. But since you have already done that, the rest should be easy.

I would suggest that you change your factory prototype from

IUnknown * GetFactory();

to

HRESULT GetFactory([out] IUnknown ** ppunk);

There seems to be a strong assumption by the COM iterop code that all COM methods return HRESULT and it will be simpler to get the marshalling to work if you go with the flow there.

Sign up to request clarification or add additional context in comments.

3 Comments

Awesome! I hadn't realized that the COM interop stuff was implemented in terms of the same P/Invoke marshalling types. Should've been obvious. Thanks.
Okay, this all works for the situations where you have a specific DLL you are going to invoke out of; however, what if you want to invoke any DLL at runtime?
@Armentage: I suggest you make a new question, I don't know the answer to that off the top of my head, but I'll bet someone here does.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.