以char *将字节数组从C#传递到C ++ DLL [英] Passing byte array from C# to C++ DLL as char*
问题描述
我正在将byte[]
从C#传递到C ++ DLL
I am passing a byte[]
from C# to C++ DLL
在C ++ DLL中,我需要调用一个接受并读取istream
对象的函数,我打算以char*
的形式从C#接收byte[]
并将其转换为istream
,
Inside the C++ DLL, I need to call a function which accept and read istream
object, I intend to receive the byte[]
from C# as char*
and convert it to 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*
Although it seems to work fine, I find that the equivalent data type of byte[]
is unsigned char*
in C++, I thought of changing to unsigned char*
but most stream
in C++ works on char*
not unsigned char*
我想问
1)数据类型char*
和unsigned char*
均为1字节,后面发生了什么?如果我继续将byte[]
与char*
一起使用,是否有任何潜在的问题?
1) Both data type char*
and unsigned char*
are 1 byte, what happened behind? Is there any potential problem if I keep using byte[]
with char*
?
2)如果出现任何问题,我应该如何使用unsigned char*
构造一个istream
对象?
2) In case there is any problem, how should I use unsigned char*
to construct an istream
object?
推荐答案
实际上,假设我们在谈论Win32应用程序,char *
和unsigned char *
类型的大小不是1个字节,而是4个字节.是指针,并且无论所指向的数据大小如何,所有指针的大小都相同.
Actually, the char *
and unsigned char *
type sizes are not 1 byte, but rather 4-bytes, assuming we are talking about a win32 application : those are pointers, and all pointers have the same size regardless of the size of the data being pointed at.
当P/Invoke机制将简单值"数组视为函数参数时,它会很高兴地将指向数组开头的指针馈送到下方的C函数.毕竟,真的从DLL的信息中了解C函数的全部地方就是其代码的开始位置.据我所知,参数的数量和类型未编码在符号名称中,因此它信任您提供的信息.这意味着即使您向它提供了一个int
数组,对C函数的实际调用也可以正常工作,因为压入堆栈的参数的大小(指针和int)与该函数的ABI匹配.当然,由于尺寸不匹配,处理可能会出错.
When the P/Invoke mechanism sees an array of "simple values" as a function argument, it happily feeds a pointer to the start of the array to the C function underneath. After all, all it really knows about the C function from the info in the DLL is where its code starts. As far as I know, the number and type of arguments is not encoded in the symbol name, so it trusts the info you provided. Which means that even if you'd fed it an int
array, the actual call to the C function would have worked, as the size of the arguments pushed on the stack (a pointer and an int) match the ABI of the function. Of course the processing would have probably been wrong as the size wouldn't have matched.
另请参见 https://msdn. microsoft.com/en-us/library/75dwhxf7(v=vs.110).aspx 有关发生的情况的更多详细信息.
See also https://msdn.microsoft.com/en-us/library/75dwhxf7(v=vs.110).aspx for more details about what happens.
处理是unsigned char
和char
之间的区别所在:如果在C#大小上,您对byte
值(范围为0-255)进行了一些数学运算,则将其传递到C侧,在char
预期值(-128至127)
再做一些数学运算,可能会出问题.如果只是使用它作为移动数据的方式,那一切都很好.
Processing is where the difference between unsigned char
and char
comes : if on the C# size you do some math on the byte
values (ranging 0-255), pass it on the C side where char
values (-128 to 127) are expected
to do some more math, something could go wrong. If it just uses it as a way to move data around, it's all fine.
这篇关于以char *将字节数组从C#传递到C ++ DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!