Tôi cần sử dụng API không được quản lý từ C++/CLI. API này lưu trữ một con trỏ void đến dữ liệu người dùng tùy ý và một vài callback. Sau đó nó cuối cùng gọi những callbacks đó, chuyển dữ liệu người dùng vào như void *.Việc sử dụng gcroot có an toàn không?
Cho đến nay tôi đã có một lớp bản địa đi qua nó "này" con trỏ như dữ liệu người dùng, và sử dụng con trỏ đó để có cuộc gọi API trở lại vào lớp này, ví dụ:
static void __stdcall Callback(void* userData) {
((MyType*)userData)->Method();
}
class MyType {
public:
MyType() { RegisterWithApi((void*)this, Callback); }
void Method();
};
Tôi đang cố gắng để dịch điều này bằng cách sử dụng một lớp được quản lý. Tôi phát hiện ra rằng loại gcroot thể được sử dụng để lưu trữ một cách an toàn một tài liệu tham khảo được quản lý trong mã nguồn gốc, vì vậy đây là cách tôi đang làm bây giờ:
// 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();
}
Trong khi điều này có vẻ tốt với trình biên dịch C++/CLI, tôi không hoàn toàn yên tâm. Từ những gì tôi hiểu, gcroot bằng cách nào đó theo dõi tham chiếu được quản lý của nó khi nó được chuyển bởi GC. Nó sẽ quản lý để làm điều này trong khi được lưu trữ như là một void * bởi mã không được quản lý? Mã này có an toàn không?
Cảm ơn.
Làm lợi cho Nguyên soái :: GetFunctionPointerForDelegate(), ví dụ [ở đây] (http://stackoverflow.com/questions/2972452/c-cli-pass-managed-delegate-to-unmanaged-code/2973278#2973278) –