从 C# 到 C++ 的调用无法正确传递参数

Posted

技术标签:

【中文标题】从 C# 到 C++ 的调用无法正确传递参数【英文标题】:Call from C# to C++ fails to pass parameters correctly 【发布时间】:2020-12-14 20:06:55 【问题描述】:

我有一个从 C# 到 C++ 的非常基本的调用。函数调用需要三个参数:

extern "C" int CLIENT_API example(const char, char * const, const unsigned int);

C# 代码将该函数导入为:

[DllImport("my.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int example(in sbyte id, byte[] buffer, in uint bufferSize);

当我像这样从 C# 调用函数时:

uint bufferSize = 400;
byte[] buffer = new byte[bufferSize];
example(0, buffer, bufferSize);

我记录了 id 和 bufferSize 的 C++ 大小变量值(对于这两个变量,每次运行都有不同的值)。我究竟做错了什么?我有其他互操作函数将指针和字符串传递给我的 C++ DLL,它们没有任何问题。似乎它只发生在更原始的 byte 和 uint 类型中。

【问题讨论】:

不要不要在 pinvoke 声明中使用in,这是纯粹的 C# hackorama 来伪装指针。来自 Roslyn 团队的可怕 hack,与从 C++ 到 C# 的编译性能作斗争。您看到的值看起来是随机的,因为传递的实际值(指针)是不可预测的。只需删除in 【参考方案1】:

in 修饰符使参数成为只读的 ref 参数。它与[In] 属性不同,后者是一个编组提示。

您正在传递 0bufferSize,而 C# 正在获取它们的地址(文字 0 作为临时变量)并传递它们。

由于地址每次都不同,您得到的值不同。

删除 in 修饰符,以便 C# 传递这些值而不是地址。

【讨论】:

以上是关于从 C# 到 C++ 的调用无法正确传递参数的主要内容,如果未能解决你的问题,请参考以下文章

从 C++ 传递函数指针以由 C# 调用 - 函数参数包括宽字符字符串 (LPCWSTR)

将参数从 C 传递到 Embedded Mono

C++ 将字符串传递到 C# dll

将回调参数从 C# 传递到非托管 C++

如何将委托或函数指针从 C# 传递到 C++ 并使用 InternalCall 调用它

将结构数组从 C# 传递到 C++