从 C++ 到 C# 的 P/Invoking int[] 显示随机大数而不是原始数组成员
Posted
技术标签:
【中文标题】从 C++ 到 C# 的 P/Invoking int[] 显示随机大数而不是原始数组成员【英文标题】:P/Invoking int[] from c++ to C# shows random large numbers instead of original array members 【发布时间】:2019-05-17 03:53:49 【问题描述】:我有以下 c++ 代码:
int nCount[5] = 0, 1, 2, 3, 4;
return &nCount[0];
我在 C# P/Invoke 层收到此代码,代码如下:
[DllImport(@"/sharedlibrary.so",CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr read_array_adapter();
效果很好。但是当我在下面运行 c# 代码时:
int[] result = new int[5];
Marshal.Copy(ptr, result, 0, 5);
它用一些随机大数填充数组结果,如下所示:
int[]1663918692,1852139884,1970351988,1936417641,244554078
这与我在 C++ 中的原始数组无关,看起来像 0,1,2,3,4 知道Marshal.Copy
可能会做什么来填充这些结果吗?
【问题讨论】:
int nCount[5] = 0, 1, 2, 3, 4; return &nCount[0];
-- 如果nCount
是局部变量,这将不起作用。您应该指定声明该数组的位置,因为这比您想象的要多得多。
它是一个局部函数变量。我应该怎样才能获得真正的价值观?
好吧,让数组全局化。在 C++ 中返回局部变量的地址是未定义的行为。
见***.com/questions/6441218/…
您还需要指定该数组的意图。很难相信它只存在 5 个数字,0,1,2,3,4。心中必须有一个更大的计划。该计划将决定您要如何指定该数组的声明位置和方式。
【参考方案1】:
如果您希望内存在函数范围内存在,并且不想使用全局变量,那么您必须从堆栈以外的其他位置(局部变量)分配它。
您可以使用任何分配器,您可以使用 .NET 已经知道的分配器,或者如果您使用另一个特定于 C++ 或您的平台的分配器,那么您还必须提供另一个 P/Invokable 函数用于解除分配,如下所示:
C++
int* read_array_adapter()
int nCount[5] = 0, 1, 2, 3, 4;
return AllocateAndCopy(...);
void free_array_adapter(int *) // or a generic pointer of course...
Free(...);
C#
static void Main(string[] args)
var ptr = read_array_adapter();
var result = new int[5];
Marshal.Copy(ptr, result, 0, 5);
free_array_adapter(ptr);
[DllImport(@"/sharedlibrary.so",CallingConvention = CallingConvention.Cdecl)]
public extern static IntPtr read_array_adapter();
[DllImport(@"/sharedlibrary.so",CallingConvention = CallingConvention.Cdecl)]
public extern static void free_array_adapter(IntPtr ptr);
您也可以在 .NET 和 C/C++ 之间使用已知的分配器,但这取决于平台(Windows、linux 等):https://www.mono-project.com/docs/advanced/pinvoke/
这是一个使用 C 的 malloc/free duo 的示例实现:
int* read_array_adapter()
int nCount[5] = 0, 1, 2, 3, 4 ;
int* p = (int*)malloc(5 * 4);
memcpy(p, nCount, 5 * 4);
return p;
void free_array_adapter(void * ptr)
free(ptr);
【讨论】:
什么是''allocateAndCopy? 任何你能想到的分配(+复制)功能。 Free 将是它的释放部分。 你能给我举个例子来说明这个分配和复制函数的样子吗?我有点迷路了。此外,我尝试通过引用传递 IntPtr,希望它能够在调用中幸存下来,但它仍然以错误的值结束:( 任何分配器/释放器都可以。我已经用 malloc/free 更新了我的答案。 非常感谢。您提供的示例刚刚修复了它。真的是一堆。但是有一个问题,这对于可变大小的字符串是否足够安全?以上是关于从 C++ 到 C# 的 P/Invoking int[] 显示随机大数而不是原始数组成员的主要内容,如果未能解决你的问题,请参考以下文章