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

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

本文关键字:C++DLL char 字节数 字节 数组      更新时间:2023-10-16

我正在将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*上工作,而不是在unsigned char*上工作

我想问

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

2) 如果有任何问题,我应该如何使用unsigned char*来构造istream对象?

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

当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值(-128到127)的C侧再做一些数学运算,可能会出问题。如果它只是把它作为一种移动数据的方式,那一切都很好。