#include <msclr/marshal.h>
using namespace msclr::interop;
msclr::interop::marshal_context^ context;
const wchar_t* __MarshaledReturnVal = context->marshal_as<const wchar_t*>(__ReturnVal);
I spent quite some time now doing research on C++ to .NET bridging using C++/CLI and found your approach and code to be the cleanest from all the examples I looked at. However, getting it to work required some changes which made me wonder if you ever tried compiling above code samples. Or maybe the way I did it was different than intended?
For anyone interested in my working solution, here my approach:
1. I used Visual Studio 2008 and created 3 projects:
- A C# class library called ManagedClasses which contains the Calculator class.
- A C++ class library with CLR support (/clr) called ILBridge which contains the ILBridge_CppCliWrapper_Calculator and NativeExport_CppCliWrapper_Calculator classes.
- A C++ console application without CLR support called NativeApp which uses the ILBridge lib.
Due to changes in the way the marshaling between objects is done in Visual Studio 2008 I added an include for <msclr/marshal.h> and changed the code in the ILBridge class from this line:
wchar_t* __MarshaledReturnVal = marshal_to<wchar_t*>(__ReturnVal);
to this code snippet:
msclr::interop::marshal_context^ context;
const wchar_t* __MarshaledReturnVal = context->marshal_as<const wchar_t*>(__ReturnVal);
delete context;
Also, I had to split up the ILBridge class into header and source file, otherwise the NativeExport class would not compile, because the compiler kept complaining that you cannot use marshal_as in a class that is translated into native code.
Then I added
#using "../ManagedClasses/bin/Debug/ManagedClasses.dll"
to the ILBridge class header so that it finds the C# assembly.
Finally I took out the #ifdef THISDLL_EXPORTS from the NativeExport class header, since unless you define this symbol it won't set the correct dll export.