Using MFC regular mixed mode dll (/clr) from a managed application with Visual Studio 2005 Beta 2

Hello all,

I am having problems using MFC within a managed application in Whidbey. What I try to do is the following:

Writing a dll in C++/CLI that uses MFC. In this dll I implement managed wrapper classes around e.g. MFC dialog classes. Using these wrappers I want to display the dialogs in a managed application, written e.g. in C#.

This used to work with Visual Studio 2003 and managed extensions for C++ but, but it doesn't with Whidbey.

I used the wizard to create a MFC regular dll that uses the shared version of MFC, then applied the /clr switch to it. Then I reference this dll in a C# application, calling a managed wrapper class of the dll.

The problem is, that MFC does not get initialized correctly. Normally the ctor of the of the single static instance of the CWinApp derived class is called before DllMain is executed, entering the adress of the single instance into afxModuleState. Then DllMain calls CWinApp::InitInstance through this pointer. That's the way it works in VS 2003, at least if you follow http://support.microsoft.com/ id=814472.

In Whidbey, DllMain (defined in the mfc80d.dll) is called before the ctor of CWinApp and therefore the initialization doesn't work. CWinApp::InitInstance is not called and AfxGetApp() returns NULL. I tried to do something similar as in the KB article, applying the /NOENTRY switch to the linker, but I didn't succeed because of  runtime errors. The header #include <_vcclrit.h> mentioned in the article is present in Whidbey but if you use it, you get a lot of "deprecated" messages and it doesn't work.

Are there any suggestions or samples for doing this What is the correct way to do this in Whidbey

Thanks for any help,
Bernd



Answer this question

Using MFC regular mixed mode dll (/clr) from a managed application with Visual Studio 2005 Beta 2

  • l_steve_l

    I have done all that, but I still get strange errors, I understand the basics of C++ as a c# programmer, but I am not familiar with the "specials", when I make a pointer in my managed routine to a MFC Dialog, and when I call a DoModal, the program crashes,

    Do you have a simple example how I can call a MFC Dialog from my c# app

    AfxGetApp()->DoMessageBox(LPCTSTR("test"),1,1);

    This does work, but I am not able tot show a window

    Regards

    Pieter Quinart



  • Candela

    Have a look in this article in The Code Project:
    http://www.codeproject.com/managedcpp/mfcandwindowsforms.asp

    It describes three ways to wrap MFC controls in order to use them in .NET forms. The code uses managed extentions, but it is pretty simple to convert to C++/CLI.

    By following the instructions, I was able to wrap the example control shown; however, the techniques shown were not helpful in wrapping other controls such as CButton, CEdit and the likes.

    I'd appreciate any further information that you have found regarding using MFC controls in .NET.

  • gill cleeren

    Hi all,

    I have made some progress! Smile

    Well, its all in the documentation, but it is not that easy to find:

    http://msdn2.microsoft.com

    Develpment Tools and Languages / Visual Studio 2005 / Product Documentation / Visual C++ / Programming Guide / Native and .NET interoperability / Mixed (Native and Managed) Assemblies

    http://msdn2.microsoft.com/en-us/library/ms140812(en-US,VS.80).aspx

    There I found several topics, well worth reading. Very interesting was
    How to: Compile MFC and ATL Code with /clr Idea

    The trick is to let the CWinApp derived class of the regular MFC dll compile without /clr. This generates a native class with a native ctor, that will be called before DllMain, as it used to be in the good old times. When CWinApp::InitInstance() is called, the afxApp pointer is valid an all is fine.

    There seems to be an error in the documentation: For a regular MFC dll, you should follow the instructions for an extenstion dll, i.e. disable the precompiled headers, and do not compile stdafx.cpp and MyMFCApp.cpp with /clr.

    You will loose support for precompiled headers Sad because it is not possible to compile some of the files with /clr and some without in a single project with precompiled headers.

    With that I was able to display MFC dialogs from a C# application. I could even reference a MFC extension .dll from my regular .dll and use the native classes defined there thru managed C++/CLI wrappers in the regular .dll. Nice! Big Smile Allows us to reuse a lot of MFC code for .NET applications.

    But always remember: you have to put AFX_MANAGE_STATE(AfxGetStaticModuleState()); in all and every function of your managed wrapper classes that call directly or indirectly into MFC. This includes the ctors of the native classes that you might call in the ctors of the managed wrappers. Therefore you cannot use the initialisation list of the ctor but you have to call the native ctors in the managed ctor body after AFX_....

    My next step will be to try to host a CWnd derived class with its own painting routines in a Windows.Forms.Control class...

    Has anybody suggestions on this

    Bernd


  • JF002

    Tomer,

    thanks for the link. That was exactly what I was looking for.

    I tried the first method mentioned in the article, subclassing the window in the OnHandleCreated() override and it worked great.

    We have a CWnd derived class that provides plotting of line graphs and we can now reuse it in C# applications without changing a single line of code.

    Regards,
    Bernd

  • Using MFC regular mixed mode dll (/clr) from a managed application with Visual Studio 2005 Beta 2