3

VS2008 ウィザードを使用して MFCApp を作成しました。アプリケーションの「InitInstance()」内で、いくつかの dll ファイルをロードする必要があるため、「LoadLibraryA()」メソッドを呼び出しています。しかし、「LoadLibraryA()」を呼び出すとすぐに、アプリケーションの「InitInstance()」が再び呼び出されるため、無限再帰になります。私が間違っていることはありますか?

// CLoader_MFCApp initialization
BOOL CLoader_MFCApp::InitInstance()
{
  INITCOMMONCONTROLSEX InitCtrls;
  InitCtrls.dwSize = sizeof(InitCtrls);
  InitCtrls.dwICC = ICC_WIN95_CLASSES;
  InitCommonControlsEx(&InitCtrls);
  CWinAppEx::InitInstance();
  SetRegistryKey(_T("MyApp"));

  HMODULE hm = LoadLibraryA("./abc/def.dll");
  // after above line InitInstance() gets called again

  // more code
  return FALSE;
}

コール スタック:

MyApp.exe!CLoader_MFCApp::InitInstance()    C++
CORE.dll!InternalDllMain(HINSTANCE__ *, unsigned long, void *)  C++
CORE.dll!__DllMainCRTStartup(void *, unsigned long, void *)     C
CORE.dll!_DllMainCRTStartup(void *, unsigned long, void *)  C
ntdll.dll!_LdrpCallInitRoutine@16()     
ntdll.dll!_LdrpRunInitializeRoutines@4()    
ntdll.dll!_LdrpLoadDll@24()     
ntdll.dll!_LdrLoadDll@16()  
kernel32.dll!_LoadLibraryExW@12()   
kernel32.dll!_LoadLibraryExA@12()   
kernel32.dll!_LoadLibraryA@4()  
MyApp.exe!CLoader_MFCApp::InitInstance()    C++
mfc90.dll!AfxWinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int)     C++
MyApp.exe!__tmainCRTStartup()   C
kernel32.dll!_BaseProcessStart@4()  

「Def.dll」はその他の dll であり、MyApp とはまったく関係ありません。この場合、別の dll "CORE.dll" をロードしようとしています。

私が理解できるのは、InitInstance ルーチンが終了する前に LoadLibrary を呼び出しているということだけです。InitInstance の後に呼び出される他の (オーバーライド可能な) メソッドはありますか? もしそうなら、LoadLibrary 呼び出しをそのメソッドに移動してみることができます...

4

3 に答える 3

1

はい、あなたは何か間違ったことをしています。あなたは mfc90.dll の DllMain にいて、DllMain から LoadLibrary を呼び出すのは安全ではありません。

http://msdn.microsoft.com/en-us/library/ms684175%28v=vs.85%29.aspx

于 2011-01-13T06:19:35.907 に答える
1

これは真の解決策というよりも回避策です (つまり、MFC の LoadLibrary のルールを知りません。使用できないと言っているものを読んだことがなく、MFC コードでこの手法を使用したこともありません)。 )。

ただし、一般的に言えば、操作の順序が原因でウィンドウが毛玉を吐き出す場合は、呼び出しを別のメッセージ ハンドラーに移動するだけです。スレッド メッセージをアプリケーションに投稿し、そのメッセージのハンドラーを作成することもできます。

何かのようなもの:

// in InitInstance - post a message to our main thread to handle after init instance...
PostMessage(NULL, WM_PostInit);

// in your message table
ON_THREAD_MESSAGE(WM_PostInit, OnPostInit)

// in your app
void MyApp::OnPostInit(WPARAM,LPARAM) // both args unused
{
  // try load library now...!
}

注: 上記は「脳のコード」です - テストされていません。完全にコンパイル可能にするためには、間違いなく詳細をマッサージする必要があります。

参考文献: http://msdn.microsoft.com/en-us/library/ms644944%28v=VS.85%29.aspx

于 2011-01-06T15:12:36.943 に答える
0

がロードされないようissueに誤って設定されてcaused byいます。Configuration typeexedlldll

修正: Project -> Configuration Properties -> General -> Configuration Type = Dynamic Library (.dll)(誤ってアプリケーション (.exe) に設定されていました)

于 2013-11-18T12:02:36.687 に答える