grogroot的这种用法安全吗?
Is this usage of gcroot safe?
我需要使用来自c++/CLI的非托管API。这个API存储了一个指向任意用户数据的空指针和一些回调函数。然后它最终调用这些回调函数,将用户数据作为void*.
传入。到目前为止,我有一个本地类传递它的"this"指针作为用户数据,并使用该指针有API回调到这个类,即:static void __stdcall Callback(void* userData) {
((MyType*)userData)->Method();
}
class MyType {
public:
MyType() { RegisterWithApi((void*)this, Callback); }
void Method();
};
我正试图用一个托管类来翻译这个。我发现可以使用类型groot在本机代码中安全地存储托管引用,所以我现在是这样做的:
// 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编译器来说似乎很好,但我并不完全放心。据我所知,当它被GC移动时,groot以某种方式跟踪它的托管引用。它会设法做到这一点,而存储为一个void*由非托管代码?这个代码安全吗?
谢谢。
这就是我最终所做的,它工作得很好。groot的目的是在本机堆上存储托管引用,这正是我在这里所做的。
不!正好相反。groot是一个本地类模板。您可以使用它以本机类型存储托管内存的句柄,该本机类型使用clr支持进行编译。您通常将使用它将对本机对象的成员函数的调用转移到存储在ggroot类型成员中的托管对象。
编辑:我昨天在手机上键入代码示例有点尴尬…gcroot<T^>
的预期和典型用法是这样的:
// ICallback.h
struct ICallback {
virtual void Invoke() = 0;
virtual void Release() = 0;
protected:
~ICallback() {}
};
这是你的原生应用或库看到和包含的内容。然后,你有一个混合组件编译与CLR支持,它实现ICallback
和存储一个句柄到一些管理对象在gcroot<ManagedType^>
:
// Callback.cpp (this translation unit must be compiled with /clr)
// I did not compile and test, but you get the point...
template<class T^> class Callback : public ICallback {
gcroot<T^> m_Managed;
virtual void Invoke()
{
m_Managed->Invoke();
}
virtual void Release()
{
delete this;
}
public:
Callback(T^ p_Managed) : m_Managed(p_Managed) {}
};
__declspec( dllexport ) ICallback* CreateCallback()
{
auto t_Managed = gcnew SomeManagedType();
return new Callback<System::Action^>(
gcnew System::Action(t_Managed, &SomeManagedType::Method));
}
您的本机应用程序调用CreateCallback
,接收ICallback
的实例,当Invoke
-d调用托管类型的方法时,在gcroot<System::Action^>
中保存…
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 这个指针在c++中的用法
- 通过网络、跨平台传递std::变体是否安全
- 在std::thread中,joinable()然后join()线程安全吗
- 使用std::istream::peek()总是安全的吗
- 从值小于256的uint16到uint8的Endian安全转换
- 使用新线程在类似于 Scott Meyer 的单例习惯用法的实现中实例化单例是否安全?
- std::map 的线程安全用法
- 运算符重载和到布尔的隐式转换与安全布尔习惯用法有关
- 安全enable_shared_from_this用法
- 安全bool习惯用法bool_type(和安全bool习惯用法)是如何工作的
- 常量正确性和安全bool习惯用法
- 在boost中是否有一个安全的bool习惯用法帮助器
- grogroot的这种用法安全吗?
- 安全布尔习惯用法在C++11中已经过时了吗