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

Passing byte array from C# to C++ DLL as char*

我正在将 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*,但大多数stream 在 C++ 中适用于 char* 而不是 unsigned char*

我想问一下

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

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

实际上,char *unsigned char * 类型大小不是 1 个字节,而是 4 个字节,假设我们谈论的是 win32 应用程序:这些是指针,所有指针都有无论指向的数据大小如何,大小都相同。

当 P/Invoke 机制将 "simple values" 的数组视为函数参数时,它会愉快地将指向数组开头的指针提供给下面的 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)进行一些数学运算,传递它在 C 端,预期 char 值(-128 到 127) 做更多的数学运算,可能会出错。如果它只是将它用作一种移动数据的方式,那就没问题了。