There is a desire to fill a Dictionary of the form Dictionary<Enum,Struct> in the native part of the code, using the translation capabilities through vcclr.h . It really does not work, the studio swears on almost every line. Is there an available usage example? I will be grateful.

I understand that it is necessary to create additional small classes for conversion, or I did not understand the description of how it works ..

  • "Dictonary" is five! :) - Harry
  • @Harry, This is Google-Claudia :) I am glad that I delivered the moments of joy :) - NewView

1 answer 1

The result of the search for solutions in this area led to several areas:

  1. 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.

  2. 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.

  3. 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.