Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# PINVOKE内存管理的单元测试 我有一个C++应用程序(.Net Cype 3.1),它使用一些非托管C++代码。互操作是使用PINVOKE实现的_C#_Unit Testing_.net Core_Garbage Collection_Pinvoke - Fatal编程技术网

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");
}