11

So I have a C API with the following struct

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

It gets passed as a parameter to one of my API functions:

void myFunction(const mat4f matrix);

I am exporting this function to C# in Unity using a dll:

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

My question is, what should I make the corresponding C# struct be?

Right now I have the following:

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

and use try to use the function as follows:

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

0

2 Answers 2

4
+25

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:

[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.

Sample use:

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

Existing implementations are similar to the one I presented above.

Sign up to request clarification or add additional context in comments.

Comments

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.

The c declaration basically specifies an array of length 16, so I would specify the c# struct as follows:

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

You can read more about how arrays are marshalled here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.