Pages

Saturday 30 December 2006

Mixing legacy MFC code with Windows Forms (Part 3)

Summary: The ability to intimately mix unmanaged MFC/C++ code with managed code is one of my favorite features in .NET. Migration projects that would otherwise take years can be done in a matter of months. To re-use legacy MFC/C++ code with minimal changes and call the code from a C# Winforms application, you need to:
  1. Create an MFC DLL project and activate the /CLR switch to indicate that this is a mixed assembly.
  2. Add the legacy source files to the MFC DLL project.
  3. Prepare the legacy code so that it compiles for Unicode (see Converting an MFC project to Unicode)
  4. Add a managed class to the above project. This class will be the interface between the managed Winforms application and the legacy MFC/C++ code.

Project settings:

  • Dynamically link against the MFC DLLs: in Configuration Properties > General > Use of MFC
  • Compile for Unicode (this is mandatory because .NET works only with Unicode): General > Character Set
  • Make it a mixed assembly: General > Common Language Runtime Support, set to /CLR. This way the DLL can contain both unmanaged and managed code. The managed code will be visible to any managed application using the DLL.

Can I debug the legacy MFC/C++ code loaded as part of the managed application?

Yes! In the project properties for the managed executable using the DLL, go to the Debug tab and tick Enable unmanaged code debugging.

Step by step:

  1. Create an MFC DLL using the MFC DLL Wizard. Call the project Legacy for instance. Options: Regular DLL using MFC DLL. If the legacy code is an MFC-based MDI application, the main frame will be created as soon as the DLL is loaded (through CLegacyApp::InitInstance)
  2. Add the source files containing the legacy code to this new project.
  3. Set the project settings as described above.
  4. Compile and fix all Unicode issues and other compiler annoyances...
  5. Created a LegacyWrapper C++ class.

Issues associated with compiling with /CLR:

  • Warning LNK4248: unresolved typeref token (01000013) for '_TREEITEM'; image may not run. Solution here. This is because _TREEITEM is defined in a native library, but the forward declaration is done in an MSIL module. Forcing the definition of _TREEITEM in stdafx.h eliminates the warning.

No comments: