Jump to content
  • Advertisement
rogerdv

C# fill fixed byte with values

Recommended Posts

Im doing some tests with new Unity3d networking APi and Im moving from sending integers to sending more complex stuff, like coordinates (3 floats). The problem is that Im forced to use fixed byte as the data container for my packets (byte[] doesnt works, must be unmanaged and blittable) and I havent found a way to put my values (floats, strings, etc) into that array of bytes and also get them back. How can I do this?

Share this post


Link to post
Share on other sites
Advertisement

I don't know the answer, as I'm not up to date with Unity and am not sure what features are available there.

I did find a couple threads that might (or might not) be relevant (the information may be out of date though - the threads are a few years old):

1
2

Also, it sounds like you've already figured out how to serialize integers (which I assume doesn't mean only bytes). How are you doing that? It seems like the solution for other types (e.g. floats) could be related.

Share this post


Link to post
Share on other sites

You do 'fixed' stuff like you do in C; LIKE A BOSS.

public unsafe void Foo()
{
    byte[] array = new byte[1024]; // for example; I assume you get your byte* from elsewhere.

    fixed (byte* ptr = array)
    {
        int* i = (int*)ptr; // cast pointer types to whatever you want
        // ^ you see that BLASPHEMY with the asterisk associated with the int?
        // That's different than C: int *i

        *i = 0x12345678;

        // moving the pointer works the same as C - advancing by the data type's size.
        // if you want to mix types, keep a byte* around to position things correctly.
        i++;

        *i = 0x23456789;

        // getting things back out is the same.
        int value = *i;  // value is now 0x23456789
        --i;
        int value2 = *i; // value2 becomes 0x12345678
    }

    // array is now 78 56 34 12 89 67 45 23 00 00 00 ......
}

You can also use the Marshal class to be (slightly) less of a BOSS.

Edited by Nypyren

Share this post


Link to post
Share on other sites

Involving unsafe what is your necesity quoting

On 9/17/2019 at 7:25 PM, rogerdv said:

(byte[] doesnt works, must be unmanaged and blittable)

It will cut out the entire memory outside of Garbace Colector (the GC) untill you return it under management, you would better copy the memory as advised with Bit Converter and "unsafe" the copy to unmanaged modules, then you are set good smooth.

Share this post


Link to post
Share on other sites
On 9/17/2019 at 5:00 PM, Zakwayda said:

I don't know the answer, as I'm not up to date with Unity and am not sure what features are available there.

I did find a couple threads that might (or might not) be relevant (the information may be out of date though - the threads are a few years old):

1
2

Also, it sounds like you've already figured out how to serialize integers (which I assume doesn't mean only bytes). How are you doing that? It seems like the solution for other types (e.g. floats) could be related.

By using DataStreamWriter, it can write ints or floats. The thing gets complicated when I want to write a series of floats, or an int+float+float+float, etc, to build an useful data packet.

17 hours ago, Endurion said:

In regular C# BitConverter is what you're looking for, I don't know if it's available in Unity though:

 

https://docs.microsoft.com/de-de/dotnet/api/system.bitconverter?view=netframework-4.8

It is, but it is not compatible with fixed byte.

Share this post


Link to post
Share on other sites
3 minutes ago, rogerdv said:

By using DataStreamWriter, it can write ints or floats. The thing gets complicated when I want to write a series of floats, or an int+float+float+float, etc, to build an useful data packet.

Apologies if I'm missing the obvious, but can you just write and read the ints/floats/etc. in sequence? (One of the threads I linked to suggests serializing vectors in this way.)

Share this post


Link to post
Share on other sites

Ok, as I expected, I had to change my design. The problem came mostly from the fact that the gae uses  new Unity threading system. I wanted to send a list of possible commands from my main thread on each Update() iteration, to the thread sending and receiving network data. That required using a NativeList or a NativeArray of the commands struct, which I wanted to contain the command code, length and the actual packet data. Also, the network thread should return a similar list of commands received from the server. Seems it is impossible, or my knowledge is not enough to do it. I had to change my approach to send only one command per frame. So, I can build the packet data inside a byte[] and copy it to a NativeArray<byte>, which I pass separately to the network thread (it is done that way in the Unity sample, though they simply fill the byte[] array with random values).

The other solution was to change the client architecture from multithreaded to single threaded, but as anyway I must code the server as multithreaded, I would face the problem eventually anyway. Thanks to all of you for your invaluable help!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!