Potrzebuję użyć niezarządzanego API z C++/CLI. Ten interfejs API przechowuje nieważny wskaźnik dla dowolnych danych użytkownika i kilku wywołań zwrotnych. Następnie w końcu wywołuje te wywołania zwrotne, przekazując dane użytkownika jako nieważne *.Czy korzystanie z gcroot jest bezpieczne?
Dotychczas miałem natywną klasę przekazując swoją „ten” wskaźnik jako danych użytkownika, a za pomocą tego wskaźnika, aby mieć wywołania API z powrotem do tej klasy, tj:
static void __stdcall Callback(void* userData) {
((MyType*)userData)->Method();
}
class MyType {
public:
MyType() { RegisterWithApi((void*)this, Callback); }
void Method();
};
próbuję przetłumacz to za pomocą klasy zarządzanej. Okazało się, że typ gcroot mogą być wykorzystane do bezpiecznego przechowywania zarządzanego odniesienie w natywnym kodzie, więc oto jak robię to teraz:
// 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();
}
Choć wydaje się dobrze do kompilatora C++/CLI, nie jestem doskonale upewniony. Z tego co rozumiem, gcroot w jakiś sposób śledzi zarządzany odnośnik, gdy jest przenoszony przez GC. Czy uda się to zrobić, gdy będzie przechowywany jako pustka * przez niezarządzany kod? Czy ten kod jest bezpieczny?
Dzięki.
Wykonaj frazę Marshal :: GetFunctionPointerForDelegate(), przykład [jest tutaj] (http://stackoverflow.com/questions/2972452/c-cli-pass-managed-delegate-to -unmanaged -code/2973278#2973278) –