Here's a minimalistic sample of a native wrapper to make a .NET managed library accessible to native C++ code, posted in response to a thread in another forum section.
The demo solution contains three projects, one representing each the managed library to be made accessible, the wrapper DLL and the native client app. Here are the relevant source files, ordered from low level upward:
public ref class ManagedClass
static void SayHello();
using namespace System;
using namespace ManagedLib;
Console::WriteLine("Hello from the managed world!");
#define EXPORTS __declspec(dllexport)
EXPORTS void WINAPI NativeHelloWrapper();
// Must be compiled with CLR support.
// In the demo solution, this project has a project reference to ManagedLib. In a real-life
// scenario with a 3rd-party .NET library DLL, that would either be an assembly reference to
// that DLL or simply a #using directive (note the #).
// No need to #include ManagedLib.h: The prototype information is implicitly imported by
// referencing the .NET library DLL.
void WINAPI NativeHelloWrapper()
Actually, the term "native wrapper" is somewhat inaccurate: The wrapper DLL isn't strictly native, it rather is a mixed-mode DLL containing both native and managed code. However, the same inaccuracy usually applies to the to the term "managed wrapper". The word before "wrapper" rather denotes the type of interface exposed.
// NativeWrapperDemo.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
using namespace std;
int _tmain(int argc, _TCHAR* argv)
HMODULE hdll = LoadLibrary(_T("NativeWrapper.dll"));
FARPROC NativeHelloWrapper = GetProcAddress(hdll, "_NativeHelloWrapper@0");
cout << "Have a nice native program run! :)" << endl;
cout << "Back in the native world." << endl;
Of course there's plenty of room left for more in-depth discussions about performance considerations and such, I'm just too tired to start that right now. At any rate, I think, while I wouldn't really bet on that the wrapper approach beats a COM-based approach which bypasses the wrapper stage hands-down in terms of performance, I'd say at least it's more convenient. And it most probably isn't significantly inferior compared to the COM approach.