How do I convert byte array to UInt32 array?
Lets say In C++ I got code like this..
void * target
uint32 * decPacket = (uint32 *)target;
So in C# it would be like..
byte[] target;
UInt32[] decPacket = (UInt32[])target;
开发者_Go百科Cannot convert type byte[] to uint[]
How do I convert this memory aligning thing C++ does to arrays to C#?
Well, something close would be to use Buffer.BlockCopy
:
uint[] decoded = new uint[target.Length / 4];
Buffer.BlockCopy(target, 0, decoded, 0, target.Length);
Note that the final argument to BlockCopy
is always the number of bytes to copy, regardless of the types you're copying.
You can't just treat a byte
array as a uint
array in C# (at least not in safe code; I don't know about in unsafe code) - but Buffer.BlockCopy
will splat the contents of the byte
array into the uint
array... leaving the results to be determined based on the endianness of the system. Personally I'm not a fan of this approach - it leaves the code rather prone to errors when you move to a system with a different memory layout. I prefer to be explicit in my protocol. Hopefully it'll help you in this case though.
You can have the cake (avoid allocations) and eat it too (avoid iterations), if you're willing to move to the dark side.
Check out my answer to a related question, in which I demonstrate how to convert float[] to byte[] and vice versa: What is the fastest way to convert a float[] to a byte[]?
As Jon mentioned, Buffer.BlockCopy will work well for copying this.
However, if this is an interop scenario, and you want to access the byte array directly as uint[]
, the closest you can do is to the C++ approach would be to use unsafe code:
byte[] target;
CallInteropMethod(ref target);
fixed(byte* t = target)
{
uint* decPacket = (uint*)t;
// You can use decPacket here the same way you do in C++
}
I personally prefer making the copy, but if you need to avoid actually copying the data, this does allow you to work (in an unsafe context).
You can use Buffer.BlockCopy
. Rather than Array.Copy
, BlockCopy
does a byte-level copy without checking the array types are fully compatible.
Like so:
uint[] array = new uint[bytes.Length/4];
Buffer.BlockCopy(bytes, 0, array, 0, bytes.Length);
I used BitConverter.ToUInt32() - https://learn.microsoft.com/en-us/dotnet/api/system.bitconverter.touint32?view=netcore-3.1
byte[] source = new byte[n];
UInt32 destination;
destination = BitConverter.ToUInt32(source, 0);
It seems to work fine for me.
Years late but maybe this will help someone else. (It's also kind of new.)
We can do a c++ style reinterpret cast (sort of) using the new Span<> in .Net Core 2.1 or later. There are no heap memory allocations so it is very fast.
Span<byte> byteArray = MemoryMarshal.AsBytes<uint>(uIntArray);
// with span we can get a byte, set a byte, iterate, and more.
byte someByte = byteSpan[2];
byteSpan[2] = 33;
If byte[] is needed, as stated in the question, then the above can be taken one step further. (This would allocate memory and copy but it is still fast.)
byte[] byteArray = MemoryMarshal.AsBytes<uint>(uIntArray).ToArray();
Loop over all array items and call Convert.ToUint32() on each of them.Here:
Uint32[] res = new Uint32[target.Length];
for(int i = 0;i <= target.Length;i++)
{
res[i] = Convert.ToUint32(target[i]);
}
Here is an official link from MSDN. http://msdn.microsoft.com/en-us/library/469cwstk.aspx
精彩评论