Pass a struct from Unity to C++ library

Hello,

I’m using a C++ custom library I built for Unity in one of my projects. I’m sending a C# struct while invoking a method in the C++ library. These structs are using the exact same names and order in its members on both C++ and C# classes. But only some of the struct members are being received correctly on the C++ side. Others are going back to default value. I only have int and bool members in the struct. No arrays. Any idea what might be happening?

anyone have any ideas?

2 Answers

2

Like Captain P. said, you should share your code. Keep in mind to use export "C" on the C++ side to avoid name mangling.

On the managed C# side you have to use [StructLayout(LayoutKind.Sequential)] on your struct to ensure a sequential memory layout.

Finally keep in mind that depending on the compiler and platform, in C++ the actual size of an int, long, etc can vary. So again, it would be way easier to provide a clear answer if we had your actual code as reference. If you want to provide the code, feel free to edit your question and add the relevant code snippets.

@Bunny83 Thank you for the response. I indeed needed to add the [StructLayout(LayoutKind.Sequential)] attribute to the struct. I also ended up having to use [MarshalAs(UnmanagedType.U1)] for all the bools and [MarshalAs(UnmanagedType.R4)] for floats inside the struct. This resolved my issue.

@Bunny83
Found this post by accident. Thanks for your answer and I got a further question. If you got the time.

I found out that it seems we can’t use “const T& param” to declare functions on C++ side. It crashes randomly on Android and iOS platform with il2cpp.

c++
extern "C"
{
    struct alignas(4) Vector3f
    {
        float x;
        float y;
        float z;
    };

	API rp3d::BoxShape* PhysicsCommon_createBoxShape(rp3d::PhysicsCommon* physicsCommonPtr, const Vector3f& halfExtents);
}
    [StructLayout(LayoutKind.Explicit, Pack = 4)]
    public struct Vector3f
    {
        [FieldOffset(0)]
        public float x;
        [FieldOffset(4)]
        public float y;
        [FieldOffset(8)]
        public float z;
   }
        [DllImport(LMNAReactPhysicsEngine.ReactPhysics_DLL, EntryPoint = "PhysicsCommon_createBoxShape", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr PhysicsCommon_createBoxShape(IntPtr physicsCommonPtr, Vector3f halfExtents);

It crashes.

But It doesn’t when I changed the c++ side as below.

	API rp3d::BoxShape* PhysicsCommon_createBoxShape(rp3d::PhysicsCommon* physicsCommonPtr, Vector3f halfExtents);
}

The crash on iOS is BAD_ACCESS. Do you have any info ? thx.