В приложении MFC, если я вызываю «LoadLibraryA» из «InitInstance», он снова и снова вызывает «InitInstance» - PullRequest
3 голосов
/ 06 января 2011

Я создал MFCApp с помощью мастера VS2008.Внутри моего приложения "InitInstance ()" я вызываю метод LoadLibraryA (), так как мне нужно загрузить несколько DLL-файлов.Но как только я вызываю «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"

Все, что я могу понять, это то, что я вызываю LoadLibrary до того, как процедура InitInstance закончилась.Есть ли другой (переопределенный) метод, который вызывается после InitInstance ???Если это так, я могу попробовать перенести вызовы LoadLibrary на этот метод ...

Ответы [ 3 ]

1 голос
/ 13 января 2011

Да, вы делаете что-то не так. Вы находитесь в DllMain mfc90.dll, и вызывать LoadLibrary из DllMain небезопасно, прямо здесь сказано:

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

1 голос
/ 06 января 2011

Это скорее обходной путь, чем истинное решение (т.е. я не знаю правил для LoadLibrary в MFC, поскольку я никогда не читал ничего такого, чтобы сказать, что вы не можете, и я не использую этот метод наш код MFC).

Однако, вообще говоря, если Windows кашляет из-за порядка операций, я просто перемещаю вызовы в другой обработчик сообщений. Вы даже можете опубликовать ветку сообщения в своем приложении и написать обработчик для этого сообщения.

Что-то вроде:

// 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

0 голосов
/ 18 ноября 2013

У меня только что были те же issue, caused by, Configuration type неправильно установлены на exe, а не dll для загрузки dll.

Исправлено: Project -> Configuration Properties -> General -> Configuration Type = Dynamic Library (.dll) (было неправильно установлено приложение (.exe))

...