将字节数组从 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 char
和 char
之间的区别所在:如果在 C# 大小上对 byte
值(范围 0-255)进行一些数学运算,则将其传递到 char
的 C 端预期值(-128 到 127)
做更多的数学运算,可能会出错。如果它只是将其用作移动数据的一种方式,那一切都很好。
【讨论】:
以上是关于将字节数组从 C# 传递到 C++ DLL 作为 char*的主要内容,如果未能解决你的问题,请参考以下文章