DllImport,C/C++->C#,输出双精度数组

c#

我想从 C++ 获取双打数组。
我用整数数组进行了测试,它工作正常,但我不知道双精度数组不能工作。
双精度数组的第一个和第二个元素是错误的。

还有一个奇怪的事情,我把FreeCoTaskMem注释掉了,因为如果我不注释,应用程序就会崩溃,ints和doubles是一样的。

给我任何提示,谢谢。

C/C++ 代码

#define DllExport __declspec(dllexport)
extern "C"
{       
   DllExport void TestOutOfInts(int** ints);
   DllExport void TestOutOfDoubles(double** doubles);
}

DllExport void TestOutOfInts(int** ints)
{
    int xyzs[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    (*ints) = xyzs;
}

DllExport void TestOutOfDoubles(double** doubles)
{   
    double xyzs[9] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };   
    (*doubles) = xyzs;
}

C# 代码

[DllImport("MeshToolsWrapper.dll")]
static extern void TestOutOfInts(out IntPtr ints);

[DllImport("MeshToolsWrapper.dll")]
static extern void TestOutOfDoubles(out IntPtr doubles);

TestOutOfInts(out IntPtr ints);
int[] test1 = new int[9];
Marshal.Copy(ints, test1, 0, 9);
//Marshal.FreeCoTaskMem(ints);

TestOutOfDoubles(out IntPtr doubles); 
double[] test2 = new double[9];
Marshal.Copy(doubles, test2, 0, 9);
//Marshal.FreeCoTaskMem(doubles);

C# 结果

# ints
1
2
3
4
5
6
7
8
9

# doubles
1.16501519399776E-311
6.95245618745976E-310
3.3
4.4
5.5
6.6
7.7
8.8
9.9

回答

这个:

DllExport void TestOutOfDoubles(double** doubles)
{   
    double xyzs[9] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };   
    (*doubles) = xyzs;
}

即使没有 C# 互操作,也是未定义的行为。您正在返回一个指向堆栈内存的指针(数组)。下一个函数调用和内容xyzs被破坏。几乎可以保证。

这同样适用于您的TestOutOfInts功能。你很幸运,它似乎有效。

这是修复:

DllExport void TestOutOfDoubles(double** doubles)
{   
    double xyzs[9] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };   
    double* result = new double[9];
    std::copy(xyzs, xysz+9, result);
    
    (*doubles) = result;
}

但是您需要提供另一个函数来释放已分配的内存供 C# 代码调用。

更好的方法是强制调用者进行分配。有不同的技术,但我建议:

DllExport void TestOutOfDoubles(double* doubles, unsigned int size)
{   
    double xyzs[9] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };   

    if (size > 9)
    {
        size = 9;
    }

    std::copy(doubles, xyzs, xysz+size);

}

另一个函数可以提前检索大小。

DllExport unsigned int GetDoubleArrayLength()
{   
   return 9; // or whatever the actual size is    
}

然后由 C# 代码来进行数组分配。


以上是DllImport,C/C++->C#,输出双精度数组的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>