I've done the other way around (Calling pure C++ code from .Net) with C++/CLI and it worked (for the most part).
How is the native->c++/cli direction done?
I really don't want to use COM interop...
I've done the other way around (Calling pure C++ code from .Net) with C++/CLI and it worked (for the most part).
How is the native->c++/cli direction done?
I really don't want to use COM interop...
Calling .NET code from C++/CLI is very straightforward. Its very similar to regular C++. Make sure your project is setup as a C++/CLI project, add a reference to your .NET assembly by going to the project properties under "Common Properties", then use your .NET objects with some code like this:
using namespace System;
using namespace System::Collections::Generic;
using namespace MyNamespace;
void MyFunctionCall()
{
MyObject ^obj = gcnew MyObject();
obj->MyMethod();
// ...
}
the book C++/CLI in Action has a chapter named Mixing Managed and Native Code and inside the chapter, under Working With Interop Mechanisms heading it talks about both accessing a managed library from native code and accessing a native library from managed code. It did help me get the concepts when i read it once upon a time.
If you have an existing native C++ app and want to avoid "poluting" it with too much CLR stuff, you can switch on the /clr flag for just one specific file and use a standard C++ header to provide an interface to it. I've done this in an old bit of code. In the header I have:
void SaveIconAsPng(void *hIcon, const wchar_t *pstrFileName);
So the rest of the program has a simple API to which it can pass an HICON and a destination filepath.
Then I have a separate source file which is the only one that has /clr switched on:
using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;
using namespace System::Drawing::Drawing2D;
#include <vcclr.h>
#include <wchar.h>
void SaveIconAsPng(void *hIcon, const wchar_t *pstrFileName)
{
try
{
Bitmap bitmap(16, 16, PixelFormat::Format32bppArgb);
Graphics ^graphics = Graphics::FromImage(%bitmap);
graphics->SmoothingMode = SmoothingMode::None;
Icon ^icon = Icon::FromHandle(IntPtr(hIcon));
graphics->DrawIcon(icon, Rectangle(0, 0, 15, 15));
graphics->Flush();
bitmap.Save(gcnew String(pstrFileName), ImageFormat::Png);
}
catch (Exception ^x)
{
pin_ptr<const wchar_t> unmngStr = PtrToStringChars(x->Message);
throw widestring_error(unmngStr); // custom exception type based on std::exception
}
}
That way I can convert HICONs into .png files from my hairy old C++ program, but I've isolate the use of the .NET framework from the rest of the code - so if I need to be portable later, I can easily swap in a different implementation.
You could take this a stage further and put the CLR-dependent code in a separate DLL, although there would be little added value in that unless you wanted to be able to patch it separately.