Drill down into MFC extension DLLs

Source: Internet
Author: User
1 Problems of the derivation When you create a DLL that uses MFC, the VS Wizard automatically adds a class that inherits from CWinApp and overloads the InitInstance and ExitInstance two functions. In front of this file there is a note:////todo: If this DLL is dynamically linked relative to the MFC DLL,//       any transfer into//  from this DLL       MFC functions must add afx_manage_state macros to the front of the function//      .        For example:////       extern "C" BOOL PASCAL EXPORT Exportedfunction ()//       {//             afx_manage_state (AfxGetStaticModuleState ());            //Here is the common function body//       }////       This macro is important to appear in each function before any MFC call//      . This means that//       it must appear as the first statement in the function//      , even before all object variable declarations,        this is because their constructors may generate MFC//       DLL invocation. So, Afx_manage_state (AfxGetStaticModuleState ()), what is important in every function is why it appears. 2             Problem Research We know that in the MFC code, if you want to access some of the modules of resources or information, usually using the Afxgetmodulestate function to get the module information pointer, then how MFC know what the user extensions of the DLL in which resources. Look at the implementation of Afxgetmodulestate: Process_local (_afx_base_module_state, _afxbasemodulestate) afx_module_state* Afxgetmodulestate () {     _afx_thread_state* pstate = _afxthreadstate;      Afx_module_state* PResult;      if (pstate->m_pmodulestate!= NULL)      {         //thread state ' s module state serves as override        & nbsp PResult = pstate->m_pmodulestate;     }      Else      {         //Otherwise, use Global app state          PResult = _ Afxbasemodulestate.getdata ();     }      ASSERT (PResult!= NULL);      return pResult; You can see from here, if we do not modify the m_pmodulestate pointer in _afx_thread_state, it will point to the _afxbasemodulestate global variable in the MFC DLL. However, when MFC runs, it sometimes has to access resources in the MFC DLL, so we can only modify this pointer each time we want to use this module resource, and then restore the pointer after it is finished. This is the work that afx_manage_state this macro completes. and see what AfxGetStaticModuleState () did. Lresult CALLBACK afxwndprocdllstatic (HWND, UINT, WPARAM, LPARAM); Class _afx_dll_module_state:public Afx_module_state {public:      _afx_dll_module_state (): afx_m Odule_state (TRUE, afxwndprocdllstatic, 7)          {}}; Static _afx_dll_module_state afxmodulestate; afx_module_state* afxgetstaticmodulestate () {     afx_module_state* pmodulestate = & Afxmodulestate;      return pmodulestate; Further analysis found that the afxgetstaticmodulestate () function is statically linked to the DLL like the DllMain function, which means that there is a separate afxmodulestate in each DLL. We know that the afx_module_state holds separate information for each module, such as the class information implemented in the module, the resources used by the module at runtime, and so on. From this we can guess that afx_manage_state is used to pass the pointer we saved DLL information to MFC. See: #define AFX_MANAGE_STATE (P) afx_maintain_state2 _ctlstate (p); Afx_module_state* afxsetmodulestate (afx_module_state* pnewstate) {     _afx_thread_state* pState = _afxthreadstate;      afx_module_state* pprevstate = pstate->m_pmodulestate;      pstate->m_pmodulestate = pnewstate;      return pprevstate; }   Afx_maintain_state::~afx_maintain_state () {     _afx_thread_state* pstate = _ Afxthreadstate;      pstate->m_pmodulestate = m_pprevmodulestate; }   Afx_maintain_state2::afx_maintain_state2 (afx_module_state* pnewstate) {     m_ Pthreadstate = _afxthreadstate;      m_pprevmodulestate = m_pthreadstate->m_pmodulestate;      m_pthreadstate->m_pmodulestate = pnewstate; As you can see from the above code, AFX_MANAGE_STATE can ensure that the original modulestate pointer is restored when the function is exited. 3 Advantages and disadvantages AnalysisThere is no doubt that this approach is useful for module independence, for example, it guarantees that resources in this module will be used as a priority when reading or creating resources without worrying about conflicting resource IDs in other modules. But the disadvantage is obvious, every time you call MFC functions must use the afx_manage_state, very troublesome, and sometimes some of the more difficult to find errors. For example, when you place a variable of this type in your own class, when the class instance invokes the destructor, the CImageList destructor will also release the resource (handle) that it reads, but this time often does not use Afx_manage_ CImageList State (because the CImageList is released after the destructor call is completed), so that the mapping of this ImageList handle to the CImageList pointer will not be released correctly, potentially causing future pitfalls. 4 Conclusion1. Use this type of DLL only if the library you write is an extension of the MFC class library, otherwise use a normal DLL. 2. If the extension DLL does not use a separate resource, you do not need to use the MFC extended DLL type. 3, you can consider the resources in this DLL in the EXE or other types of main programs, so as to avoid the use of this type of DLL. 4, if you are using a statically linked DLL library, there is no problem.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.