2009-03-25 11 views
1

Ich versuche, WTL innerhalb einer In-Prozess-COM-Server-DLL (ein IE BHO) zu verwenden, aber ich kämpfe mit _Module.Wie verwende ich WTL in einer DLL?

Meine DLL muss CMyModule von CAtlDllModuleT<> abgeleitet:

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(); 
} 

Aber diese Konflikte mit den meisten WTL Beispiele, die innerhalb stdafx.h so etwas wie dies erfordern:

extern CAppModule _Module; // WTL version of CComModule 

Egal, wie ich es tun, Ich (nicht überraschend) bekomme Kompilierungsfehler. CMyModule abgeleitet von CAppModule Borken auf _Module.DllUnregisterServer() usw. CMyModule abgeleitet von CAtlDllModuleT<> Borks auf Code wie _Module.GetMessageLoop().

Haben Sie gute Referenzen darüber, wie WTL in einer DLL funktionieren soll? Google findet viele Fragen mit wenigen Antworten.

Antwort

0

Haben Sie die Option der Mehrfachvererbung in Betracht gezogen? Versuchen Sie, von CAtlDllModule und CAppModule zu erben, da Sie beide benötigen.

+0

Ich habe versucht, das aber gegeben habe es ein bisschen mehr von einem jetzt gehen. Bringt mich so weit, aber eins führt zum anderen. Scheint, dass mehrfaches Erben mit CAtlBaseModule mir zu wenig gibt (z. B. GetMessageLoop fehlt in _Module). Vererben mit CAppModule gibt zu viel (z. B. uneindeutigen Zugriff von DLLMain). – Mat

1

Ich habe ein Projekt, das WTL in einer DLL verwendet. Ich sah, wie meine Header sind eingerichtet und es sieht aus wie ich hackte um das gleiche Problem ...

Ich habe mein Modul eingerichtet wie Ihre Beispielcode erben von CAtlDllModuleT <> außer dem Namen der globalen Modul-Variable ist _AtlModule statt _Module. Beispiel:

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

CMyModule _AtlModule; 

So verwenden alle Einstiegspunkte DllMain.cpp _AtlModule. Dann in der Datei stdafx.h sieht es wie folgt aus:

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

Das _pModule Sache in atlbase.h wie definiert:

__declspec(selectany) CComModule* _pModule = NULL; 

Es muss einen besseren Weg, aber dies funktioniert.

0

Ich verwende WTL in einem Office-Add-In; das folgende funktioniert für mich. (Am Ende der 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; 

Und dann der DLL Haupt Verwendung _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; 
}