Search code examples
c++windowswinapidllcom

Use _COM_SMARTPTR CreateInstance without Registration within the same DLL


I'm currentyl trying to write a DLL which consumes a Typelib (.tlb) registered in the system. This Typelib requires that I implement two interfaces with my own classes, and register one of them within the Running Object Table, which I did in an ATL project using Visual Studio 2015.

The Application that consumes my DLL should have no knowledge of COM at all, everything should work there behind the scenes and hidden by the DLL I'm implementing.

Within my DLL, at some point I'm trying to get Instances of a clas MyClass which implements the above mentionend COM-Interfaces of the Typelib. The code looks like this:

IInterfaceClassPtr dataPtr;
hr = dataPtr.CreateInstance(CLSID_MyClass);

IInterfaceClassPtr is actually a Macro (all of this is generated by Visual Studio), which looks like this:

_COM_SMARTPTR_TYPEDEF(IExampleInterface, __uuidof(IExampleInterface));

IExampleInterface is defined in the Typelib I consume, and implemented by MyClass.

If I'm registering my own DLL using regsvr32, everything works fine. But I want to avoid that because it requires Admin privileges.

If my DLL is not registered, the above call fails with HRESULT "0x80040154, Class is not registered". I read the article Registration free activation of COM-Components (And a few others). But I can't tweak the consuming applications' manifest here - the class (MyClass) I'm trying to activate lives in the very same DLL as the mentioned "CreateInstance" call.

What do I need to do to be able to Create Instances of these Classes without using regsvr32 or some Manifest-Tweaking?


Solution

  • You can create concrete instances of your objects directly within your DLL (assuming the classes are implemented there).

    CComObject<CMyClass>* pMyClassPtr;
    CComObject<CMyClass>::CreateInstance(&pMyClassPtr);
    pMyClassPtr->AddRef();
    

    CComObject<T>::CreateInstance creates an instance of a COM object by directly calling new CComObject<T> so it bypasses the registry.

    You can then use QueryInterface on the object to get your required interface.

    IInterfaceClassPtr spIInterface;
    pMyClassPtr->QueryInterface(&spIInterface);