Регистрация COM класса
Создал в Visual Studio ATL проект
В test.idl описал такой интерфейс
[ uuid(92FAFEE3-71D8-49C6-91DD-8B1560C6FA68), oleautomation ] interface ITest : IUnknown { HRESULT _stdcall Create(); };При компиляции проекта создался файл test_i.h с абстрактным классом
MIDL_INTERFACE("92FAFEE3-71D8-49C6-91DD-8B1560C6FA68") ITest : public IUnknown { public: virtual HRESULT __stdcall Create( void) = 0; };Я от него отнаследовался и реализовал методы
class CITestImpl : public ITest { private: volatile ULONG refCount; public: virtual HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject); virtual ULONG __stdcall AddRef(void); virtual ULONG __stdcall Release(void); virtual HRESULT __stdcall Create(void); }; HRESULT __stdcall CITestImpl::QueryInterface(REFIID riid, void** ppvObject) { if (!ppvObject) return E_INVALIDARG; *ppvObject = NULL; if (riid == IID_IUnknown || riid == IID_ITest) { *ppvObject = (LPVOID)this; AddRef(); return NOERROR; } return E_NOINTERFACE; } ULONG __stdcall CITestImpl::AddRef(void) { return InterlockedIncrement(&refCount); } ULONG __stdcall CITestImpl::Release(void) { ULONG res = InterlockedDecrement(&refCount); if (res == 0) delete this; return res; } HRESULT __stdcall CITestImpl::Create(void) { return S_OK; }
Теперь вопрос: как этот класс передать в фабрику классов для его регистрации?
В dllmain.hесть такой класс
class CTestModule : public ATL::CAtlDllModuleT< CTestModule >
{
public :
DECLARE_LIBID(LIBID_TestLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_TEST, "{45092c55-0c4e-4362-8bb6-96a8c824d65e}")
};
extern class CTestModule _AtlModule;
Как я понимаю, именно здесь и нужно добавить мой класс. А как?
Ответы (1 шт):
В idl файле создаем coclass
[ uuid(1EFA49AE-DBF4-4C57-9625-B22BA2CF40C7) ] coclass CoTest { [default] interface ITest; };Создаем или редактируем rgs файл
HKCR { NoRemove CLSID { ForceRemove {1EFA49AE-DBF4-4C57-9625-B22BA2CF40C7} = s 'Test COM Object' { InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } TypeLib = s '{45092c55-0c4e-4362-8bb6-96a8c824d65e}' Version = s '1.0' } } }Убеждаемся, что в rc файле есть строчка
IDR_TEST REGISTRY "Test.rgs"Указываем правильных родителей для класса, где реализован интерфейс и добавляем пару макросов
class ATL_NO_VTABLE CTestImpl : public ATL::CComObjectRoot, // Здесь уже реализованы методы IUnknown public ATL::CComCoClass<CTestImpl, &CLSID_CoTest>, public ITest { public: BEGIN_COM_MAP(CTestImpl) COM_INTERFACE_ENTRY(ITest) //сообщаем какие интерфейсы поддерживает наш класс END_COM_MAP() DECLARE_REGISTRY_RESOURCEID(IDR_TEST) // Указываем, что записать в реестр при регистрации // Inherited via ITest STDMETHOD(Create)(); // Объявление самих интерфейсных методов }И в итоге, в dllmain.cpp добавляем строку
OBJECT_ENTRY_AUTO(CLSID_CoTest, CTestImpl)
После этого все компилируем и регистрируем через regsvr32.
Разбирался вот по этому репозиторию на гитхабе