Thursday, February 26, 2009

Call Managed DLL From Unmanaged EXE

Here's a quick run-through showing how to call a .NET assembly from a native MFC C++ application.

Why would anyone want to do that? Useful for extending a large existing MFC codebase to use new CLR features without modifying the build settings of the original MFC projects.

Unmanaged Native C++ application calls through a bridge dll to the managed .NET Assembly:

MFC exe --> MFC Extension DLL --> .NET Assembly

The MFC executable doesn't need to have /clr turned on because the MFC Extension DLL acts as a cover over the .NET code. The .NET Assembly can be written in your favorite .NET language, like C#.



1. This example assumes you're starting with an existing MFC application solution. Set up the .NET Assembly by adding a new CLR Class Library project to your solution.

  • Add a new CLR Class Library, called BackEnd.dll for this example.
  • Add a new class to the dll, use the standard export declarations.
namespace BackEnd {

public ref class Class1
{
public:
int BCount(int a, int b)
{
return a + b;
}
};
}


2. Add the bridge dll to sit between the managed dll and your unmanaged application:

  • Add a new MFC Extension DLL, called Bridge.dll for this example.
  • Don't forget to add Linker Additional Dependancies : "..\bin\Bridge.lib" to your executables project settings.
  • Turn on CLR support, set the /clr flag in the bridge dll project settings.
  • Add a new class to the dll, use the standard export declarations.

Check.h

class __declspec(dllexport) Check
{
public:
Check(void);
virtual ~Check(void);

int Count(int a, int b);
};

Check.cpp

#include "StdAfx.h"
#include "Check.h"

#using "..\Debug\BackEnd.dll"

using namespace System;
using namespace BackEnd;

Check::Check(void)
{
}

Check::~Check(void)
{
}

int Check::Count(int a, int b)
{
// Note this is dll uses C++/CLI style coding
Class1^ test = gcnew Class1();
return test->BCount(a, b);
}

Also, be sure to set the debugger to mixed mode to allow breaking in managed code when running from the native executable.

No comments: