Есть желание заполнять Dictionary вида Dictionary<Enum,Struct>
в нативной части кода, используя возможности трансляции через vcclr.h
. Толком ничего не получается, студия ругается почти на каждую строчку. Есть ли доступный пример использования? буду признателен.
Я так понимаю что надо создавать дополнительные мелкие классы по конвертации, или я не так понял описание как это работает..
Результатом поиска решений в этой области привели к нескольким направлениям:
Использовать #include <cliext/adapter>
, это ms решение по сути работает только внутри C++
функции (unmanaged). Экспортировать в C++clr
(managed) код, то есть вернуть результатом работы функции не удастся, для этих целей не подходит.
Интересное, хоть и не очень свежее решение marshalfx, но требует добавления описания собственных не generic объектов. С generic'ами работает отлично.
Использование нативных прокси классов и директивы gcroot
(vcclr.h). Именно на нем я остановился, по порядку:
Например все это проживает в нэймспейс:
namespace MyNameSpace
{
Имеем managed класс:
public ref class MyData
{
public:
properties MyNameSpace::MyEnum MEnum;
properties Int32 MyInt;
properties Sting ^ MyStr;
}
Пишем для него прокси класс для unmanaged C++ кода:
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);
}
}
Определяем сокращение для Dictionary, чтобы было меньше букв :)
namespace SCG = System::Collections::Generic;
Пишем прокси класс для Dictionary (unmanaged C++ код):
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);
}
};
Как это использовать в C++
unmanaged коде:
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;
}
Для удобства создания прокси классов так-же можно написать простенький темплейт:
template<class T>
class ProxyObject
{
public:
gcroot<T^> vHandle;
ProxyObject() : vHandle(gcnew T()) {}
};
class ProxyMyData : public ProxyObject<MyNameSpace::MyData>
{
public:
Set(/* ... */) { /* ... */ }
}
Надеюсь что сэкономил кому либо пару лишних часов, информации на эту тему не очень много, к сожалению.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Мой профиль ( через команду netsh wlan show networks) имеет вот такую кофигурацию:
По умолчанию у меня собираются статические библиотеки (если явно не указываю SHARED при создании библиотеки или BUILD_SHARED_LIBS при запуске cmake), а как...
Предположим имеется следующий код, почему если его выполнить, и ввести, например ваыёё, то программа завершится, будто бы, пропустив оставшиеся...
В интернет искал ответ на свой вопрос, но не один из способов не работал