我将WinDbg附加到本地应用程序的调试版本上并运行我的场景。在反序列化期间,WinDbg发现如下:
"警告:无法从档案中加载。未定义类。CArchive异常:badClass."
我认为这里存在一些资源问题,因此我运行本地应用程序的发布版本,加载MFCXDLL_2的发布版本。然后,我将.NET用户控件的调试版本(再次加载MFCXDLL_2的调试版本)加载到本地应用程序中。
然后一切都很顺利。本地代码加载了一个MFCXDLL_2的发布版本,.NET用户控件加载了一个MFCXDLL_2的调试版本,所有这些都在本地应用程序内部运行。
那么到底发生了什么?是否不可能同时从扩展DLL和常规DLL访问同一个MFCXDLL?
资源链是否以某种方式被破坏?
有哪些可能的解决方案?
以下是显示如何加载MFCXDLL_2 DLL的一些代码
当本地应用程序启动时,将调用MFCXDLL_2 DLLMain:
static AFX_EXTENSION_MODULE MFCXDLL_2 = { NULL, NULL };
static CDynLinkLibrary* gpDynLinkLibrary = NULL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID )
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization
AfxInitExtensionModule(MFCXDLL_2, hInstance);
// Insert this DLL into the resource chain
gpDynLinkLibrary = new CDynLinkLibrary(MFCXDLL_2);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
if (gpDynLinkLibrary)
{
delete gpDynLinkLibrary;
gpDynLinkLibrary = NULL;
}
// Terminate the library before destructors are called
AfxTermExtensionModule(MFCXDLL_2);
}
return 1; // ok
}
当.NET用户控件被加载时,MFCXDLL_2 DLL会再次被加载:
//==============================================================
// Exported DLL initialization to run in context of Regular DLL.
// Must be called in InitInstance
// BOOL CYourRegularDLLApp::InitInstance()
//==============================================================
extern "C" _declspec(dllexport) CDynLinkLibrary* WINAPI InitMFCXDLL_2FromRegularDLL()
{
if (gpDynLinkLibrary)
{
delete gpDynLinkLibrary;
gpDynLinkLibrary = NULL;
}
// Create a new CDynLinkLibrary for this Regular DLL
return new CDynLinkLibrary(MFCXDLL_2);
}
MFCXDLL_2中的反序列化代码
CMyClass* pMyclass = NULL; //CObject derived serializeable class
BYTE *pBuf = pGlobalCom->GetBuffer(); //Buffer with serialized CMyClass
int nBufSize = pGlobalCom->GetSize(); //Size of buffer
CMemFile mf;
mf.Attach(pBuf,nBufSize);
CArchive ar(&mf, CArchive::load); //“Warning: Cannot load CMyClass from archive. Class not defined.CArchive exception: badClass.”
ar >> pMyclass; //CArchive exception thrown
ar.Close();
mf.Detach();
此图展示了dll之间的关系。