我有一个本地课程:
class NativeClass
{
int someVariable;
public:
void someNativeFunction(){}
};
我有一个托管类,可以轻松包装此本机类。
class ManagedClass
{
NativeClass *nativeClassObject;
public:
void someManagedFunction()
{
nativeClassObject->someNativeFunction();
}
};
我在C#应用程序中使用此托管类:
static void Main(string[] args)
{
ManagedClass objManagedClass = new ManagedClass();
objManagedClass.someManagedFunction();//line_1
//At this point onwards objManagedClass still has a reference on the stack, but is not used again.
//So, GC can delete this object.
}
由于在line_1之后未引用objManagedClass
,因此垃圾收集器可以随意销毁该对象,即使该对象正在处理内部本机调用也是如此。这将导致objManagedClass
的破坏,进而将破坏*nativeClassObject
。仅当someNativeFunction
分配大量内存或花费很长时间时,才可能发生这种情况,但为确保确定,我必须在调用之后稍后添加对objManagedClass
的引用。
class ManagedClass
{
NativeClass *nativeClassObject;
public:
void someManagedFunction()
{
nativeClassObject->someNativeFunction();
...
...
System::GC::KeepAlive(this);
}
};
KeepAlive()
调用应防止GC销毁它。有什么办法可以测试这种情况?我可以编写一些测试用例,如果不提供KeepAlive()
,它将失败,但是一旦我调用它就会通过?在托管函数之间调用Thread.Sleep(5000)
会有所帮助吗?
您可以通过调用GC::Collect
强制开始垃圾收集,然后使用GC::WaitForPendingFinalizers
等待直到垃圾收集完成。这应该可以让您测试您的方案。
看一下MSDN上的示例