从C ++到C#的数组 [英] Array from C++ to C#

查看:66
本文介绍了从C ++到C#的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将一个双精度数组(实际上是一个std :: vector,但在传输时进行转换)从c ++ dll转换为c#脚本(统一). 使用此处 https://stackoverflow.com/a/31418775 概述的方法.

I am trying to pass a double array (its actually a std::vector, but converted at transfer) from a c++ dll into a c# script (unity). Using the approach outlined here https://stackoverflow.com/a/31418775.

我可以统一在控制台上成功获得阵列打印的大小,但是由于我使用的是Xcode,而且它似乎没有COM,因此我无法使用"CoTaskMemAlloc"为阵列分配内存.

I can successfully get the size of the array printing on my console in unity however I am not able to use "CoTaskMemAlloc" to allocate memory for the array since I am using Xcode and it doesnt seem to have COM.

对于更多背景知识,此数组是GUI控件的一部分,c ++创建它,用户使用c#GUI进行编辑-因此,计划是在编辑完数组后将其传递回c ++.

For a little more background this array is part of a control for a GUI, c++ creates it and the user edits with the c# GUI - so the plan is to be able to pass the array back to c++ when it has been edited.

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的不足.

If I leave out the code concerning the array, the int passes just fine. So I beleive the method to be the right one, its just getting around the lack of CoTaskMemAlloc.

推荐答案

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

You should be able to allocate memory in XCode using malloc and free it in C# using Marshal.FreeCoTaskMem. To be able to free it however, you need to have the IntPtr for it:

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

修改

内存管理中,我收集到了Marshal.FreeCoTaskMem将最有可能使用free()实现,因此合适的分配器将是malloc().

From Memory Management I gathered that Marshal.FreeCoTaskMem would most likely be implemented using free(), so the fitting allocator would be malloc().

有两种方法可以确保:

  1. 使用Marshal.AllocCoTaskMem在CLI中分配内存,将其传递给本机以进行填充,然后使用Marshal.FreeCoTaskMem在CLI中再次释放它.
  2. 保持原样(本机使用malloc()分配内存),但不要在CLI中释放内存.取而代之的是,拥有另一个freeArray(double **data)之类的本机函数,并在完成CLI使用后将其作为数组free()给您.
  1. Allocate the memory in CLI using Marshal.AllocCoTaskMem, pass it to native to have it filled, and then free it in the CLI again using Marshal.FreeCoTaskMem.
  2. Leave it as it is (native allocates memory with malloc()), but do not free the memory in CLI. Instead, have another native function like freeArray(double **data) and have it free() the array for you once CLI is done using it.

这篇关于从C ++到C#的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆