Объявление HMODULE вызывает исключение во время выполнения

Я пишу DLL C++, которая загружает другую DLL во время одной из своих функций. Однако, когда я пытаюсь запустить его, он падает, когда я впервые объявляю свою переменную HMODULE, даже до того, как я пытаюсь вызвать LoadLibrary.

В частности, мой код:

HMODULE my_hmod;
my_hmod = LoadLibrary("C:\\path_to_dll");

он падает между этими двумя строками (я прошел через это и заметил, что он падает в «ostream», если это полезно).

Исключение составляет следующее:

Необработанное исключение по адресу 0x00a7392d (d3d9.dll) в PixelMotionBlur.exe: 0xC0000005: место чтения нарушения прав доступа 0x00000000.

Любая помощь будет оценена по достоинству! При необходимости я опубликую дополнительную информацию о коде/отладке.

EDIT: вот фактический код функции:

    D3D9Wrapper::IDirect3D9* WINAPI Direct3DCreate9(UINT Version)
{
    InitializeDLL();
    HMODULE hD3D;
    if(IsWow64())
    {
        hD3D = LoadLibrary("C:\\Windows\\SysWOW64\\d3d9.dll");
    }
    else
    {
        hD3D = LoadLibrary(g_Globals.RealD3D9DLL.CString());
    }

    if( hD3D == NULL )
    {
        g_Globals.ErrorFile() << "LoadLibrary on d3d9.dll failed\n";
        return NULL;
    }

    D3D9Wrapper::D3DCREATE pCreate = (D3D9Wrapper::D3DCREATE)GetProcAddress(hD3D, _T("Direct3DCreate9"));
    if( pCreate == NULL )
    {
        g_Globals.ErrorFile() << "coud not find Direct3DCreate9 in d3d9.dll\n";
        return NULL;
    }

    D3D9Base::LPDIRECT3D9 pD3D = pCreate(D3D_SDK_VERSION);
    if( pD3D == NULL )
    {
        return NULL;
    }

    //return (D3D9Wrapper::IDirect3D9*)pD3D;
    return D3D9Wrapper::IDirect3D9::GetDirect3D(pD3D);
}

В случае, если это поможет, функция этой DLL (большинство из них на самом деле не мой код, но используется с разрешения) состоит в том, чтобы перехватывать все вызовы d3d9.dll, помещая новую dll также с именем d3d9 в папку с целевым .exe (прямо сейчас Я тестирую его с образцами .exe из SDK Direct X 9).

РЕДАКТИРОВАТЬ 2: здесь полная разборка функции:

    D3D9Wrapper::IDirect3D9* WINAPI Direct3DCreate9(UINT Version)
{
008B6960  push        ebp  
008B6961  mov         ebp,esp  
008B6963  and         esp,0FFFFFFF8h  
008B6966  sub         esp,8  
    InitializeDLL();
008B6969  cmp         byte ptr [g_Globals (8CAC40h)],0  
008B6970  push        esi  
008B6971  push        edi  
008B6972  jne         Direct3DCreate9+48h (8B69A8h)  
008B6974  mov         edi,offset g_Globals (8CAC40h)  
008B6979  call        Globals::Init (8B6A80h)  
008B697E  mov         eax,dword ptr [g_Globals+34h (8CAC74h)]  
008B6983  push        8C0D98h  
008B6988  push        eax  
008B6989  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B698E  call        dword ptr [__imp_D3D9CallbackInitialize (8B81A4h)]  
008B6994  mov         ecx,dword ptr [g_Globals+34h (8CAC74h)]  
008B699A  push        8C0DB0h  
008B699F  push        ecx  
008B69A0  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B69A5  add         esp,10h  
    HMODULE hD3D;
    if(IsWow64())
008B69A8  push        8C0E60h  
008B69AD  push        8C0E70h  
008B69B2  mov         dword ptr [esp+14h],0  
008B69BA  call        dword ptr [__imp__GetModuleHandleA@4 (8B80D0h)]  
008B69C0  mov         edi,dword ptr [__imp__GetProcAddress@8 (8B80C4h)]  
008B69C6  push        eax  
008B69C7  call        edi  
008B69C9  mov         esi,eax  
008B69CB  test        esi,esi  
008B69CD  je          Direct3DCreate9+94h (8B69F4h)  
008B69CF  lea         edx,[esp+0Ch]  
008B69D3  push        edx  
008B69D4  call        dword ptr [__imp__GetCurrentProcess@0 (8B80B8h)]  
008B69DA  push        eax  
008B69DB  call        esi  
008B69DD  test        eax,eax  
008B69DF  jne         Direct3DCreate9+94h (8B69F4h)  
008B69E1  mov         eax,dword ptr [g_Globals+3Ch (8CAC7Ch)]  
008B69E6  push        8C0E7Ch  
008B69EB  push        eax  
008B69EC  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B69F1  add         esp,8  
008B69F4  cmp         dword ptr [esp+0Ch],0  
008B69F9  je          Direct3DCreate9+0A2h (8B6A02h)  
    {
        hD3D = LoadLibrary("C:\\Windows\\SysWOW64\\d3d9.dll");
008B69FB  push        8C0E98h  
    }
    else
008B6A00  jmp         Direct3DCreate9+0B1h (8B6A11h)  
    {
        hD3D = LoadLibrary(g_Globals.RealD3D9DLL.CString());
008B6A02  mov         eax,dword ptr [g_Globals+1Ch (8CAC5Ch)]  
008B6A07  test        eax,eax  
008B6A09  jne         Direct3DCreate9+0B0h (8B6A10h)  
008B6A0B  mov         eax,offset g_Globals+1Ch (8CAC5Ch)  
008B6A10  push        eax  
008B6A11  call        dword ptr [__imp__LoadLibraryA@4 (8B80CCh)]  
    }

    if( hD3D == NULL )
008B6A17  test        eax,eax  
008B6A19  jne         Direct3DCreate9+0D9h (8B6A39h)  
    {
        g_Globals.ErrorFile() << "LoadLibrary on d3d9.dll failed\n";
008B6A1B  mov         ecx,dword ptr [g_Globals+3Ch (8CAC7Ch)]  
008B6A21  push        8C0EB8h  
008B6A26  push        ecx  
008B6A27  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B6A2C  add         esp,8  
        return NULL;
008B6A2F  xor         eax,eax  
}
008B6A31  pop         edi  
008B6A32  pop         esi  
008B6A33  mov         esp,ebp  
008B6A35  pop         ebp  
008B6A36  ret         4  
    }
    D3D9Wrapper::D3DCREATE pCreate = (D3D9Wrapper::D3DCREATE)GetProcAddress(hD3D, _T("Direct3DCreate9"));
008B6A39  push        8C0ED8h  
008B6A3E  push        eax  
008B6A3F  call        edi  
    if( pCreate == NULL )
008B6A41  test        eax,eax  
008B6A43  jne         Direct3DCreate9+103h (8B6A63h)  
    {
        g_Globals.ErrorFile() << "coud not find Direct3DCreate9 in d3d9.dll\n";
008B6A45  mov         edx,dword ptr [g_Globals+3Ch (8CAC7Ch)]  
008B6A4B  push        8C0EE8h  
008B6A50  push        edx  
008B6A51  call        std::operator<<<std::char_traits<char> > (8938F0h)  
008B6A56  add         esp,8  
        return NULL;
008B6A59  xor         eax,eax  
}
008B6A5B  pop         edi  
008B6A5C  pop         esi  
008B6A5D  mov         esp,ebp  
008B6A5F  pop         ebp  
008B6A60  ret         4  
    }

EDIT 3: стек вызовов на момент возникновения исключения:

>   d3d9.dll!std::operator<<<std::char_traits<char> >(std::basic_ostream<char,std::char_traits<char> > & _Ostr, const char * _Val)  Line 773 + 0x3 bytes    C++
    d3d9.dll!InitializeDLL()  Line 70 + 0x15 bytes  C++
    d3d9.dll!Direct3DCreate9(unsigned int Version)  Line 141    C++
    PixelMotionBlur.exe!DXUT_Dynamic_Direct3DCreate9(unsigned int SDKVersion)  Line 714 + 0xc bytes C++
    PixelMotionBlur.exe!DXUTDelayLoadD3D9()  Line 2706 + 0xa bytes  C++
    PixelMotionBlur.exe!DXUTGetD3D9Object()  Line 712 + 0x23 bytes  C++
    PixelMotionBlur.exe!CD3D9Enumeration::Enumerate(bool (_D3DCAPS9 *, _D3DFORMAT, _D3DFORMAT, bool, void *)* IsD3D9DeviceAcceptableFunc, void * pIsD3D9DeviceAcceptableFuncUserContext)  Line 309 + 0x5 bytes  C++
    PixelMotionBlur.exe!DXUTGetD3D9Enumeration(bool bForceEnumerate)  Line 255  C++
    PixelMotionBlur.exe!DXUTFindValidDeviceSettings(DXUTDeviceSettings * pOut, DXUTDeviceSettings * pIn, DXUTMatchOptions * pMatchOptions)  Line 174    C++
    PixelMotionBlur.exe!DXUTCreateDevice(bool bWindowed, int nSuggestedWidth, int nSuggestedHeight)  Line 2010 + 0x17 bytes C++
    PixelMotionBlur.exe!wWinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, HINSTANCE__ * __formal, HINSTANCE__ * __formal)  Line 207  C++
    PixelMotionBlur.exe!__tmainCRTStartup()  Line 547 + 0x2c bytes  C
    PixelMotionBlur.exe!wWinMainCRTStartup()  Line 371  C
    kernel32.dll!75e1339a()     
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    ntdll.dll!77829ed2()    
    ntdll.dll!77829ea5()    

person zergylord    schedule 05.01.2012    source источник
comment
Он не падает там, где вы думаете, что он падает.   -  person Seth Carnegie    schedule 06.01.2012
comment
Это не авария. Вы компилируете с включенной оптимизацией? Если это так, отладчик лжет вам о том, где произошел сбой. Разместите больше кода, а также опубликуйте дизассемблирование по этому адресу.   -  person Adam Rosenfield    schedule 06.01.2012
comment
Делает ли другая dll что-нибудь в своей DllMain?   -  person Zac    schedule 06.01.2012
comment
Я использую компилятор VS 2010, в котором я совсем новичок - я думаю, что он не оптимизирован, так как я отключил оптимизацию всей программы в свойствах конфигурации проекта. Есть ли другое место, где VS прокрадывается в оптимизации компиляции?   -  person zergylord    schedule 06.01.2012
comment
@Zac другая dll (то есть та, которую я пытаюсь загрузить) определенно не вызывается, так как ошибка сохраняется даже без вызова loadlibrary :-/   -  person zergylord    schedule 06.01.2012
comment
Вы строите его с конфигурацией проекта Debug?   -  person Gerald    schedule 06.01.2012
comment
По-видимому, я использую конфигурацию Active (Release). Я так понимаю, вместо этого я должен использовать конфигурацию отладки?   -  person zergylord    schedule 06.01.2012
comment
Хорошо, декларация HMODULE официально не является проблемой; Я переместил его в ранее вызванную функцию dll, и он отлично работает, но вскоре после этого происходит сбой. Любые идеи относительно того, как я могу отладить это? :(   -  person zergylord    schedule 06.01.2012
comment
Объявление HMODULE на самом деле ничего не делает, поскольку ему ничего не присваивается. Как видно из дампа сборки, между ним и вызовом IsWin64 нет ассемблерного кода. Разместите стек вызовов, из которого произошло нарушение прав доступа.   -  person Gerald    schedule 06.01.2012
comment
Опубликован стек вызовов — вершина — это место, где произошло исключение   -  person zergylord    schedule 06.01.2012
comment
Ошибка в InitializeDLL. Смотрите мой ответ.   -  person Gerald    schedule 06.01.2012
comment
Вы создали свою собственную DLL с именем d3d9.dll с функцией InitializeDll()? Это не сработает.   -  person Hans Passant    schedule 06.01.2012


Ответы (2)


Судя по стеку вызовов, ошибка в функции InitializeDLL. Не могу точно сказать, не видя исходный код этой функции, но, поскольку это исключение указателя NULL через std::ostream, могу поспорить, что вы пытаетесь отправить строку NULL в std::cout или что-то в этом роде. .

Проверьте строку 70 исходного файла, в которой находится InitializeDLL. Если вы не видите проблемы, опубликуйте код из InintializeDLL.

person Gerald    schedule 06.01.2012
comment
Вы, сэр, действительно волшебны. Именно это и шло не так, и, несмотря на то, что я ошибся, тебе все же удалось это найти. Браво, и я извиняюсь перед всеми, что я не правильно локализовал свою проблему. - person zergylord; 06.01.2012
comment
Кроме того, должен ли я удалить этот вопрос, поскольку проблема вовсе не связана с HMODULE? - person zergylord; 06.01.2012
comment
Оставьте вопрос, так как путь к решению может оказаться полезным для кого-то еще. - person Gerald; 06.01.2012

Убедитесь, что вы запускаете и создаете отладочную версию своей программы. В VS2010 убедитесь, что у вас выбрана конфигурация сборки «Отладка», а в меню отладчика убедитесь, что вы прерываете выброс любых исключений C++.

Вы правы - я могу сделать следующее просто отлично.

HMODULE hD3D = LoadLibrary(L"C:\\Windows\\SysWOW64\\d3d9.dll");
person Zac    schedule 05.01.2012
comment
Я только что попытался изменить конфигурацию на отладку, и проблема не устранена. Имеют ли значение различные имена конфигураций помимо пресетов свойств конфигурации, с которыми они связаны? - person zergylord; 06.01.2012
comment
Также я пробовал ставить HMODULE hD3D = LoadLibrary(LC:\\Windows\\SysWOW64\\d3d9.dll); в другой части моей dll, и она загружается нормально, а затем вылетает в том же месте, несмотря ни на что :( - person zergylord; 06.01.2012
comment
конечно, свойства являются важными элементами, надеюсь, в конфигурации отладки должна быть отключена вся оптимизация и включены проверки отладки. Что такое стек вызовов, когда он падает? - person Zac; 06.01.2012
comment
Тот факт, что он падает в ostream, является важной подсказкой. - person Zac; 06.01.2012