So I have a C API with the following struct
所以我有一个带有以下结构的C API
typedef struct mat4f_ { float m[4][4]; } mat4f;
It gets passed as a parameter to one of my API functions:
它作为参数传递给我的一个API函数:
void myFunction(const mat4f matrix);
I am exporting this function to C# in Unity using a dll:
我使用dll将此函数导出到Unity中的C#:
[DllImport ("mylib")]
private static extern void myFunction(mat4f matrix);
My question is, what should I make the corresponding C# struct be?
我的问题是,我应该如何制作相应的C#结构?
Right now I have the following:
现在我有以下内容:
[StructLayout(LayoutKind.Sequential)]
public struct mat4f
{
public float[,] m;
}
and use try to use the function as follows:
并使用try尝试使用如下函数:
//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
Is this the correct thing to do? Is there a better way to do this?
这是正确的做法吗?有一个更好的方法吗?
2 个解决方案
#1
4
For a 4×4 matrix, you can use UnityEngine.Matrix4x4
. If you want to use your own struct, I recommend you implement it the same way UnityEngine.Matrix4x4
is implemented:
对于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
};
}
This is a blittable type. Blittable types do not require conversion when they are passed between managed and unmanaged code.
这是一种blittable类型。 Blittable类型在托管代码和非托管代码之间传递时不需要转换。
Sample use:
mat4f matrix = mat4f.Identity;
myFunction(matrix); // Call DLL function
Existing implementations are similar to the one I presented above.
现有的实现类似于我上面提到的实现。
-
Matrix implementation of Unity (decompiled; original source code is not available for free). See
UnityEngine.Matrix4x4
docs. - Matrix implementation of SharpDX.
-
Matrix implementation of OpenTK. (Note: the
Vector4
type is also a value type.)
Unity的Matrix实现(反编译;原始源代码不可免费获得)。请参阅UnityEngine.Matrix4x4文档。
SharpDX的矩阵实现。
OpenTK的矩阵实现。 (注意:Vector4类型也是值类型。)
#2
1
Passing a C# struct to an imported function like you are doing is valid, but you should specify the length of the array in the struct, even if you later specify its size.
将C#结构传递给您正在执行的导入函数是有效的,但是您应该在结构中指定数组的长度,即使您稍后指定其大小也是如此。
The c declaration basically specifies an array of length 16, so I would specify the c# struct as follows:
c声明基本上指定了一个长度为16的数组,所以我将指定c#结构如下:
[StructLayout(LayoutKind.Sequential)]
public struct mat4f
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public float[,] m;
}
You can read more about how arrays are marshalled here.
您可以在此处详细了解如何编组数组。
#1
4
For a 4×4 matrix, you can use UnityEngine.Matrix4x4
. If you want to use your own struct, I recommend you implement it the same way UnityEngine.Matrix4x4
is implemented:
对于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
};
}
This is a blittable type. Blittable types do not require conversion when they are passed between managed and unmanaged code.
这是一种blittable类型。 Blittable类型在托管代码和非托管代码之间传递时不需要转换。
Sample use:
mat4f matrix = mat4f.Identity;
myFunction(matrix); // Call DLL function
Existing implementations are similar to the one I presented above.
现有的实现类似于我上面提到的实现。
-
Matrix implementation of Unity (decompiled; original source code is not available for free). See
UnityEngine.Matrix4x4
docs. - Matrix implementation of SharpDX.
-
Matrix implementation of OpenTK. (Note: the
Vector4
type is also a value type.)
Unity的Matrix实现(反编译;原始源代码不可免费获得)。请参阅UnityEngine.Matrix4x4文档。
SharpDX的矩阵实现。
OpenTK的矩阵实现。 (注意:Vector4类型也是值类型。)
#2
1
Passing a C# struct to an imported function like you are doing is valid, but you should specify the length of the array in the struct, even if you later specify its size.
将C#结构传递给您正在执行的导入函数是有效的,但是您应该在结构中指定数组的长度,即使您稍后指定其大小也是如此。
The c declaration basically specifies an array of length 16, so I would specify the c# struct as follows:
c声明基本上指定了一个长度为16的数组,所以我将指定c#结构如下:
[StructLayout(LayoutKind.Sequential)]
public struct mat4f
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=16)] public float[,] m;
}
You can read more about how arrays are marshalled here.
您可以在此处详细了解如何编组数组。