Ho bisogno di utilizzare un'API non gestita da C++/CLI. Questa API memorizza un puntatore vuoto su dati utente arbitrari e alcuni callback. Alla fine chiama quei callback, passando i dati dell'utente nel nulla *.L'uso di gcroot è sicuro?
Finora ho avuto una classe nativa passando il suo puntatore "this" come i dati degli utenti, e l'utilizzo di tale puntatore per avere la chiamata API di nuovo in questa classe, vale a dire:
static void __stdcall Callback(void* userData) {
((MyType*)userData)->Method();
}
class MyType {
public:
MyType() { RegisterWithApi((void*)this, Callback); }
void Method();
};
sto cercando di traduci questo utilizzando una classe gestita. Ho trovato che il tipo gcroot può essere utilizzata per memorizzare in modo sicuro un riferimento gestito in codice nativo, quindi ecco come lo sto facendo ora:
// 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();
}
Anche se questo sembra che vada bene per il compilatore C++/CLI, io non sono perfettamente rassicurante. Da quanto ho capito, gcroot in qualche modo tiene traccia del suo riferimento gestito mentre viene spostato dal GC. Riuscirà a farlo mentre memorizzato come vuoto * dal codice non gestito? Questo codice è sicuro?
Grazie.
Preferire Marshal :: GetFunctionPointerForDelegate(), un esempio [è qui] (http://stackoverflow.com/questions/2972452/c-cli-pass-managed-delegate-to-unmanaged-code/2973278#2973278) –