如何在c# Unity中使用C结构体和2D数组

本文关键字:结构体 2D 数组 Unity | 更新日期: 2023-09-27 18:04:06

所以我有一个C API与以下结构

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

它作为参数传递给我的一个API函数:

void myFunction(const mat4f matrix);

我在Unity中使用dll导出这个函数到c#:

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

我的问题是,我应该使相应的c#结构是什么?

现在我有以下内容:

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

和use尝试如下使用函数:

//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

这是正确的事情吗?有更好的方法吗?

如何在c# Unity中使用C结构体和2D数组

对于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
    };
}

这是一个blitable类型。在托管和非托管代码之间传递时,位元表类型不需要转换。

样本使用:

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

现有的实现与我上面介绍的类似。

  • 矩阵实现Unity(反编译;原始源代码不是免费的)。参见UnityEngine.Matrix4x4 docs.
  • 矩阵SharpDX的实现。
  • 矩阵实现OpenTK。(注:Vector4类型也是一种值类型)

将c#结构体传递给导入的函数是有效的,但是您应该在结构体中指定数组的长度,即使您稍后指定它的大小。

c声明基本上指定了一个长度为16的数组,因此我将按照如下方式指定c#结构体:

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

你可以在这里阅读更多关于数组是如何编组的。