将复杂结构编组为c#

本文关键字:复杂 结构 | 更新日期: 2023-09-27 17:50:45

我仍然在努力将一个相当复杂的结构从c++编组到c#。

c++中的结构如下:

typedef struct {
    DWORD Flags;                    
    DWORD TimeCode;                 
    DWORD NodeMoving;   
    Matrix NodeRots[NUM_GYROS];
    Vector Position;                
    DWORD ContactPoints;            
    float channel[NUM_CHANNELS];
} Frame;
向量:

typedef struct {
    union {
        struct {
            float x, y, z;
        };
        float Array[3];
    };
} Vector;
矩阵:

typedef struct {
    union {
        struct {
            float xx, xy, xz;       //This row is the right vector
            float yx, yy, yz;       //This row is the up vector
            float zx, zy, zz;       //This row is the forward vector
        };
        float Array[3][3];          //[row][col]
    };
} Matrix;

下面是我在c#中的代码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct Matrix
    {
        public float xx;
        public float xy;
        public float xz;
        public float yx;
        public float yy;
        public float yz;
        public float zx;
        public float zy;
        public float zz;    
    }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct Vector{
        public float x;
        public float y;
        public float z; 
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct Frame{
        public uint Flags;                  
        public uint TimeCode;                   
        public uint NodeMoving;             
        public fixed byte NodeRots[NUM_GYROS];
        public Vector Position;             
        public uint ContactPoints;          
        public fixed float channel[CHANNEL_ARRAY_SIZE];

        public unsafe float[] Channel
        {
            get
            {
                fixed (float* ptr = channel)
                {
                    float[] array = new float[CHANNEL_ARRAY_SIZE];
                    Marshal.Copy((IntPtr)ptr, array, 0, CHANNEL_ARRAY_SIZE);
                    return array;
                }
            }
        }
        public unsafe Matrix[] nodeRots{
            get{
                fixed (byte* ptr = NodeRots){
                    IntPtr ptr2 = (IntPtr)ptr;
                    Matrix[] array = new Matrix[NUM_GYROS];
                    for (int i = 0; i < array.Length; i++)
                    {
                        array[i] = (Matrix)Marshal.PtrToStructure(ptr2, typeof(Matrix));
                        IntPtr oldptr = ptr2;
                        ptr2 = new IntPtr(oldptr.ToInt32() + Marshal.SizeOf(typeof(Matrix)));
                    }
                    return array;
                }
            }
        }

帧结构的Flags, TimeCode, NodeMoving和NodeRots的值已经正确传递。成员位置、接触点和通道没有正确编组。我想我必须对Position Member做些什么,但我真的不知道到底是什么错误。

将复杂结构编组为c#

我已经告诉过你了。你不能用fixed byte作为问题的通用解决方案。

public fixed byte NodeRots[NUM_GYROS];
必须

public fixed Matrix NodeRots[NUM_GYROS];
然后

:

Marshal.Copy((IntPtr)ptr, array, 0, CHANNEL_ARRAY_SIZE)
必须

Marshal.Copy((IntPtr)ptr, array, 0, CHANNEL_ARRAY_SIZE * sizeof(float));

对于nodeRots getter,你并不需要Marshal.PtrToStructure,因为你的结构可以直接封送。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public unsafe struct Frame
{
    public uint Flags;
    public uint TimeCode;
    public uint NodeMoving;
    public fixed float nodeRots[NUM_GYROS * 9];
    public Vector Position;
    public uint ContactPoints;
    public fixed float channel[CHANNEL_ARRAY_SIZE];
    public unsafe float[] Channel
    {
        get
        {
            fixed (float* ptr = channel)
            {
                float[] array = new float[CHANNEL_ARRAY_SIZE];
                Marshal.Copy((IntPtr)ptr, array, 0, CHANNEL_ARRAY_SIZE * sizeof(float));
                return array;
            }
        }
    }
    public unsafe Matrix[] NodeRots
    {
        get
        {
            fixed (float* ptr = nodeRots)
            {
                Matrix[] array = new Matrix[NUM_GYROS];
                for (int i = 0, y = 0; i < array.Length; i++, y += 9)
                {
                    array[i].xx = ptr[y + 0];
                    array[i].xy = ptr[y + 1];
                    array[i].xz = ptr[y + 2];
                    array[i].yx = ptr[y + 3];
                    array[i].yy = ptr[y + 4];
                    array[i].yz = ptr[y + 5];
                    array[i].zx = ptr[y + 6];
                    array[i].zy = ptr[y + 7];
                    array[i].zz = ptr[y + 8];
                }
                return array;
            }
        }
    }
}