将复杂结构编组为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做些什么,但我真的不知道到底是什么错误。
我已经告诉过你了。你不能用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;
}
}
}
}