Как использовать 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
существующими реализациями похожи на тот, который я представленный выше.
-
матричная реализация Unity (декомпилированный; исходный код не предоставляется бесплатно!--10-->). См.
UnityEngine.Matrix4x4
docs. - матричная реализация SharpDX.
-
матричная реализация OpenTK. (Примечание:
Vector4
type также является типом значения.)
передача структуры C# импортированной функции, как вы это делаете, допустима, но вы должны указать длину массива в структуре, даже если позже вы укажете его размер.
объявление c в основном определяет массив длины 16, поэтому я бы указал структуру c# следующим образом:
[StructLayout(LayoutKind.Sequential)]
public struct mat4f
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public float[,] m;
}
вы можете узнать больше о том, как массивы-это упорядоченные здесь.