2017-01-30 17 views
1

Я пытаюсь написать DLL, которая потребляет Typelib (.tlb), зарегистрированную в системе. Это Typelib требует, чтобы я реализовать два интерфейса со своими собственными классами, и зарегистрировать один из них в таблице запущенных объектов, которые я сделал в проекте ATL с помощью Visual Studio 2015.Использовать _COM_SMARTPTR CreateInstance без регистрации в пределах одной DLL

приложение, которое потребляет мой DLL должен иметь никакого знания COM вообще, все должно работать там за кулисами и скрываться от DLL, которую я реализую.

В моей DLL, в какой-то момент я пытаюсь получить экземпляры класа MyClass, который реализует вышеупомянутые COM-интерфейсы Typelib. Код выглядит следующим образом:

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

IInterfaceClassPtr фактически Macro (все это генерируется Visual Studio), который выглядит следующим образом:

_COM_SMARTPTR_TYPEDEF(IExampleInterface, __uuidof(IExampleInterface)); 

IExampleInterface определяется в TYPELIB я потребляем, и осуществляется по MyClass.

Если я регистрирую свою собственную DLL, используя regsvr32, все работает нормально. Но я хочу избежать этого, потому что он требует прав администратора.

Если моя DLL не зарегистрирована, вышеуказанный вызов завершился неудачно с HRESULT «0x80040154, класс не зарегистрирован». Я прочитал статью Registration free activation of COM-Components (И еще несколько других). Но я не могу настроить манифест потребляющих приложений здесь - класс (MyClass), который я пытаюсь активировать в той же DLL, что и упомянутый вызов «CreateInstance».

Что нужно сделать, чтобы создавать экземпляры этих классов без с помощью regsvr32 или некоторых манифестаций?

+0

вы можете зарегистрироваться в 'HKEY_CURRENT_USER \ Software \ Classes \ CLSID' это не требует администратора – RbMm

ответ

1

Вы можете создавать конкретные экземпляры ваших объектов непосредственно в своей DLL (при условии, что там реализованы классы).

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

CComObject<T>::CreateInstance создает экземпляр COM-объекта с помощью прямого вызова new CComObject<T> так он обходит реестр.

Затем вы можете использовать QueryInterface на объекте, чтобы получить необходимый интерфейс.

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

Это решает мою проблему. Однако мне нужно «удалить» CComObject или вызывать pMyClassPtr-> Release() достаточно? – Vertigo

+2

Объект создается с помощью 'new' и имеет исходный RefCount' 0'. Вы должны немедленно вызвать 'AddRef', а затем' Release', когда вы закончите с объектом. 'Release' будет вызывать' delete' для вас. – lcs