tags:

views:

629

answers:

1

I have successfully upgraded an MFC application which was compiled with an old version of Developer Studio to Visual Studio 2008. A very small number of changes were needed because of some breaking changes in MFC. Now that everything works, I'd like to take the next step and compile the solution with /clr.

To do so, I have found useful information on the MSDN web site:

Here are the steps I have taken:

  1. Set the Runtime Library to Multi-threaded Debug DLL (/MDd).
  2. Set the Use of MFC to Use MFC in a Shared DLL.

However, doing so prevents me from linking the project:

  1. The reference to afxData can no longer be resolved; somehow, afxData is only visible when linking statically against MFC. In my code, I have the following declaration:

    extern AFX_DATA AUX_DATA afxData;

    which works fine with the statically linked MFC version.

  2. The references to _afxThreadState and _afxWinState cannot be resolved either.

Here are the full error messages :

error LNK2001: unresolved external symbol "struct AUX_DATA afxData" (?afxData@@3UAUX_DATA@@A)
error LNK2001: unresolved external symbol "class CThreadLocal<class _AFX_THREAD_STATE> _afxThreadState" (?_afxThreadState@@3V?$CThreadLocal@V_AFX_THREAD_STATE@@@@A)
error LNK2001: unresolved external symbol "class CProcessLocal<class _AFX_WIN_STATE> _afxWinState" (?_afxWinState@@3V?$CProcessLocal@V_AFX_WIN_STATE@@@@A)

in case this might be related to the name mangling...

So, what can I do in order to dynamically link against MFC, but still reference afxData, _afxThreadState and _afxWinState?

+1  A: 

When using MFC in a shared DLL, AUX_DATA must be dllimported.

extern __declspec(dllimport) AUX_DATA afxData

For thread state, rather than using template classes, use one of these

AFX_MODULE_THREAD_STATE* pState = _AFX_CMDTARGET_GETSTATE()->m_thread;
AFX_THREAD_STATE* pState = AfxGetThreadState();

Depending on the state information you require. For example, see here for some members that were moved to module state to fix a bug. Note that AfxGetModuleThreadState exists but is undocumented and could be changed in a future version.

Win state does not ring a bell, how is it used? There is probably a new way to accomplish it.

Aidan Ryan
Thank you for the hints; here are my first results at trying to solve this: AfxGetThreadState() seems to replace the previous use of _afxThreadState.I should have thought of the __declspec(dllimport) myself! I tried it and it works.I'll further investigate the _afxWinState thing. It points to a _AFX_WIN_STATE class which has a single member, m_bUserAbort, which is used by our code while printing, to check if the user pressed Cancel, I guess from what I see.
Pierre
The afxWinState.m_bUserAbort is a design mistake made by Microsoft, from what I understand reading this article: http://www.ddj.com/184409908?pgno=5The solution is to replace that code completely by using a global flag in our own code and by rewriting the default AbortProc.
Pierre
Added some clarification. There are some situations where you may want Module thread state.
Aidan Ryan