0

I'm doing C++ --> C# interop stuff and I have a bunch of structs that contain each other like Matryoshka dolls. The problem is that one of these 'nestings' takes the form of a fixed length array:

typedef struct tagBIRDREADING
{
    BIRDPOSITION    position;
    BIRDANGLES      angles;
    BIRDMATRIX      matrix;
    BIRDQUATERNION  quaternion;
    WORD            wButtons;
}
BIRDREADING;

typedef struct tagBIRDFRAME
{
    DWORD           dwTime;
    BIRDREADING     reading[BIRD_MAX_DEVICE_NUM + 1];
}
BIRDFRAME;

Following the hallowed teachings of Eric Gunnerson, I did the following in C#:

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct BIRDREADING
{
    public BIRDPOSITION position;
    public BIRDANGLES angles;
    public BIRDMATRIX matrix;
    public BIRDQUATERNION quaternion;
    public ushort wButtons;
}

[StructLayout(LayoutKind.Sequential, Size = 127)]
public struct BIRDREADINGa
{
    public BIRDREADING reading;
}

public struct BIRDFRAME
{
    public uint dwTime;
    public BIRDREADINGa readings; 
}

My question is, how do I access each of the 127 instances of BIRDREADING contained within BIRDREADINGa and therefore BIRDFRAME? Or have I gone terrible wrong?

2 Answers 2

4

I think you just want this:

[StructLayout(LayoutKind.Sequential)]
public struct BIRDFRAME
{
    public uint dwTime;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=127)] 
    public BIRDREADING[] readings; 
}
Sign up to request clarification or add additional context in comments.

4 Comments

You're always really fast with the P/Invoke answers. Every time I go to submit one, yours pops up :-]
@ildjarn Sorry! I do like P/Invoke questions, even though I never do any P/Invoke for real myself.
No apology necessary, just paying a compliment. :-]
Thanks for this Dave. I wonder whether you'd enjoy a follow-up question? stackoverflow.com/q/5681647/50151
0

To access all those instances without using an array you need to use an unsafe block to grab the address of the "fake array" you set up, and then use pointer arithmetic. It's going to get ugly:

public struct BIRDREADINGa
{
    public BIRDREADING reading;

    public BIRDREADING GetReading(int index)
    {
        unsafe
        {
            fixed(BIRDREADING* r = &reading)
            {
                return *(r + index);
            }
        }
    }
}

3 Comments

Hmm, apparently changing the values will not work like this readingA.GetReading(3).wButtons = 3 :(
Plus it uses fixed which OP would like not to do
@David: it's not the same fixed. I know from chat that he was talking about the fixed that means fixed size arrays, not the fixed that means pin references.

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.