微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从C到C的数组#

我试图将一个双数组(它实际上是一个std :: vector,但转换后转换)从c dll传递到c#脚本(unity).
使用此处概述的方法https://stackoverflow.com/a/31418775.

我可以在我的控制台上成功地获得阵列打印的大小但是我无法使用“CoTaskMemAlloc”来为阵列分配内存,因为我使用Xcode并且它似乎没有COM.

对于更多背景,此数组是GUI控件的一部分,c创建它并且用户使用c#GUI进行编辑 – 因此计划是在编辑时将数组传递回c.

C++ code
extern "C" ABA_API void getArray(long* len, double **data){
    *len = delArray.size();
    auto size = (*len)*sizeof(double);
    *data = static_cast<double*>(CoTaskMemAlloc(size));
    memcpy(*data, delArray.data(), size);
}

C# code 
[DllImport("AudioPluginSpecDelay")]
private static extern void getArray (out int length,[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] out double[] array);

int theSize;
double[] theArray;
getArray(out theSize, out theArray);

如果我省略了关于数组的代码,int传递就好了.所以我相信这个方法是正确的,它只是绕过缺乏CoTaskMemAlloc.

解决方法:

您应该能够使用malloc在XCode中分配内存,并使用Marshal.FreeCoTaskMem在C#中释放它.但是,为了能够释放它,你需要有它的IntPtr:

C代码

extern "C" ABA_API void getArray(long* len, double **data)
{
    *len = delArray.size();
    auto size = (*len)*sizeof(double);
    *data = static_cast<double*>(malloc(size));
    memcpy(*data, delArray.data(), size);
}

C#代码

[DllImport("AudioPluginSpecDelay")]
private static extern void getArray(out int length, out IntPtr array);

int theSize;
IntPtr theArrayPtr;
double[] theArray;

getArray(out theSize, out theArrayPtr);
Marshal.copy(theArrayPtr, theArray, 0, theSize);
Marshal.FreeCoTaskMem(theArrayPtr);

// theArray is a valid managed object while the native array is already freed

编辑

Memory Management开始,我收集到Marshal.FreeCoTaskMem最有可能使用free()实现,因此拟合分配器将是malloc().

有两种方法可以确定:

>使用Marshal.AllocCoTaskMem在CLI中分配内存,将其传递给native以使其填充,然后使用Marshal.FreeCoTaskMem再次在CLI中释放它.
>保持原样(本机使用malloc()分配内存),但不要在CLI中释放内存.相反,拥有另一个本机函数,如freeArray(double ** data),并在使用它完成CLI后为它释放free()数组.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐