2017-01-30 4 views
1

Ich bin currentyl versucht, eine DLL zu schreiben, die eine Typelib (.tlb) im System registriert verbraucht. Diese Typelib erfordert, dass ich zwei Schnittstellen mit eigenen Klassen implementieren und registriere einen von ihnen in der Running Object Table, die ich in einem ATL-Projekt habe Visual Studio 2015Verwenden Sie _COM_SMARTPTR CreateInstance ohne Registrierung innerhalb der gleichen DLL

Die Anwendung, die mein DLL verbraucht sollte Keine Ahnung von COM überhaupt, alles sollte hinter den Kulissen funktionieren und von der DLL, die ich implementiere, versteckt sein.

Innerhalb meiner DLL versuche ich irgendwann, Instanzen einer Klasse MyClass zu bekommen, die die oben genannten COM-Schnittstellen der Typelib implementiert. Der Code sieht wie folgt aus:

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

IInterfaceClassPtr ist eigentlich ein Makro (all dies von Visual Studio generiert wird), die wie folgt aussieht:

_COM_SMARTPTR_TYPEDEF(IExampleInterface, __uuidof(IExampleInterface)); 

IExampleInterface in der Typelib I definiert ist verbrauchen, und implementiert von MyClass.

Wenn ich meine eigene DLL mit regsvr32 registriere, funktioniert alles gut. Aber ich möchte das vermeiden, weil es Admin-Privilegien benötigt.

Wenn meine DLL nicht registriert ist, schlägt der obige Aufruf mit HRESULT fehl "0x80040154, Klasse ist nicht registriert". Ich lese den Artikel Registration free activation of COM-Components (Und ein paar andere). Aber ich kann das Manifest der konsumierenden Anwendungen hier nicht optimieren - die Klasse (MyClass), die ich zu aktivieren versuche, lebt in der gleichen DLL wie der erwähnte "CreateInstance" -Aufruf.

Was muss ich tun, um Instanzen dieser Klassen ohne mit regsvr32 oder einigen Manifest-Tweaking erstellen zu können?

+0

Sie unter 'HKEY_CURRENT_USER \ Software \ Classes \ CLSID' registrieren kann dies nicht Admin erfordern – RbMm

Antwort

1

Sie können konkrete Instanzen Ihrer Objekte direkt in Ihrer DLL erstellen (vorausgesetzt, die Klassen sind dort implementiert).

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

CComObject<T>::CreateInstance erstellt eine Instanz eines COM-Objekt direkt durch den Aufruf new CComObject<T> so umgeht es die Registrierung.

Sie können dann QueryInterface für das Objekt verwenden, um Ihre erforderliche Schnittstelle zu erhalten.

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

Das ist mein Problem löst. Muss ich jedoch das CComObject löschen oder ruft pMyClassPtr-> Release() genug? – Vertigo

+2

Das Objekt wird über 'new' erstellt und hat einen initialen RefCount von' 0'. Sie sollten sofort 'AddRef' und dann' Release' aufrufen, wenn Sie mit dem Objekt fertig sind. 'Release' ruft' delete' für Sie auf. – lcs

Verwandte Themen