The result of the search for solutions in this area led to several areas:
To use #include <cliext/adapter> , this ms solution essentially only works inside the C++ function (unmanaged). It is impossible to export C++clr (managed) code to C++clr , that is, to return the result of the function’s operation, it is not suitable for this purpose.
An interesting, though not very fresh marshalfx solution, but requires the addition of a description of your own non-generic objects. It works great with generics.
Using native proxy classes and gcroot directives (vcclr.h). It was on it that I stopped, in order:
For example, it all lives in namespace:
namespace MyNameSpace {
We have managed class:
public ref class MyData { public: properties MyNameSpace::MyEnum MEnum; properties Int32 MyInt; properties Sting ^ MyStr; }
We write for it a proxy class for unmanaged C ++ code:
class ProxyMyData { public: ProxyMyData() { vHandle = gcnew MyNameSpace::MyData(); } gcroot<MyNameSpace::MyData^> vHandle; void Set(MyNameSpace::MyEnum id, Int32 idx, wchar_t *wstr) { vHandle->MEnum = id; vHandle->MyInt = idx; vHandle->MyStr = gcnew String(wstr); } }
Define abbreviations for Dictionary so that there are fewer letters :)
namespace SCG = System::Collections::Generic;
Writing a proxy class for Dictionary (unmanaged C ++ code):
class ProxyDictionary { public: ProxyDictionary() { vHandle = gcnew SCG::Dictionary<MyNameSpace::MyEnum, MyNameSpace::MyData^>(); } gcroot<SCG::Dictionary<MyNameSpace::MyEnum, MyNameSpace::MyData^>^> vHandle; void Add(MyNameSpace::MyEnum id, gcroot<MyNameSpace::MyData^> val) { vHandle->Add(id, val); } };
How to use it in C++ unmanaged code:
SCG::Dictionary<MyNameSpace::MyEnum, MyNameSpace::MyData^> ^ MyClass::MyFunc(Int32 idx, wchar_t *wstr) { auto pdict = std::make_unique<ProxyDictionary>(); auto pdata = std::make_unique<ProxyMyData>(); pdata.get()->Set( MyNameSpace::MyEnum::TAG_1, idx, wstr ); pdict.get()->Add( MyNameSpace::MyEnum::TAG_0, pdata.get()->vHandle ); return pdict.get()->vHandle; }
For the convenience of creating proxy classes, you can also write a simple template:
template<class T> class ProxyObject { public: gcroot<T^> vHandle; ProxyObject() : vHandle(gcnew T()) {} }; class ProxyMyData : public ProxyObject<MyNameSpace::MyData> { public: Set(/* ... */) { /* ... */ } }
I hope that saved someone a couple of extra hours, information on this topic is not very much, unfortunately.