Search Unity

Showcase how to convert byte array to nativearray<byte> and vice versa ?

Discussion in 'Unity Transport' started by mohammadrezah, Jul 19, 2021.

  1. mohammadrezah

    mohammadrezah

    Joined:
    Jul 12, 2021
    Posts:
    3
    hello
    I want to send byte array from server to client with unity transport . how do I do this?



    Code (CSharp):
    1.          NetworkPipeline pipline = ServerCode._UnreliablePipline;
    2.             if (ServerCode.m_serverDrive.BeginSend(pipline, clientlistener.m_connections, out var sendData) == 0)
    3.             {
    4.                 sendData.WriteBytes(bytearray);
    5.                 ServerCode.m_serverDrive.EndSend(sendData);
    6.  
    7.             }

    Error :


    [I]Argument 1: cannot convert from 'byte[]' to 'Unity.Collections.NativeArray<byte>'[/I]
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,411
  3. mohammadrezah

    mohammadrezah

    Joined:
    Jul 12, 2021
    Posts:
    3
    I tried it and I faced with this error

    Code (CSharp):
    1.  
    2. NullReferenceException: Object reference not set to an instance of an object
    3. Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckReadAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at <24599fe2776145d58ab771516c063d56>:0)
    4. Unity.Collections.NativeList`1[T].get_Length () (at Library/PackageCache/com.unity.collections@0.17.0-preview.18/Unity.Collections/NativeList.cs:223)
    5.  
     
  4. mohammadrezah

    mohammadrezah

    Joined:
    Jul 12, 2021
    Posts:
    3
    I solved my problem with this line code. but i got another error from this line.

    Code (CSharp):
    1.  
    2.  
    3. NativeArray<byte> NativebyteArray = new NativeArray<byte>(bytearray, Allocator.Persistent);
    4.  
    5.  
    6.    NetworkPipeline pipline = ServerCode._UnreliablePipline;
    7.             if (ServerCode.m_serverDrive.BeginSend(pipline, ServerCode.m_connections[i], out var sendData) == 0)
    8.             {
    9.                 sendData.WriteBytes(NativebyteArray);
    10.                 ServerCode.m_serverDrive.EndSend(sendData);
    11.      
    12.             }
    13.  
    14.  
    error:


    Code (CSharp):
    1. A Native Collection has not been disposed, resulting in a memory leak. Allocated from:
    2. Unity.Collections.NativeArray`1:.ctor(Byte[], Allocator)
     
    Last edited: Jul 19, 2021
  5. luke-unity

    luke-unity

    Joined:
    Sep 30, 2020
    Posts:
    306
    After `EndSend` call `Dispose` on the native array. Also you probably want to use `Allocator.Temp` here instead of `Persistent`.
     
  6. andrews_unity

    andrews_unity

    Unity Technologies

    Joined:
    Dec 11, 2015
    Posts:
    264
    Also Allocator.Temp is faster here so I would as @luke-unity mention recommend using it but it should be kept around for longer than a frame.
     
  7. NemanjaPavlovic

    NemanjaPavlovic

    Joined:
    Feb 25, 2022
    Posts:
    7
    So can we call Dispose on array that is allocated with persistent tag ? I don't think so ...
     
  8. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Yes, you can (and really should) call
    Dispose
    on native arrays that were allocated persistently.

    Persistent allocations are basically acquiring memory from the heap (think
    malloc
    if you've ever programmed in C). If you don't dispose of it after you don't need it anymore, it will stay there and keep using resources for nothing. I'm guessing the "persistent" name was chosen because the memory allocation will persist across jobs and frames.
     
  9. NemanjaPavlovic

    NemanjaPavlovic

    Joined:
    Feb 25, 2022
    Posts:
    7
    Yes, but if I try I got this error all the time :InvalidOperationException: The Unity.Collections.NativeArray`1[System.Byte] has been set to undisposable and cannot be deallocated.

    this is how its init : _data = new NativeArray<byte>(_rt.height * _rt.width * 4, Allocator.Persistent);

    if i do next OnDestroy()
    {
    _data.Dispose();
    }

    I have error saying that this is not possible ,
     
    Last edited: Aug 17, 2022
  10. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    441
    Are you perhaps using this native array with
    AsyncGPUReadback.RequestIntoNativeArray
    ? There are reports of issues when doing that. Or maybe you're passing it to a job and the job hasn't been properly completed when you try to dispose of it?
     
  11. NemanjaPavlovic

    NemanjaPavlovic

    Joined:
    Feb 25, 2022
    Posts:
    7
    yes I use it with AsyncGPUReadback.RequestIntoNativeArray ,and from it i pass it to a job , so Async feeds data to a array than i pass it to a job to work on it ( encode it to a PNG ) .
     
  12. NemanjaPavlovic

    NemanjaPavlovic

    Joined:
    Feb 25, 2022
    Posts:
    7
    Yes , GPU readback is holding nativeArray is need with it before I call destroy on object . Now its solved thank you for assistance and help.
     
  13. cwidisgroup

    cwidisgroup

    Joined:
    Sep 12, 2022
    Posts:
    2
    if (byteArray.Length != 0) byteArray.Dispose();
    byteArray = new Unity.Collections.NativeArray<byte>(currentSize, Unity.Collections.Allocator.Persistent);
    Hello, I am new to Unity and C#, but I feel I face the same probelm. If my byteAaary is created like this, how can I dispose of it?

    This is my error message:(Cwipc is a point cloud reader and renderer, in the form of a unity package)
    A Native Collection has not been disposed, resulting in a memory leak. Allocated from:
    Unity.Collections.NativeArray`1:.ctor(Int32, Allocator, NativeArrayOptions)
    Cwipc.PrerecordedPointCloudReader:GetComputeBuffer(ComputeBuffer&) (at Library\PackageCache\nl.cwi.dis.cwipc@959f2f9bec\Runtime\Scripts\PrerecordedPointCloudReader.cs:98)
    Cwipc.PointCloudRenderer:LateUpdate() (at Library\PackageCache\nl.cwi.dis.cwipc@959f2f9bec\Runtime\Scripts\PointCloudRenderer.cs:150)