从 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]
属性不同,后者是一个编组提示。
您正在传递 0
和 bufferSize
,而 C# 正在获取它们的地址(文字 0
作为临时变量)并传递它们。
由于地址每次都不同,您得到的值不同。
删除 in
修饰符,以便 C# 传递这些值而不是地址。
【讨论】:
以上是关于从 C# 到 C++ 的调用无法正确传递参数的主要内容,如果未能解决你的问题,请参考以下文章
从 C++ 传递函数指针以由 C# 调用 - 函数参数包括宽字符字符串 (LPCWSTR)