MFC的模块状态:从AfxGetApp()和AFX_MANAGE_STATE()看MFC的模块状态

1.      Introduction

当我们在用MFC编程的时候,我们经常用到AfxGetApp()来获得当前的CWinAppInstance。看看MFC的源代码中AfxGetApp()的实现,你会发现AfxGetApp()的实现并不像一般情况下面那样直接:

_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()

       { return afxCurrentWinApp; }

#define afxCurrentWinApp    AfxGetModuleState()->m_pCurrentWinApp

AfxGetApp()调用的是AfxGetModuleState(),该函数返回一个AFX_MODULE_STATE的指针,其中的一个成员保存着当前的CWinApp的指针。可AfxGetModuleState()的作用又是什么呢?

 

此外,当我们在开发MFC DLL程序的时候,我们会在每个输出的DLL函数前面加上一句AFX_MANAGE_STATE

void SomeMFCDllFunction()

{

AFX_MANAGE_STATE(AfxGetStaticModuleState())

 

AFX_MANAGE_STATE又是起什么作用呢?从字面上看来,它是Manage某种State,而AfxGetStaticModuleState又是获得State的,那么State究竟是什么呢?

MFC中,States用来保存某种相关的状态信息,分为下面几类:

1.     Process State,和某个单独的进程绑定起来

2.     Thread State,和某个单独的线程绑定

3.     Module State,和Module相关

前两种State和一般的全局变量十分类似,只是根据需求的不同被绑定于不同的进程/线程,如多线程支持等。而Module State本身比较特别,Module State根据情况的不同,可以是全局,线程,或者进程相关的State,并且可以根据要求快速切换。

2.      Process State

常见的Process State有:

1.     _AFX_WIN_STATE

2.     _AFX_DB_STATE

3.     _AFX_DEBUG_STATE

4.     _AFX_SOCK_STATE

5.     ……

从字面上面可以很容易猜出这些状态的用处。

MFC通过下面的宏来定义Process State:

#define PROCESS_LOCAL(class_name, ident_name) /

       AFX_COMDAT CProcessLocal<class_name> ident_name;

#define EXTERN_PROCESS_LOCAL(class_name, ident_name) /

       extern CProcessLocal<class_name> ident_name;

PROCESS_LOCALCProcessLocal模板类定义了一个CProcessLocal<class_name>的一个实例作为状态变量,而EXTERN_PROCESS_LOCAL则使在头文件中声明此状态变量。CProcessLocal的定义如下:

class AFX_NOVTABLE CProcessLocalObject

{

public:

// Attributes

       CNoTrackObject* GetData(CNoTrackObject* (AFXAPI* pfnCreateObject)());

 

// Implementation

       CNoTrackObject* volatile m_pObject;

       ~CProcessLocalObject();

};

 

template<class TYPE>

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; }

};

 

CProcessLocal的作用只是一个WrapperHold一个TYPE*的指针,一旦用户调用GetData来获得这个指针,GetData会首先判断该指针是否为空,如果为空,则创建一个新的实例保存起来,否则返回已有的指针。前提条件是,TYPE必须从CNoTrackObject继承。任何从CNoTrackObject继承的类都拥有自己的new/delete,这样此对象便不会被Debug的内存分配系统所跟踪而误判

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值