C# PINVOKE内存管理的单元测试 我有一个C++应用程序(.Net Cype 3.1),它使用一些非托管C++代码。互操作是使用PINVOKE实现的
我的代码是这样做的(简化):C# PINVOKE内存管理的单元测试 我有一个C++应用程序(.Net Cype 3.1),它使用一些非托管C++代码。互操作是使用PINVOKE实现的,c#,unit-testing,.net-core,garbage-collection,pinvoke,C#,Unit Testing,.net Core,Garbage Collection,Pinvoke,我的代码是这样做的(简化): 我遵循这种模式,C++代码应该在将数组存储到UnMeaveDebug状态之前将其复制到内部。 现在我想为非托管对象在内部复制数组的命题编写一个单元测试。 我的尝试如下所示: UnmanagedObject unmanaged; { double[] managedArray = new[] { 1.0, 2.0, 3.0 }; unmanaged = CreateUnmanagedObject(managedArray); } // With thi
我遵循这种模式,C++代码应该在将数组存储到UnMeaveDebug状态之前将其复制到内部。
现在我想为非托管对象在内部复制数组的命题编写一个单元测试。 我的尝试如下所示:UnmanagedObject unmanaged;
{
double[] managedArray = new[] { 1.0, 2.0, 3.0 };
unmanaged = CreateUnmanagedObject(managedArray);
}
// With this call I'm relying on the fact, that the GC will collect
// managedArray, because it's gone out of scope.
System.GC.Collect();
// If DoStuff works properly here, it means that the C++ code
// has copied the array internally.
unmanaged.DoStuff();
GC将收集的短语是否因为超出范围而正确?这保证会一直发生吗
[我对问题进行了编辑,删除了一些不相关的内容,以使问题更加清晰。一些注释不再适用。]在将原始类型的数组传递给pinvoke之前,您不需要锁定/修复它们。您可以直接传递它们,在方法调用期间,.NET将为您锁定它们(因此当pinvoke返回时,它们将被取消锁定)
如果你想检查你的数据是否真的被C++复制,你可以:
UnmanagedObject unmanaged;
{
double[] managedArray = new[] { 1.0, 2.0, 3.0 };
unmanaged = CreateUnmanagedObject(managedArray);
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = double.NaN;
}
}
// At this point the GC should collect the managedArray, if I trigger it.
System.GC.Collect();
// If DoStuff works properly here, it means that the C++ code
// has copied the array internally
unmanaged.DoStuff();
非托管对象非托管;
{
double[]managedArray=new[]{1.0,2.0,3.0};
非托管=CreateUnmanagedObject(managedArray);
for(int i=0;i
因此,可以将数组的值设置为其他值
您甚至可以检查对象是否确实已收集:
WeakReference wr;
{
double[] managedArray = new[] { 1.0, 2.0, 3.0 };
wr = new WeakReference(managedArray);
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = double.NaN;
}
}
// At this point the GC should collect the managedArray, if I trigger it.
System.GC.Collect();
if (wr.IsAlive)
{
Console.WriteLine("Warning: the object hasn't been collected");
}
else
{
Console.WriteLine("The object has been collected");
}
WeakReference wr;
{
double[]managedArray=new[]{1.0,2.0,3.0};
wr=新WeakReference(managedArray);
for(int i=0;i
请注意,如果程序是在调试模式下编译的,GC在方法结束之前不会收集对象,而在发布模式下,可以在作用域结束时收集对象。在将基元类型传递给pinvoke之前,不需要固定/修复基元类型数组。您可以直接传递它们,在方法调用期间,.NET将为您锁定它们(因此当pinvoke返回时,它们将被取消锁定)。您是否阅读了注释,当然请注意,当控件位于固定块中时,intPtr仅指向数组。。。这还取决于
CreateUnmanagedObject
做什么真正的代码比这更复杂,我需要这样做。这与问题无关。问题是如何编写一个测试,用于测试在方法调用之后非托管代码仍然有效。@塞尔文是的,这就是为什么我写的“我遵循这个模式,C++代码应该在内部复制数组”。我希望避免两次复制数组。关于直接传递数组:我不能这样做(C++函数期望空洞*,它应该与任何内置类型数组一起工作)。无论如何,这与问题无关。当然,我可以手动更改数组。但是我问我是否可以依靠垃圾收集器,或者我是否必须自己去做。
UnmanagedObject unmanaged;
{
double[] managedArray = new[] { 1.0, 2.0, 3.0 };
unmanaged = CreateUnmanagedObject(managedArray);
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = double.NaN;
}
}
// At this point the GC should collect the managedArray, if I trigger it.
System.GC.Collect();
// If DoStuff works properly here, it means that the C++ code
// has copied the array internally
unmanaged.DoStuff();
WeakReference wr;
{
double[] managedArray = new[] { 1.0, 2.0, 3.0 };
wr = new WeakReference(managedArray);
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = double.NaN;
}
}
// At this point the GC should collect the managedArray, if I trigger it.
System.GC.Collect();
if (wr.IsAlive)
{
Console.WriteLine("Warning: the object hasn't been collected");
}
else
{
Console.WriteLine("The object has been collected");
}