tags:

views:

792

answers:

2

I'm trying to use WTL within an in-process COM server DLL (an IE BHO), but am struggling with _Module.

My DLL needs CMyModule derived from 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();
}

But this conflicts with most WTL examples, which require something like this within stdafx.h:

extern CAppModule _Module; // WTL version of CComModule

No matter which way I do it, I (unsurprisingly) get compile errors. CMyModule derived from CAppModule borks on _Module.DllUnregisterServer(), etc. CMyModule derived from CAtlDllModuleT<> borks on code like _Module.GetMessageLoop().

Any good references on how WTL is supposed to work within a DLL? Google finds lots of questions, with few answers.

A: 

Have you considered the option of multiple inheritance? Try inheriting from both CAtlDllModule and CAppModule since you need both.

1800 INFORMATION
I'd tried that but have given it a bit more of a go now. Gets me so far, but one things leads to another. Seems that multiple inheriting with CAtlBaseModule gives me too little (e.g. GetMessageLoop missing from _Module). Inheriting with CAppModule gives too much (e.g. ambiguous access of DLLMain).
Mat
+1  A: 

I have a project that uses WTL in a DLL. I looked at how my headers are set up and it looks like I hacked around this same problem...

I have my module set up like your sample code inheriting from CAtlDllModuleT<> except the name of the global module variable is _AtlModule rather than _Module. For example:

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

CMyModule _AtlModule;

So, all of the DllMain.cpp entry points use _AtlModule. Then in the stdafx.h file it looks like this:

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

That _pModule thing is defined in atlbase.h like:

__declspec(selectany) CComModule* _pModule = NULL;

There must be a better way, but this does work.

Skrymsli