2

I have C# class:

namespace Models
{
    [StructLayout(LayoutKind.Explicit, Size = 120, CharSet = CharSet.Unicode)]
    public struct DynamicState
    {
        [FieldOffset(0)]
        public double[] Position;

        [FieldOffset(24)]
        public double[] Velocity;

        [FieldOffset(48)]
        public double[] Acceleration;

        [FieldOffset(72)]
        public double[] Attitude;

        [FieldOffset(96)]
        public double[] AngularVelocity;
    }
}

and C++/CLI method:

Models::DynamicState SomeClassClr::DoSomething(Models::DynamicState ds)
{
    int struct_size = Marshal::SizeOf(ds);
    System::IntPtr ptr = Marshal::AllocHGlobal(struct_size);
    DynamicStateStruct ds_struct;
    struct_size = sizeof(ds_struct);

    Marshal::StructureToPtr(ds, ptr, false);
    ds_struct = *(DynamicStateStruct*)ptr.ToPointer();

    Models::DynamicState returnVal;
    mpSomeClass->doSomething(ds_struct);

    return returnVal;
}

where DynamicStateStruct is a native C++ class:

struct DynamicStateStruct
{
    double mPosition[3];
    double mVelocity[3];
    double mAcceleration[3];
    double mAttitude[3];
    double mAngularVelocity[3];
};

When I recover the struct (ds_struct) in native C++ I am not getting the correct values, any ideas with what I am missing?

3
  • Note when I'm testing I'm only assigning one array in the managed DynamicState object. Commented Oct 5, 2012 at 13:32
  • Why would the arrays of doubles be marshaled to an array of 3 C++ doubles? What if one of the arrays had 6 items? Commented Oct 5, 2012 at 13:41
  • assume the initialization of each array is constrained to 3. i.e. as per the length of each fieldoffset attribute. Commented Oct 5, 2012 at 13:52

1 Answer 1

1

Try the following variant:

public struct DynamicState
{
    [MarshalAs (UnmanagedType.ByValArray, SizeConst=3)]
    public double[] Position;

    [MarshalAs (UnmanagedType.ByValArray, SizeConst=3)]
    public double[] Velocity;

    [MarshalAs (UnmanagedType.ByValArray, SizeConst=3)]
    public double[] Acceleration;

    [MarshalAs (UnmanagedType.ByValArray, SizeConst=3)]
    public double[] Attitude;

    [MarshalAs (UnmanagedType.ByValArray, SizeConst=3)]
    public double[] AngularVelocity;
}

Another option is to use fixed array available in unsafe code:

public unsafe struct DynamicState
{
    public fixed double Position[3];

    public fixed double Velocity[3];

    public fixed double Acceleration[3];

    public fixed double Attitude[3];

    public fixed double AngularVelocity[3];
}

P.S. A good guide on .Net interop can be found here: http://www.mono-project.com/Interop_with_Native_Libraries

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

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.