1

Using the NetworkInfo2SecurityParameter function I am trying to copy the fixed-size buffer unkRandom from from LdnNetworkInfo struct held in NetworkInfo struct to the SecurityParameter struct's buffer.

Basically I am making a method to convert these two types, and I want to copy these two arrays to another. This code features all structs relevant.

The error is happening at the Buffer.MemoryCopy() function. The error is "You cannot use fixed size buffers contained in unfixed expressions. Try using the 'fixed' statement"

unsafe void NetworkInfo2SecurityParameter(NetworkInfo info, out SecurityParameter output)
{
    output = new SecurityParameter();
    output.sessionId = info.networkId.sessionId;
    Buffer.MemoryCopy(output.unkRandom, info.ldn.unkRandom, 16, 16);
}

struct SecurityParameter {
    public unsafe fixed byte unkRandom[16];// = new byte[16];
    public SessionId sessionId;
};

struct NetworkInfo : /sf::/LargeData {
    public NetworkId networkId;
    public CommonNetworkInfo common;
    public LdnNetworkInfo ldn;
};

struct LdnNetworkInfo {
    public unsafe fixed byte unkRandom[16];// = new byte[16];
    public ushort securityMode;
    public byte stationAcceptPolicy;
    public unsafe fixed byte _unk1[3];// = new byte[3];
    public byte nodeCountMax;
    public byte nodeCount;
    //TODO non primitive array,,
    private unsafe fixed byte _nodes[sizeof(NodeInfo)*NodeCountMax]; //Needs to be fixed array, and needs to be casted to NodeInfo span, so thats why its size is this
    public unsafe fixed Span<NodeInfo> nodes => MemoryMarshal.Cast<byte, NodeInfo>(MemoryMarshal.CreateSpan(ref _nodes[0], 128));
    public ushort _unk2;
    public ushort advertiseDataSize;
    public unsafe fixed byte advertiseData[AdvertiseDataSizeMax];// = new byte[AdvertiseDataSizeMax];
    public unsafe fixed byte _unk3[148];// = new byte[148];
};

7
  • What is the error? Commented May 5, 2020 at 12:08
  • You cannot use fixed size buffers contained in unfixed expressions. Try using the 'fixed' statement Commented May 5, 2020 at 12:09
  • 1
    Well, the obvious question is, have you tried using the fixed statement? Commented May 5, 2020 at 12:14
  • If the array is just 16 bytes, could you take a pointer to the array, cast it to a int64 pointer and copy it in two 64-bit chunks? Commented May 5, 2020 at 12:15
  • @HereticMonkey Where? Commented May 5, 2020 at 12:22

2 Answers 2

1

struct is assignable, like any primitive. Undoubtedly faster than Buffer.MemoryCopy() would be:

public unsafe struct FixedSizeBufferWrapper
{
    public unsafe fixed byte unkRandom[16];
}

unsafe 
{
    fixed (byte* firstStruct = somewhere.securityParameter, otherStruct = somewhereElse.ldnNetworkInfo )
    {
        //one assignment blits all contents
        *((FixedSizeBufferWrapper*)firstStruct.unkRandom) =
        *((FixedSizeBufferWrapper*)otherStruct.unkRandom);
    }
}

We cast buffers in each of your original structs to the wrapper pointer type and dereference each pointer SO THAT we can assign one to the other; assigning fixed buffers directly is not possible.

We have to cast outside the fixed statement because (at least in my version of C#) we aren't allowed to cast inside fixed(...) and we cannot assign anything other than a primitive type (usually byte[]) as the buffer type. The wrapper struct exists purely for this casting / assignment.

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

Comments

0

Fixed it with this approach: I created a new variable called ret, which I did copy the data to, and then I assigned ret to output.

unsafe void NetworkInfo2SecurityParameter(NetworkInfo info, out SecurityParameter output)
        {
            var ret = new SecurityParameter();
            output.sessionId = info.networkId.sessionId;
            Buffer.MemoryCopy(ret.unkRandom, info.ldn.unkRandom, 16, 16);
            output = ret;
        }

Comments

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.