Как я могу использовать WTL в DLL? - PullRequest
1 голос
/ 25 марта 2009

Я пытаюсь использовать WTL внутри внутрипроцессной DLL-библиотеки COM-сервера (IE BHO), но борюсь с _Module.

Моя DLL нуждается в CMyModule, полученном из CAtlDllModuleT<>:

class CMyModule : public CAtlDllModuleT< CMyModule >
{
public:
    DECLARE_LIBID(LIBID_MyLib)
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYPROJ, "{...}")
};

CMyModule _Module;

extern "C" BOOL WINAPI DllMain(...)
{
    hInstance;
    return _Module.DllMain(dwReason, lpReserved); 
}

...

STDAPI DllUnregisterServer(void)
{
    return _Module.DllUnregisterServer();
}

Но это противоречит большинству примеров WTL, которые требуют что-то вроде этого в stdafx.h:

extern CAppModule _Module; // WTL version of CComModule

Независимо от того, каким образом я это делаю, я (неудивительно) получаю ошибки компиляции. CMyModule получено из CAppModule borks на _Module.DllUnregisterServer() и т. Д. CMyModule получено из CAtlDllModuleT<> borks с кодом, подобным _Module.GetMessageLoop().

Какие-нибудь хорошие ссылки на то, как WTL должен работать в DLL? Google находит много вопросов, с несколькими ответами.

Ответы [ 3 ]

1 голос
/ 02 июня 2009

У меня есть проект, который использует WTL в DLL. Я посмотрел, как настроены мои заголовки, и похоже, что я взломал эту проблему ...

Мой модуль настроен так, как ваш пример кода, наследуемый от CAtlDllModuleT <>, за исключением того, что имя глобальной переменной модуля - _AtlModule, а не _Module Например:

class CMyModule : public CAtlDllModuleT< CMyModule >
{
public:
    DECLARE_LIBID(LIBID_MyLib)
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYPROJ, "{...}")
};

CMyModule _AtlModule;

Итак, все точки входа DllMain.cpp используют _AtlModule. Тогда в файле stdafx.h это выглядит так:

// WTL includes
#define _Module (*_pModule)
#include <atlapp.h>
#include <atlctrls.h>
#include <atldlgs.h>
#undef _Module

Эта вещь _pModule определена в atlbase.h как:

__declspec(selectany) CComModule* _pModule = NULL;

Должен быть лучший способ, но это работает.

0 голосов
/ 28 ноября 2010

Я использую WTL в надстройке Office; следующие работы для меня. (Внизу stdafx.h)

class DECLSPEC_UUID("XXXX-...") MyLib;

using namespace ATL;

/*
 * Application module
 */
class CAddInModule : public CAtlDllModuleT< CAddInModule >
{
public:
    CAddInModule() : m_hInstance(NULL)
    {
    }

    DECLARE_LIBID(__uuidof(MyLib))

    HINSTANCE GetResourceInstance()
    {
        return m_hInstance;
    }
    void SetResourceInstance(HINSTANCE hInstance)
    {
        m_hInstance = hInstance;
    }

private:

    HINSTANCE m_hInstance;
};

extern CAddInModule _AtlModule;

И затем основное использование DLL _AtlModule:

// DLL Entry Point
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    _AtlModule.SetResourceInstance(hInstance);
    return _AtlModule.DllMain(dwReason, lpReserved); 
}


// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
{
    return _AtlModule.DllCanUnloadNow();
}


// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}


// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    HRESULT hr = _AtlModule.DllRegisterServer();
    return hr;
}


// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
    HRESULT hr = _AtlModule.DllUnregisterServer();
    return hr;
}
0 голосов
/ 25 марта 2009

Рассматривали ли вы вариант множественного наследования? Попробуйте унаследовать от CAtlDllModule и CAppModule, так как вам нужны оба.

...