Мне нужно использовать неуправляемый API из C++/CLI. Этот API хранит указатель void на произвольные пользовательские данные и несколько обратных вызовов. Затем он вызывает эти обратные вызовы, передавая данные пользователя как void *.Является ли это использование gcroot безопасным?
До сих пор я был родной класс, передавая ее «это» указатель в качестве пользовательских данных, и с помощью этого указателя есть вызов API обратно в этот класс, то есть:
static void __stdcall Callback(void* userData) {
((MyType*)userData)->Method();
}
class MyType {
public:
MyType() { RegisterWithApi((void*)this, Callback); }
void Method();
};
Я пытаюсь переведите это, используя управляемый класс. Я обнаружил, что тип gcroot может использоваться для безопасного хранения управляемых ссылок в машинном коде, так вот, как я делаю это сейчас:
// This is called by the native API
static void __stdcall Callback(void* userData) {
// Cast back to gcroot and call into managed code
(*(gcroot<MyType^>*)userData)->Method();
}
ref class MyType {
gcroot<MyType^>* m_self;
public:
MyType() {
m_self = new gcroot<MyType^>;
RegisterWithApi((void*)m_self, Callback);
}
~MyType() { delete m_self; }
// Method we want called by the native API
void Method();
}
Хотя это кажется штраф в C++/CLI компилятор, я не отлично зарекомендовал себя. Из того, что я понимаю, gcroot каким-то образом отслеживает свою управляемую ссылку, поскольку она перемещается GC. Удастся ли это сделать, сохраняя как пустоту * неуправляемым кодом? Безопасен ли этот код?
Спасибо.
Do favor Marshal :: GetFunctionPointerForDelegate(), пример [здесь] (http://stackoverflow.com/questions/2972452/c-cli-pass-managed-delegate-to-unmanaged-code/2973278#2973278) –