SSpoke
SSpoke

Reputation: 5836

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;

Cannot convert type byte[] to uint[]

How do I convert this memory aligning thing C++ does to arrays to C#?

Upvotes: 6

Views: 19823

Answers (7)

SunsetQuest
SunsetQuest

Reputation: 8867

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();

Upvotes: 0

Alex Seceleanu
Alex Seceleanu

Reputation: 545

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.

Upvotes: 1

Omer Mor
Omer Mor

Reputation: 5216

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[]?

Upvotes: 2

Reed Copsey
Reed Copsey

Reputation: 564821

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).

Upvotes: 1

user744186
user744186

Reputation:

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

Upvotes: -1

thecoop
thecoop

Reputation: 46148

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);

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1503290

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.

Upvotes: 14

Related Questions