关于这两种DLL的一些使用上的区别,
Regular DLLs:有一个CWinApp的派生类,但没有消息循环(DllMain函数被MFC所提供,不用自己显式的写出来),可以在DLL内部使用MFC,与应用程序的接口不能使用MFC,有静态链接和动态链接两种创建方式,各种编程语言都可以调用……Extension DLLs:有一个DLLMain函数,在DLL内部和与应用程序的接口中都能使用MFC,并可以导出MFC派生类,采用MFC的动态链接版本创建,只能供MFC程序使用……--------------------------------------------------------------------------------------------------
老大的意思是让我探索一下这两种DLL的本质区别,为什么它们会造成上面这些结果,可以从源代码分析。额是新手,源代码分析几乎没有做过。我也不知道怎么去找DLL这些内部的源代码,怎么去分析?各位大侠,帮帮忙指点指点,谢谢!!!
Regular DLLs:有一个CWinApp的派生类,但没有消息循环(DllMain函数被MFC所提供,不用自己显式的写出来),可以在DLL内部使用MFC,与应用程序的接口不能使用MFC,有静态链接和动态链接两种创建方式,各种编程语言都可以调用……Extension DLLs:有一个DLLMain函数,在DLL内部和与应用程序的接口中都能使用MFC,并可以导出MFC派生类,采用MFC的动态链接版本创建,只能供MFC程序使用……--------------------------------------------------------------------------------------------------
老大的意思是让我探索一下这两种DLL的本质区别,为什么它们会造成上面这些结果,可以从源代码分析。额是新手,源代码分析几乎没有做过。我也不知道怎么去找DLL这些内部的源代码,怎么去分析?各位大侠,帮帮忙指点指点,谢谢!!!
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("EXTENSIONDLL.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(ExtensionDLLDLL, hInstance))
return 0; // Insert this DLL into the resource chain
// NOTE: If this Extension DLL is being implicitly linked to by
// an MFC Regular DLL (such as an ActiveX Control)
// instead of an MFC application, then you will want to
// remove this line from DllMain and put it in a separate
// function exported from this Extension DLL. The Regular DLL
// that uses this Extension DLL should then explicitly call that
// function to initialize this Extension DLL. Otherwise,
// the CDynLinkLibrary object will not be attached to the
// Regular DLL's resource chain, and serious problems will
// result. new CDynLinkLibrary(ExtensionDLLDLL);
}初始化期间所创建的 CDynLinkLibrary 对象使MFC扩展 DLL 可以将 DLL中的CRuntimeClass 对象或资源导出到应用程序;为什么这样就可以导出CRuntimeClass(我可以理解成MFC类吧)?
但是水平有限,看这些代码,也看不出个所以然来。希望有高手指点一二。
{
// only initialize once
if (state.bInitialized)
{
AfxInitLocalData(hModule);
return TRUE;
}
state.bInitialized = TRUE; // save the current HMODULE information for resource loading
ASSERT(hModule != NULL);
state.hModule = hModule;
state.hResource = hModule; // save the start of the runtime class list
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
state.pFirstSharedClass = pModuleState->m_classList.GetHead();
pModuleState->m_classList.m_pHead = pModuleState->m_pClassInit;#ifndef _AFX_NO_OLE_SUPPORT
// save the start of the class factory list
state.pFirstSharedFactory = pModuleState->m_factoryList.GetHead();
pModuleState->m_factoryList.m_pHead = pModuleState->m_pFactoryInit;
#endif return TRUE;
}有文章对以上初始化代码:AfxInitExtensionModule函数主要作以下事情:
(1)把扩展DLL模块的模块句柄hModule、资源句柄hModule分别保存到参数state的成员变量hModule、hResource中;(2)把当前模块状态的m_classList列表的头保存到state的成员变量pFirstSharedClass中,m_classInit的头设置为模块状态的m_pClassInit。在扩展DLL模块进入DllMain之前,如果该扩展模块构造了静态AFX_CLASSINIT对象,则在初始化时把有关CRuntimeClass信息保存在当前模块状态(注意不是扩展DLL模块,而是应用程序模块)的m_classList列表中。因此,扩展DLL模块初始化的CRuntimeClass信息从模块状态的m_classList中转存到扩展模块状态state的pFirstSharedClass中,模块状态的m_classInit恢复被该DLL改变前的状态。关于CRuntimeclass信息和AFX_CLASSINIT对象的构造。一个扩展DLL在初始化时,如果需要输出它的CRuntimeClass对象,就可以使用相应的CRuntimeClass对象定义一个静态的AFX_CLASSINIT对象,而不一定要使用IMPLEMENT_SERIAL宏。当然,可以序列化的类必定导致可以输出的CRuntimeClass对象。(3)若支持OLE的话,把当前模块状态的m_factoryList的头保存到state的成员变量pFirstSharedFactory中。m_factoryList的头设置为模块状态的m_m_pFactoryInit。(4)这样,经过初始化之后,扩展DLL模块包含了扩展DLL的模块句柄、资源句柄、本模块初始化的CRuntimeClass类等等。对于(2)中“因此,扩展DLL模块初始化的CRuntimeClass信息从模块状态的m_classList中转存到扩展模块状态state的pFirstSharedClass中,模块状态的m_classInit恢复被该DLL改变前的状态。”,我是不理解是怎么因此出来的?如果说前半句是把一个头赋给另一个头(原来的头没有变啊)还可以理解,为什么后面又说恢复被该DLL改变前的状态。
pModuleState->m_classList.m_pHead = pModuleState->m_pClassInit;我查看了一些源代码(在类似DllMain的函数里),发现是这样的赋值:
pModuleState->m_pClassInit = pModuleState->m_classList.GetHead(); 或者
pModuleState->m_pClassInit = pModuleState->m_classList;
(这里有另外一个疑问,后面的返回的是CTypedSimpleList<CRuntimeClass*>,而前面是一个CRuntimeClass*,也可以赋值?)而GetHead(CSimpleList成员函数,CTypedSimpleList派生自CSimpleList)返回的正是m_pHead指针,所以我的理解是pModuleState->m_pClassInit指向的就是那个m_classList的头,这个头没有改变啊,却又给它赋一次值,说是恢复。我自己也都晕了。从现在看的情况,也只能做出这么多猜测了。