6

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#?

2

7 Answers 7

14

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.

Sign up to request clarification or add additional context in comments.

2 Comments

helped in my case yup. Seems in C++ it never copy's anything though.. it just realigns from byte scan to two bytes at once. Atleast this solution avoids me using loops to do this process.
In unsafe code, you can sort of do it - you can fix the array and use pointer math to iterate through the byte array as uint pointers directly. It works well, but it's basically reverting to a C/C++/native approach...
2

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

Comments

1

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

5 Comments

wow awesome!.. I'll have to try this out! what is? CallInteropMethod
@SSpoke: C#, in an unsafe context, can act very much like C++ - and get all that pointer goodness/nastiness back ;)
The CallInteropMethod was just saying "this is something to fill in the byte[]" - normally, this wouldn't be used in pure managed code...
Blah I thought about it.. and I was sick of C++.. that's why I am porting this to .NET.. so I'll keep it strictly C#.. without any unsafe code. (Honestly I am very confused :P I have to wrap all the brackets around all my logic? then I also have encPacket which also is bytes -> uint32 blah too complicated hehe
@SSpoke: Good call (unless this is perf. critical code) - I'd typically avoid this in all situations except those where I've profiled and discovered it's very, very difficult to handle otherwise without major implications.
1

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.

Comments

0

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

2 Comments

I am pretty sure if you do this, you will get an exception. "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection"
Why? The length to the argument to BlockCopy is specified in bytes.
0

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

1 Comment

This converts the array the other way around. The original question was about converting FROM byte array TO uint array.
-1

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

4 Comments

will this even work? it will create as much UInt32's are there is byte's.. I have to make 2 bytes into 1 uint though.
I think new Uint32[target.length] has to be new Uint32[target.length / sizeof(UInt32)]
This requires using BitConverter if you want to loop. This will give you a unit with the value of the individual byte - which is very different...
Feel free to edit if you are sure that that is correct @SSpoke.I am always open for people willing to fix my mistakes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.