AFX_MANAGE_STATE(AfxGetStaticModuleState());
宏定义如下
#define AFX_MANAGE_STATE_NO_INIT_MANAGED(p) AFX_MAINTAIN_STATE2 _ctlState(p);
#defineAFX_MANAGE_STATE(p)_AfxInitManaged();AFX_MANAGE_STATE_NO_INIT_MANAGED(p)
等同于VC6的这一句~
#define AFX_MANAGE_STATE(p) AFX_MAINTAIN_STATE2 _ctlState(p);
__declspec( noinline ) inline int __cdecl _AfxInitManaged()//打酱油的
{
return 0;
}
AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2(AFX_MODULE_STATE* pNewState)
{
m_pThreadState = _afxThreadState;
m_pPrevModuleState = m_pThreadState->m_pModuleState;
m_pThreadState->m_pModuleState = pNewState;
}//设置新的模块值
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState()
{
AFX_MODULE_STATE* pModuleState = &afxModuleState;
return pModuleState;
}//返回&afxModuleState
static _AFX_DLL_MODULE_STATE afxModuleState;
afxModuleState这家伙貌似只在dll里面发挥作用,这边我不管它了。
下面这个结构非常重要。。
class AFX_MODULE_STATE : public CNoTrackObject
{
public:
CWinApp* m_pCurrentWinApp;
HINSTANCE m_hCurrentInstanceHandle;
HINSTANCE m_hCurrentResourceHandle;
LPCTSTR m_lpszCurrentAppName;
BYTE m_bDLL; // TRUE if module is a DLL, FALSE if it is an EXE
BYTE m_bSystem; // TRUE if module is a "system" module, FALSE if not
BYTE m_bReserved[2]; // padding
DWORD m_fRegisteredClasses; // flags for registered window classes
………………………..
………………………..
// define thread local portions of module state
CThreadLocal<AFX_MODULE_THREAD_STATE> m_thread;
//就是这边,它和线程相关啦~~~
};
看下CThreadLocal的代码
class CThreadLocal : public CThreadLocalObject
{
// Attributes
public:
AFX_INLINE TYPE* GetData()//我就选这个函数进去看看
{
TYPE* pData = (TYPE*)CThreadLocalObject::GetData(&CreateObject);
ENSURE(pData != NULL);
return pData;
}
AFX_INLINE TYPE* GetDataNA()
{
TYPE* pData = (TYPE*)CThreadLocalObject::GetDataNA();
return pData;
}
AFX_INLINE operator TYPE*()
{
return GetData();
}
AFX_INLINE TYPE* operator->()
{
return GetData();
}
// Implementation
public:
static CNoTrackObject* AFXAPI CreateObject()
{ return new TYPE; }
};
CNoTrackObject* CThreadLocalObject::GetData(
CNoTrackObject* (AFXAPI* pfnCreateObject)())
{
ENSURE(pfnCreateObject);
if (m_nSlot == 0)
{
if (_afxThreadData == NULL)
{
_afxThreadData = new(__afxThreadData) CThreadSlotData;
ENSURE(_afxThreadData != NULL);
}
m_nSlot = _afxThreadData->AllocSlot();//分配个索引,不贴代码了
ENSURE(m_nSlot != 0);
}
CNoTrackObject*pValue=static_cast<CNoTrackObject*>(_afxThreadData->GetThreadValue(m_nSlot)); //代码在下面
if (pValue == NULL)
{
// allocate zero-init object
pValue = (*pfnCreateObject)();
// set tls data to newly created object
_afxThreadData->SetValue(m_nSlot, pValue);//这里不进去了,很简单的
ASSERT(_afxThreadData->GetThreadValue(m_nSlot) == pValue);
}
return pValue;
}
下面看这个类CThreadSlotData
class CThreadSlotData
{
public:
CThreadSlotData();
// Operations
int AllocSlot();
void FreeSlot(int nSlot);
void SetValue(int nSlot, void* pValue);
// delete all values in process/thread
void DeleteValues(HINSTANCE hInst, BOOL bAll = FALSE);
// assign instance handle to just constructed slots
void AssignInstance(HINSTANCE hInst);
// Implementation
DWORD m_tlsIndex; // used to access system thread-local storage
int m_nAlloc; // number of slots allocated (in UINTs)
int m_nRover; // (optimization) for quick finding of free slots
int m_nMax; // size of slot table below (in bits)
CSlotData* m_pSlotData; // state of each slot (allocated or not)
CTypedSimpleList<CThreadData*> m_list; // list of CThreadData structures
CRITICAL_SECTION m_sect;
void* GetThreadValue(int nSlot); // special version for threads only!
//进去看看
void* PASCAL operator new(size_t, void* p)
{ return p; }
void DeleteValues(CThreadData* pData, HINSTANCE hInst);
~CThreadSlotData();
};
inline void* CThreadSlotData::GetThreadValue(int nSlot)
{
…………………..
CThreadData* pData = (CThreadData*)TlsGetValue(m_tlsIndex);//从tls里面找指针
…………………..
void* pRetVal = pData->pData[nSlot];//不解释了,结构在下面
…………………..
return pRetVal;
}
struct CThreadData
{ CThreadData* pNext;
int nCount;
void *pData;
}
从上面可以得出AFX_MODULE_STATE是线程相关的,因为它和每个线程独有的tls紧密相连。
下面要开始乱跑了,往回跑,跑到AfxGetModuleState吧,堆栈如下:
AFX_MODULE_STATE* AFXAPI AfxGetModuleState()
{
_AFX_THREAD_STATE* pState = _afxThreadState;
ENSURE(pState);
AFX_MODULE_STATE* pResult;
if (pState->m_pModuleState != NULL)
{
// thread state's module state serves as override
pResult = pState->m_pModuleState;
}
else
{
// otherwise, use global app state
pResult = _afxBaseModuleState.GetData();
}
ENSURE(pResult != NULL);
return pResult;
}
EXTERN_THREAD_LOCAL(_AFX_THREAD_STATE, _afxThreadState)
#define EXTERN_THREAD_LOCAL(class_name, ident_name) \
extern CThreadLocal<class_name> ident_name;上面的宏定义可以看出_afxThreadState是个CThreadLocal<_AFX_THREAD_STATE >的对象
class _AFX_THREAD_STATE : public CNoTrackObject
{
public:
_AFX_THREAD_STATE();
virtual ~_AFX_THREAD_STATE();
// override for m_pModuleState in _AFX_APP_STATE
AFX_MODULE_STATE* m_pModuleState;//主要是这家伙,和线程相关呐。。
AFX_MODULE_STATE* m_pPrevModuleState;
……………………………..
};
_afxBaseModuleState是这样的CProcessLocal<_AFX_BASE_MODULE_STATE>
进程相关的家伙~
_AFX_BASE_MODULE_STATE实际上就是AFX_MODULE_STATE结构,跟不出定义,可能是导出的。
class CProcessLocal : public CProcessLocalObject //定义和线程的很像
{
// Attributes
public:
AFX_INLINE TYPE* GetData()//看看它怎么实现的
{
TYPE* pData = (TYPE*)CProcessLocalObject::GetData(&CreateObject);
ENSURE(pData != NULL);
return pData;
}
AFX_INLINE TYPE* GetDataNA()
{ return (TYPE*)m_pObject; }
AFX_INLINE operator TYPE*()
{ return GetData(); }
AFX_INLINE TYPE* operator->()
{ return GetData(); }
// Implementation
public:
static CNoTrackObject* AFXAPI CreateObject()
{ return new TYPE; }
};
CNoTrackObject* CProcessLocalObject::GetData(
CNoTrackObject* (AFXAPI* pfnCreateObject)())
{
……
m_pObject = (*pfnCreateObject)();
……..
return m_pObject;
}
下面去看下mfc的dll载入过程是神马情况~~
if (dwReason == DLL_PROCESS_ATTACH)
{
#ifdef _AFX_OLE_IMPL
BOOL bRegister = !coreDLL.bInitialized;
// shared initialization
AFX_MODULE_STATE* pModuleState = _AfxGetOleModuleState();
pModuleState->m_hCurrentInstanceHandle = hInstance;
pModuleState->m_hCurrentResourceHandle = hInstance;
pModuleState->m_pClassInit = pModuleState->m_classList.GetHead();
pModuleState->m_pFactoryInit = pModuleState->m_factoryList.GetHead();
#endif
// initialize this DLL's extension module
VERIFY(AfxInitExtensionModule(coreDLL, hInstance));
#ifdef _AFX_OLE_IMPL
AfxWinInit(hInstance, NULL, _T(""), 0);
………………….后面的不看了,累死了~
}
AFX_MODULE_STATE* AFXAPI _AfxGetOleModuleState()
{
return &_afxOleModuleState;
}
afxOleModuleState这东西也是AFX_MODULE_STATE结构
BOOL AFXAPI AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance,
__in LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);
// handle critical errors and avoid Windows message boxes
SetErrorMode(SetErrorMode(0) |
SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
// set resource handles
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_hCurrentInstanceHandle = hInstance;//初始化的两个句柄
pModuleState->m_hCurrentResourceHandle = hInstance;
pModuleState->CreateActivationContext();
// fill in the initial state for the application
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
{
// Windows specific initialization (not done if no CWinApp)
pApp->m_hInstance = hInstance;
hPrevInstance; // Obsolete.
pApp->m_lpCmdLine = lpCmdLine;
pApp->m_nCmdShow = nCmdShow;
pApp->SetCurrentHandles();
}
// initialize thread specific data (for main thread)
if (!afxContextIsDLL)
AfxInitThread();
// Initialize CWnd::m_pfnNotifyWinEvent
HMODULE hModule = ::GetModuleHandle(_T("user32.dll"));
if (hModule != NULL)
{
CWnd::m_pfnNotifyWinEvent = (CWnd::PFNNOTIFYWINEVENT)::GetProcAddress(hModule, "NotifyWinEvent");
}
//这边很有意思,user32里面提供了一个事件函数,莫非这是事件机制的接收点?~
return TRUE;
}
void AFX_MODULE_STATE::CreateActivationContext()
{
_AfxInitContextAPI();//初始化了kernel里面的一些函数,不贴了
HMODULE hModule = m_hCurrentInstanceHandle;
WCHAR rgchFullModulePath[MAX_PATH + 2];
rgchFullModulePath[_countof(rgchFullModulePath) - 1] = 0;
rgchFullModulePath[_countof(rgchFullModulePath) - 2] = 0;
DWORD dw=GetModuleFileNameW(hModule,rgchFullModulePath, _countof(rgchFullModulePath)-1);
if (dw == 0)
{
return;
}
if (rgchFullModulePath[_countof(rgchFullModulePath) - 2] != 0)
{
SetLastError(ERROR_BUFFER_OVERFLOW);
return;
}
//First try ID 2 and then ID 1 - this is to consider also a.dll.manifest file
//for dlls, which ID 2 ignores.
ACTCTXW actCtx;
…..actCtx的赋值,不管了~
}
本来到这边应该结束了,but其实__DllMainCRTStartup里面是这样
if ( dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH ) {
if ( _pRawDllMain )
retcode = (*_pRawDllMain)(hDllHandle, dwReason, lpreserved);
if ( retcode )
retcode = _CRT_INIT(hDllHandle, dwReason, lpreserved);
if ( !retcode )
__leave;
}
retcode = DllMain(hDllHandle, dwReason, lpreserved);//dllmain在后面才执行
pRawDllMain,以及_CRT_INIT这两个就不去挖了,挖也不一定挖的到,到此结束。。