0

我使用 ATL 创建了一个简单的 DLL 项目,代码如下:

class main_window : 
    public wtlext::LayeredWindow<ATL::CWindowImpl<main_window>, bool>,
    public CVWModule,
    public IPropertyObserver
{
// Construction
public:
    main_window();
    ~main_window();

    HWND Create(HWND hWndParent)
    {
        ATL::CWindowImpl<main_window>::Create(hWndParent, rcDefault, NULL,
            WS_POPUP | WS_VISIBLE,
            WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED);

        return m_hWnd;
    };
}

字符是 unicode 并且 runtimelibrary 是 MDd

异常警告:代码 0xC0000005 类型:访问冲突 描述:线程试图读取或写入虚拟地址,但它没有适当的访问权限。exe中的0x76fe8dc9处最可能的异常: 0xC0000005: 写入位置0x00000014时访问发生冲突</p>

给您带来不便,第一次在这里发帖,请见谅。
我发现 exe 使用了 CAPPMODULE ,此外我发现项目使用了 WTL。在 DLL 主 CPP 下方。` //#include "stdafx.h" //#include "iconized.h" //#include "iconizedDlg.h"

// #define UNICODE
// #define _UNICODE 

CAppModule _Module;



HINSTANCE hDll_Instance;
HWND hWnd;


extern "C" BOOL WINAPI DllMain( HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
{



    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        {

            hDll_Instance = (HINSTANCE)hModule;



            //ShowWindow();
        }
        break;
    case DLL_THREAD_ATTACH:
        {

        }

        break;
    case DLL_THREAD_DETACH:

        break;
    case DLL_PROCESS_DETACH:{

        ;
                            }
                            break;
    }
    return TRUE;
}

 int WINAPI Iconized_tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
 {
    //AtlAxWinInit();
    Gdiplus::GdiplusStartupInput gdiplusStartupInput; 
    ULONG_PTR gdiplusToken; 
    int nRet = -1;


    // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
    ::DefWindowProc(NULL, 0, 0, 0L);

    // create VW module window as soon as we can
    iconized::main_window *pMainWnd = new iconized::main_window;
    assert(pMainWnd != 0);

    // Init module (ATL magic starts here)
    HRESULT  hRes = _Module.Init(NULL, hInstance);
    ATLASSERT(SUCCEEDED(hRes));

    AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);  // add flags to support other controls

    // Init GDI+
    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    // create main window
    if(pMainWnd->Create(0) == NULL)
    {
    ATLTRACE(_T("Main window creation failed!\n"));
    return 0;
    }

    pMainWnd->ShowWindow(nCmdShow);

    // Run main message loop
    CMessageLoop theLoop;
    _Module.AddMessageLoop(&theLoop);

    nRet = theLoop.Run();

    _Module.RemoveMessageLoop();

    // main window must be destroued before GDI+ is shutdown 
    // in order to release its resources properly
    pMainWnd->Destroy();

    // Finalize GDI+
    Gdiplus::GdiplusShutdown(gdiplusToken);

    _Module.Term();

    delete pMainWnd;

//#ifdef USE_MEMTRACK
//    std::stringstream s;
//    MemTrack::TrackDumpBlocks(s);
//    ::MessageBox(0, s.str().c_str(), "Memblocks", MB_OK);
//#endif

     return 0;
 }

`

4

1 回答 1

0

这个问题已经解决了,原因是没有调用InitializeCriticalSection(...);因为我使用了loadlibrary(*.dll),导致全局变量(_AtlWinModule,_AtlBaseModule,_AtlComModule后面被ATL组件使用)未初始化. 所以在这种情况下,将 _CRT_INIT 添加到 DLLMain 可以克服访问问题,crt_INIT 函数可以帮助初始化相关的全局变量。喜欢 :

DLLMain增加_CRT_INIT (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
  {
   //_CRT_INIT(hModule,ul_reason_for_call,lpReserved);}
于 2013-03-07T10:22:54.513 回答