在 C++ 代码中,指针按值传递,因此无论函数设置它们指向什么地址,调用者都无法接收这些地址。为此,您需要按引用或按指针传递指针,例如:
extern "C" __attribute__ ((visibility ("default")))
void funcplugin(int* &corners, double* &points)
{
corners = new int[16];
points = new double[24];
//code to compute and populate array values
}
或者:
extern "C" __attribute__ ((visibility ("default")))
void funcplugin(int** corners, double** points)
{
*corners = new int[16];
*points = new double[24];
//code to compute and populate array values
}
此外,如果函数使用调用者无法直接访问的任何内存管理器(即,通过new[])分配数组,您将需要导出一个函数以使用相同的内存管理器释放数组(即,通过delete[]) 在调用者完成使用它们之后,例如:
例如:
extern "C" __attribute__ ((visibility ("default")))
void funcpluginfree(int* corners, double* points)
{
delete[] corners;
delete[] points;
}
然后在 C# 端,您可以这样做:
private int num_corners = 16;
private int num_points = 24;
[DllImport ("native")]
private static extern void funcplugin(out IntPtr corners, out IntPtr points);
[DllImport ("native")]
private static extern void funcpluginfree(IntPtr corners, IntPtr points);
void call
{
int[] first = new int[num_corners];
double[] second = new double[num_points];
IntPtr corners;
IntPtr points;
funcplugin(out corners, out points);
Marshal.Copy(corners, first, 0, num_corners);
Marshal.Copy(points, second, 0, num_points);
funcpluginfree(corners, points);
for (int i = 0; i < num_corners; i++)
{
Debug.Log("corners: " + first[i]);
}
for (int j = 0; j < num_points; j++)
{
Debug.Log("points " + second[j]);
}
}
现在,话虽这么说......
您的原始 C# 代码正在分配内存(但未分配足够的内存,顺便说一句)以传递给 C++ 代码以填充数据。在这种情况下,C++ 代码没有理由也分配自己的内存。所以,你可以在funcplugin()里面去掉new[],这样就不需要导出一个函数来调用delete[],例如:
C++
extern "C" __attribute__ ((visibility ("default")))
void funcplugin(int* corners, double* points)
{
//code to compute and populate array values
}
C#
private int num_corners = 16;
private int num_points = 24;
[DllImport ("native")]
private static extern void funcplugin(IntPtr corners, IntPtr points);
void call
{
int[] first = new int[num_corners];
double[] second = new double[num_points];
IntPtr corners = Marshal.AllocHGlobal(num_corners * sizeof(int));
IntPtr points = Marshal.AllocHGlobal(num_points * sizeof(double));
funcplugin(corners, points);
Marshal.Copy(corners, first, 0, num_corners);
Marshal.Copy(points, second, 0, num_points);
Marshal.FreeHGlobal(corners);
Marshal.FreeHGlobal(points);
for (int i = 0; i < num_corners; i++)
{
Debug.Log("corners: " + first[i]);
}
for (int j = 0; j < num_points; j++)
{
Debug.Log("points " + second[j]);
}
}
或者,正如cmets中提到的@Charlieface,您可以使用C#的原生array marshaling(也可以是see this)而不是手动分配内存,例如:
private int num_corners = 16;
private int num_points = 24;
[DllImport ("native")]
private static extern void funcplugin([In, Out] int[] corners, [In, Out] double[] points);
void call
{
int[] first = new int[num_corners];
double[] second = new double[num_points];
funcplugin(first, second);
for (int i = 0; i < num_corners; i++)
{
Debug.Log("corners: " + first[i]);
}
for (int j = 0; j < num_points; j++)
{
Debug.Log("points " + second[j]);
}
}