【问题标题】:Pass an array parameter to a C++ DLL from C#从 C# 将数组参数传递给 C++ DLL
【发布时间】:2021-01-29 01:04:17
【问题描述】:

我正在尝试将一个双精度数组传递给从 C++ DLL 导入到 C# 的函数。 该函数在 C++ DLL 中如下所示(使用调用约定 cdecl):

__declspec(dllexport) void FunctionToImport(void* values, size_t numberOfValues, const char* someString);

这里是 C# 中的导入:

[DllImport("DLLToImport.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern void FunctionToImport(IntPtr values, int numberOfValues, string someString);

以这种方式从 C# 调用时:

double[] bytes = { 1.0, 2.0, 3.0, 4.0 };

IntPtr testvalues = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, testvalues, bytes.Length);

CSharpClass.FunctionToImport(testvalues, Marshal.SizeOf(testvalues), "someString";

Marshal.FreeHGlobal(testvalues);

我收到 AccessViolationException,有时程序会崩溃。

将一个 size_t 模拟量的数组传递给库的正确方法是什么?

【问题讨论】:

  • 第一个参数是 IntPtr[]。数组元素应该指向什么(如果有的话)是完全不明显的。展示一些示例 C/C++ 代码,这些代码使用此函数来获得您需要的帮助。

标签: c# c++ pinvoke marshalling dllimport


【解决方案1】:

我收到 AccessViolationException,有时程序会崩溃。

你得到一个例外,因为 bytes.Length 是 4,但你实际上需要分配 4*sizeof(double) 字节的内存。您将数组中的元素数量与需要分配的内存量混淆了。此外, Marshal.Sizeof(values) 将为您提供 IntPtr 的大小,而我认为您需要元素的数量。此外,C 方法签名使这一点令人困惑:如果它需要一个双精度数组,为什么参数 void *[] 而不是 double[] 或 double *?您的 C# 数组名为“bytes”,但其中包含双精度数,这也让我质疑 C 代码期望的类型。这种 void 类型不会与第二个参数“numberOfValues”混为一谈,因为通常情况下,如果某些东西需要一个 void * 它想知道字节数而不是值的数量。所以我认为 API 也存在一些不明确的地方。

[DllImport("DLLToImport.dll", CallingConvention = CallingConvention.Cdecl)] 公共静态外部无效 FunctionToImport(IntPtr 值,int numberOfValues,字符串 一些字符串); 如果您修复上述问题以便分配和复制正确数量的内存,这可能会起作用,但这是一种艰难的方式。相反,让 P/Invoke 为您执行编组。尝试类似:

[DllImport("DLLToImport.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern void FunctionToImport(double[] values, int numberOfValues, string someString);

这简化了很多。现在您可以像调用 C# 函数一样调用此方法: 双重的

double[] numbers = { 1.0, 2.0, 3.0, 4.0 };
FunctionToImport(numbers, numbers.Length, "someString");

有时您需要使用 Marshal,但我怀疑这不是其中之一。

【讨论】:

  • 我想你忽略了C函数接受一个双指针(一个数组,其中每个数组元素都是一个void*
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 2021-07-18
相关资源
最近更新 更多