Как использовать C struct с 2D-массивом в C# Unity

Итак, у меня есть API C со следующей структурой

typedef struct mat4f_ { float m[4][4]; } mat4f;

передается в качестве параметра одной из моих функций API:

void myFunction(const mat4f matrix);

я экспортирую эту функцию в C# в Unity с помощью dll:

[DllImport ("mylib")] 
private static extern void myFunction(mat4f matrix);

мой вопрос:что я должен сделать соответствующей структурой C#?

прямо сейчас у меня есть следующее:

[StructLayout(LayoutKind.Sequential)]
public struct mat4f
{
    public float[,] m;
}

и использовать попробуйте использовать функцию следующим образом:

//Just make an identity matrix
mat4f matrix; 
matrix.m = new float[4, 4] { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };

myFunction(matrix); //Call dll function

это правильно? Есть ли лучший способ сделать это?

2 ответов


для матрицы 4×4 Вы можете использовать UnityEngine.Matrix4x4. Если вы хотите использовать свою собственную структуру, я рекомендую вам реализовать ее так же UnityEngine.Matrix4x4 реализуется:

[StructLayout(LayoutKind.Sequential)]
public struct mat4f
{
    public float m00;
    public float m01;
    public float m02;
    public float m03;
    public float m10;
    public float m11;
    public float m12;
    public float m13;
    public float m20;
    public float m21;
    public float m22;
    public float m23;
    public float m30;
    public float m31;
    public float m32;
    public float m33;

    public static mat4f Identity = new mat4f
    {
        m11 = 1.0f,
        m22 = 1.0f,
        m33 = 1.0f,
        m44 = 1.0f
    };
}

это blittable тип. Непреобразуемые типы не требуется преобразование, когда они передаются между управляемым и неуправляемым кодом.

пример использования:

mat4f matrix = mat4f.Identity;
myFunction(matrix);  // Call DLL function

существующими реализациями похожи на тот, который я представленный выше.


передача структуры C# импортированной функции, как вы это делаете, допустима, но вы должны указать длину массива в структуре, даже если позже вы укажете его размер.

объявление c в основном определяет массив длины 16, поэтому я бы указал структуру c# следующим образом:

[StructLayout(LayoutKind.Sequential)]
public struct mat4f
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public float[,] m;
}

вы можете узнать больше о том, как массивы-это упорядоченные здесь.