Во время массивного обновления кода из состава VC6, VS2003 и VS2005 я столкнулся с проблемой, когда VS2010 не ведет себя как VS2003 сделал. Приложение сканирует каталог DLL и пытается загрузить их по одному. Это делается здесь: шоуИмпорт DLL не работает (VS2003 - VS2010, многопотоковая многопоточная DLL)
CConfigPlugin::CConfigPlugin(LPCTSTR szPluginName)
{
ASSERT(szPluginName);
ASSERT(AfxIsValidString(szPluginName));
m_csFullpath = szPluginName;
m_hModule = LoadLibrary(m_csFullpath);
m_pInterface = (IConfigDllInterface *) NULL;
pInterface pPtr = pInterface(NULL);
if (m_hModule != NULL)
{
// If we loaded the DLL get the interface pointer
pPtr = pInterface(GetProcAddress(m_hModule, "GetInterface"));
}
if (pPtr != NULL)
{
pPtr(&m_pInterface);
}
else
{
::FreeLibrary(m_hModule);
m_hModule = HMODULE(NULL);
}
}
Все DLL, как загружаются: ... 'GenConfig.exe': Loaded 'C: \ SRC \ Debug \ Config \ GenLogonConfig.dll', Символы загружены. 'GenConfig.exe': загружен 'C: \ src \ Debug \ config \ GenReportConfig.dll', загружены символы. 'GenConfig.exe': загружен 'C: \ src \ Debug \ config \ ImportConfig.dll', загружены символы. ...
Каждая DLL имеет идентичную реализация GetInterface показана ниже:
CConfigDllInterfaceImpl<CParentDlg> gdllObj;
BOOL GetInterface(IConfigDllInterface **ppPtr)
{
*ppPtr = &gdllObj;
// Temporary edit to test if gdllObj is set to proper parent.
CString name;
name = gdllObj.GetDisplayName();
// End edit
return true;
}
С шаблоном, как показано ниже:
__declspec(selectany) UINT guiAdvise;
template <class T> class CConfigDllInterfaceImpl : public IConfigDllInterface
{
public:
CConfigDllInterfaceImpl()
{
guiAdvise = RegisterWindowMessage(_T("GenConfig"));
m_pDlg = NULL;
}
virtual LPCTSTR GetDisplayName() const
{
static CString csTemp;
csTemp.LoadString(IDS_DISPLAY_NAME);
return csTemp;
}
// Can't be virtual because it uses the template T argument
BOOL DoModal(HWND hParent)
{
ASSERT(IsWindow(hParent));
if (m_pDlg == (T *) NULL)
{
m_pDlg = new T(CWnd::FromHandle(hParent));
return m_pDlg->Create();
}
else if (IsWindow(m_pDlg->GetSafeHwnd()))
{
m_pDlg->PostMessage(guiAdvise, eAdviseSwitchViews);
m_pDlg->SetActiveWindow();
}
return TRUE;
} // SNIP...
Я могу сказать, что мой шаблон не правильно регистрации его предполагаемому родителю. GetDisplayName возвращает "". Мое подозрение, причина моей проблемы в том, что я принял решение месяц назад, чтобы изменить все на Multithreaded DLL из Multithreaded. Это все проекты MFC, и казалось, что самый простой и простой способ просто использовать _AFXDLL и сделать все правильно компилируемым и связанным. Все остальные мои проекты работают нормально, но я считаю, что из-за загрузки этой DLL:
CConfigDllInterfaceImpl gdllObj;
Больше не работает так, как раньше.
Итак, вопрос 1: Является ли мое подозрение правильным? Или я полностью вне базы? Вопрос 2: Если мое подозрение правильное, как мне обойти это? На данный момент это не вариант возврата к многопоточности.
Заранее спасибо.
Вы перестроили все свои DLL-файлы с помощью VS2010? –
Да. Все части того же решения. – milenko121175
Убедитесь, что ваши ресурсы не были потеряны в обновлении. –