1

I've created a COM library defined in an IDL, it has an "entrypoint" called IFoo:

[
    object,
    uuid(789b4d46-4028-4196-8412-4c5c8ef86caa),
    nonextensible,
    pointer_default(unique)
]
interface IFoo: IUnknown
{
    HRESULT HelloWorld();
};

I've implemented this in my C# library like so:

[ComVisible(true)]
[Guid("45b50f1e-d551-4be0-b52a-7ec075840114")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IFoo))]
class Foo: IFoo
{
    public void HelloWorld()
    {
        Console.WriteLine("Hello world");
    }
}

I compiled this, and registered it with:

regasm.exe foo.dll

Everything looks good thus far.

Now, how do I create an instance of this in my C++ program? I think the right function is ::CoCreateInstance:

::CoInitializeEx(NULL, COINIT_MULTITHREADED); 
IUnknown *pUnk = 0;
HRESULT hr = ::CoCreateInstance(???, 
                                NULL, 
                                CLSCTX_INPROC_SERVER, 
                                __uuidof(IFoo), 
                               (void**)&pUnk);

Is this the right way to create an instance of this class? If so, what goes in "???" above?

I think the class's UUID ("45b50f1e-d551-4be0-b52a-7ec075840114" above) should go there, but I can't figure out how to manually create an IID from this GUID string.

2 Answers 2

2

It turns out, I was right, the class's UUID goes there, but getting it was something I didn't expect:

struct __declspec(uuid("45b50f1e-d551-4be0-b52a-7ec075840114")) Cls;

Then:

HRESULT hr = ::CoCreateInstance(__uuidof(Cls), 
                                NULL, 
                                CLSCTX_INPROC_SERVER, 
                                __uuidof(IFoo), 
                               (void**)&pUnk);

This fixed the problem and worked correctly.

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

Comments

1

Just use MIDL to compile your IDL file into set of C++ files and include them into your C++ program. Have in mind that interface is not the "entry point" and you are going to need the class object in your IDL too.

Another way to create a COM client in C++ is Microsoft specific #import directive, but I am not sure if it is compatible with .NET-based components. If you can create a .tlb file for your .NET component, you can just add the needed stuff like this:

#import "MyLibrary.tlb"

This directive has lots of options. Check this MSDN article for details.

4 Comments

I did use MIDL to compile down to a set of C++ files. I used this to produce a .lib I link against and a .h I include. I think you missed the point of the question, how to activate and create an instance of this class I made in .Net. Unless, of course, I'm misunderstanding your reply. =)
@LCC One of the files created by MIDL (namely your_lib_name_i.c) contains the definitions of all GUIDS in project and your_lib_name.h has the declarations of these GUIDS. By including these files into your C++ you will be able to use constants like CLSID_Foo in your COM functions calls.
You may have missed the CLSID of your class in your MIDL-generated files because your IDL is missing the class declaration
Ah, that makes sense. I didn't define the class there, so that's part of the problem. Thanks!

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.