将字节数组从 C# 传递到 C++ DLL 作为 char*

Posted

技术标签:

【中文标题】将字节数组从 C# 传递到 C++ DLL 作为 char*【英文标题】:Passing byte array from C# to C++ DLL as char* 【发布时间】:2017-02-14 04:54:40 【问题描述】:

我将 byte[] 从 C# 传递到 C++ DLL

在 C++ DLL 中,我需要调用一个接受和读取 istream 对象的函数,我打算从 C# 接收 byte[] 作为 char* 并将其转换为 istream

C++ DLL

extern "C" _declspec(dllexport) bool CheckData(char* data, int dataLength)

C#

[DllImport("example.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CheckData(byte[] incoming, int size);

public void Process(byte[] bytes)

    CheckData(bytes, bytes.Length);

虽然看起来工作正常,但我发现 byte[] 的等效数据类型在 C++ 中是 unsigned char*,我想改成 unsigned char* 但 C++ 中的大多数 stream 适用于 char* 而不是 @ 987654333@

我想问

1)char*unsigned char*的数据类型都是1字节,后面发生了什么?如果我继续使用byte[]char*,会不会有任何潜在问题?

2) 万一出现问题,我应该如何使用unsigned char*来构造istream对象?

【问题讨论】:

拥有它就可以了。 你知道后面发生了什么吗?我想了解发生了什么 什么都没有发生。实际上有一个重新解释演员表。 【参考方案1】:

实际上,char *unsigned char * 类型的大小不是 1 字节,而是 4 字节,假设我们正在讨论一个 win32 应用程序:它们是指针,并且所有指针的大小都相同,无论大小指向的数据。

当 P/Invoke 机制将“简单值”数组视为函数参数时,它会愉快地将指向数组开头的指针提供给下面的 C 函数。毕竟,它真正从 DLL 中的信息中知道的关于 C 函数的所有信息都是它的代码开始的地方。据我所知,参数的数量和类型未编码在符号名称中,因此它信任您提供的信息。这意味着即使你给它一个 int 数组,对 C 函数的实际调用也会起作用,因为压入堆栈的参数的大小(指针和 int)与函数的 ABI 匹配.当然,处理可能是错误的,因为大小不匹配。

另请参阅https://msdn.microsoft.com/en-us/library/75dwhxf7(v=vs.110).aspx,了解更多详情。

处理是 unsigned charchar 之间的区别所在:如果在 C# 大小上对 byte 值(范围 0-255)进行一些数学运算,则将其传递到 char 的 C 端预期值(-128 到 127) 做更多的数学运算,可能会出错。如果它只是将其用作移动数据的一种方式,那一切都很好。

【讨论】:

以上是关于将字节数组从 C# 传递到 C++ DLL 作为 char*的主要内容,如果未能解决你的问题,请参考以下文章

如何通过引用从 c# 到 c++ 传递字节数组

将字节数组从 c++ 传递到 c#(单声道)

将字节数组从 c++ 传递到 c# 程序集都有哪些不同的方法?

将字节数组从 Unity C# 传递到 C++ 库方法

将 C# 3D 数组作为 1D 字节数组传递给 C++ 库

将复杂的结构(带有结构的内部数组)从 C# 传递到 C++