none
How to Port MFC to .NET; from VC6 C++ to Managed C++ and/or C# .NET

    Question

  • Can someone point me to information on how to port and/or reuse a portion of a huge MFC app to C# .NET managed and/or C++ .NET managed code.

    Willing to rewrite most of the user interface, but need to preserve/modify existing code that is based on 50+ classes derived from MFC's CObject.  I need the "Serialize" portions of CObject so that my existing data files can be read into the ported app, or so I can create a conversion app.

    I already have everything compiling and running in VS.NET C++ 2003 using MFC.  But this is not a Managed code app, and C# can't talk to it in an interop kind of way.  Further, it can't use 3rd party .NET Controls such as those from Infragistics and no other developers here can work on it.

    It's not a web-based app; it's desktop only and doesn't use any traditional database.

    Want to have new app use .NET Framework.  I have 3 experienced .NET programmers on my team including strong SQL experience; none of them know anything about C++ or MFC, much less interop issues.

    I do not need to port any dialog box or Doc/View architecture-related code, but it would be nice to cut and paste some of that into managed code.

    I do not need any database support.  i.e. not using ADO, Sql, Ole or Oracle.  Also NOT using ActiveX, COM, DCOM, ATL or any other such technologies.

    My serialized files are huge (50MB to 750MB) and contain "the data" and are all derived from CObject.  You could call this a simple proprietary database without many features, but extremely fast.

    A "CObject" emulator class written in C# or C++ managed would be great; willing to buy it.

    It's ok if I have to create some sort of static MFC library Dll as long as it can be called somehow (like interop) from managed code.  I can't figure out how to do this (link and #include issues etc) when a Managed language like C++ or C# is in control.  Willing to Wrap MFC objects in some other class even if it's a lot of work.

    It is NOT an option to convert proprietary file to XML format and then import into managed app... too huge for client PC.  That would be too slow and would required too much hard drive space.  Must either read and use directly or convert from proprietary to MSDE, for example, without going the XML route.

    Have VS2003; will use VS2005 beta in November.

    The VC6 version of this app uses a 3rd party Grid control from Stringray, now owned by RogueWave.  I'm willing to use the .NET version of their grid as an interim step, but long-term it needs to be something more flexible and able to support databinding from MS SQL Data Provider/DataAdaper.

    My employer has resources and money to do this; just need to get pointed somewhere.  I'm a seasoned MFC expert (since 1995) and the only developer who has ever worked on this code, a 5-year fulltime effort.
    Tuesday, September 20, 2005 9:40 PM

Answers

  • You can create managed wrapper classes around your unmanaged CObject derived classes in managed C++ or C++/CLI (VS.NET 2005). Put them all together into a regular MFC dll that you compile with /clr. Then reference this assembly from e.g. a C# application.

    The managed wrapper class can hold a pointer to the unmanaged class and you simply forward all method calls to the unmanaged class. So you should be able to use serialization of MFC and access (read/write) the data in the classes from for e.g. a C# application.

    Please see my recent post for more details.

    http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=90030

    Bernd


    Wednesday, September 21, 2005 11:00 AM
  • Good answer!  I was hoping I didn't have to put all the MFC stuff into a separate DLL, but I can live with that.  Not as "seemless", but still better than writing from scratch.

    I'll try it within the next few days... not sure how to reference a C++ DLL from C#, but hopefully that's not too hard to figure out. i.e. don't know how to tell C# to #include a class in a C++ dll, even though that dll is present in the Solution Explorer.  Perhaps #include MyMFCDll.MyWrappedFMCClass.h???  I'm just learning C#.

    I understand what you mean about wrapping and had already tried that.  Wrapping an unmanaged class was easy and as documented in several places... but if I had to do that with a CObject-derived class, it wouldn't compile because CObject isn't defined in the managed C++ or C# app as generated by the Wizard.  Your idea to put that in a separate dll apparently avoids that issue... somehow.

    Fortunately I don't need to use the dialog classes as you did... seems like that's pretty cool though... might do it as an interim step to get everything going.  I only needed CObject because of CObject's serialize support to read my existing legacy files for conversion.  Aside from that, the entire app is being rewritten to eventually use ADO.NET.




    Wednesday, September 21, 2005 6:13 PM
  • Thanks.

    The MFC dll containing the managed wrapper classes and the MFC classes compiled with /clr "is a" .NET assembly. So you can reference it as any other .NET assembly in a C# or VB.NET or managed C++/CLI project. The main app  sees the managed classes then, no need to #include something (at least in VS.NET 2005).

    I would recommend putting the MFC / managed interop stuff into a seperate dll for serveral reasons:

    1. that is a special dll because it contains a mixture of managed and unmanaged code and is therefore "unsafe". You main app still could be "pure" and "safe" (and managed).

    2. you might want to replace your MFC classes later by different, managed classes. All you have to do then, is replacing the .dll

    3. Having a component that handles the persistance seperatly in a different dll and therefore reducing what the main app sees to the public interface of the dll is a good idea from an architecture point, regardless of the MFC stuff.

    Bernd
    Thursday, September 22, 2005 6:43 AM

All replies

  • The .NET compiler does not create managed C++ code by default, I believe all you need to do is add a /clr compiler switch to make this happen, but I also think that's the thin end of the wedge.  Basically, you should buy a book on managed C++, and/or read articles such as http://www.ondotnet.com/pub/a/dotnet/2003/01/13/intromcpp.html, and you should have no trouble compiling your business logic in C++ so that your C# app can call it.  Your main issue could well be getting your code to compile, seeing as VC6 was such a poor implimentation of the standard, but it seems you have passed that step already, the rest should be smooth sailing.

    Tuesday, September 20, 2005 10:08 PM
  • I have read Visual C++ .NET - A Managed Code Approach for Experienced Programmers by Deitel.

    I have successfully created managed projects that can communicate to unmanaged code.  A managed C++ object can interact with an unmanaged C++ object.  But that unmanaged class code can't be MFC's CObject.  So that's my problem.

    Thanks for trying to help, wish it was that simple.
    Tuesday, September 20, 2005 10:20 PM
  • But that unmanaged class code can't be MFC's CObject.  So that's my problem.

    OK, sorry I didn't get that from your original post.  Here's the thing tho - there is definately no way to convert MFC to C# automagically, so no matter which way you look at it, if you can't use CObject in your unmanaged class ( although I can't imagine why that would be ? ), then you're going to have to change it, no matter what.  What does CObject give you that you need ?



    Tuesday, September 20, 2005 10:24 PM
  • You can create managed wrapper classes around your unmanaged CObject derived classes in managed C++ or C++/CLI (VS.NET 2005). Put them all together into a regular MFC dll that you compile with /clr. Then reference this assembly from e.g. a C# application.

    The managed wrapper class can hold a pointer to the unmanaged class and you simply forward all method calls to the unmanaged class. So you should be able to use serialization of MFC and access (read/write) the data in the classes from for e.g. a C# application.

    Please see my recent post for more details.

    http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=90030

    Bernd


    Wednesday, September 21, 2005 11:00 AM
  • Good answer!  I was hoping I didn't have to put all the MFC stuff into a separate DLL, but I can live with that.  Not as "seemless", but still better than writing from scratch.

    I'll try it within the next few days... not sure how to reference a C++ DLL from C#, but hopefully that's not too hard to figure out. i.e. don't know how to tell C# to #include a class in a C++ dll, even though that dll is present in the Solution Explorer.  Perhaps #include MyMFCDll.MyWrappedFMCClass.h???  I'm just learning C#.

    I understand what you mean about wrapping and had already tried that.  Wrapping an unmanaged class was easy and as documented in several places... but if I had to do that with a CObject-derived class, it wouldn't compile because CObject isn't defined in the managed C++ or C# app as generated by the Wizard.  Your idea to put that in a separate dll apparently avoids that issue... somehow.

    Fortunately I don't need to use the dialog classes as you did... seems like that's pretty cool though... might do it as an interim step to get everything going.  I only needed CObject because of CObject's serialize support to read my existing legacy files for conversion.  Aside from that, the entire app is being rewritten to eventually use ADO.NET.




    Wednesday, September 21, 2005 6:13 PM
  • In order to compile CObject, it has to be an MFC app or Dll.  I need CObject because of it's serialize capabilities for my legacy file conversions.  It would also be nice to be able to use CTypePtrArray-derived template classes that I have written, but that wasn't as important.

    Thanks for your response... the other response is from someone who ran into the same issue I did.  The beauty of his approach is that you can do the wrapping in C++, but use the class in that dll from C#.  Cool.  So there's not anywhere near as many "changes" to write.  I'll try it within the next few days.
    Wednesday, September 21, 2005 6:21 PM
  • Thanks.

    The MFC dll containing the managed wrapper classes and the MFC classes compiled with /clr "is a" .NET assembly. So you can reference it as any other .NET assembly in a C# or VB.NET or managed C++/CLI project. The main app  sees the managed classes then, no need to #include something (at least in VS.NET 2005).

    I would recommend putting the MFC / managed interop stuff into a seperate dll for serveral reasons:

    1. that is a special dll because it contains a mixture of managed and unmanaged code and is therefore "unsafe". You main app still could be "pure" and "safe" (and managed).

    2. you might want to replace your MFC classes later by different, managed classes. All you have to do then, is replacing the .dll

    3. Having a component that handles the persistance seperatly in a different dll and therefore reducing what the main app sees to the public interface of the dll is a good idea from an architecture point, regardless of the MFC stuff.

    Bernd
    Thursday, September 22, 2005 6:43 AM
  • I came across a product called RC Converter (www.dudelabs.com) which will convert your resources to .NET, so you don't have to rewrite your UI.  We are considering using it to convert our MFC applications to .NET.  In addition to our UI we have a lot of business rules code written in MFC and C++.  I was just going to put a COM wrapper around this code, but maybe the managed wrapper is a better way to go.
    Tuesday, October 04, 2005 2:05 AM
  • Looks good.  For $99 it might be worth a shot and might change my migration strategy.  Let me know if you try it.
    Tuesday, October 04, 2005 1:33 PM
  • We tried it with our app.  It works well and saved us lots of time as our app has 300+ plus dialogs and views.  We just needed to manually replace our date controls (which were an old 3rd party control) with the .NET datetimepicker. 

    Also, the article at this location http://blogs.wdevs.com/mpbutler/archive/2005/04/29/movingfrommfctocsharp.aspx also
    gave some good information about .NET replacements for more advanced controls.
    Friday, October 07, 2005 1:39 AM
  • Hello,

    It seems to be just the program I need as well.

    So I down loaded the restricted demo version then tried to buy it.

    But it looks as though they have disappeared your link does not work.

    Does anybody know how to get the program? or anything similar.

    David

    Wednesday, October 04, 2006 11:07 AM
  • We haven't disappeared.  We did had a problem with our hosting service, but the site is back up now.  Let me know if you have any questions via support@dudelabs.com.

    Wednesday, October 04, 2006 8:06 PM
  • Glad to hear it, your program can save me a lot of time.

    David

    Thursday, October 05, 2006 8:56 AM
  • I'm also trying to convert code from a MFC app to something that can be called from a C# app, but the link you have posted here is broken.  Is there any other way to see your post?
    Monday, July 27, 2009 6:06 PM
  • Hello,  Do you still have this code/article in your archive?  Please let me know
    Sunday, June 16, 2013 9:02 PM
  • Hello Bernd....the link forums.microsoft.com/msdn/ShowPost.aspx?PostID=90030" is stale.

    Can you point me to the right resource...i need to host MFC dialogs in my .NET app (WPF) and ur answer seems helpful....

    Monday, October 07, 2013 5:16 AM