现在的位置: 首页 > 综合 > 正文

AFX_MANAGE_STATE(AfxGetStaticModuleState())的一次旅行~

2014年02月19日 ⁄ 综合 ⁄ 共 10200字 ⁄ 字号 评论关闭

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这两个就不去挖了,挖也不一定挖的到,到此结束。。

抱歉!评论已关闭.