Before I started developing MMALSharp I had never needed to deal with low level memory access or unmanaged resources in C#; I had done some C programming whilst at university, but those days were mainly over and my daily programming at work is done in a managed environment. But, as MMALSharp is heavily dependent on the C implementation of the MMAL library, things were about to change…fast.

Before I knew it, I was analysing large amounts of C code, refreshing my mind on pointers (can I not just use a class and forget this ever happened?) and low level memory management; it was a lot to take in at first, and the first hurdle appeared when I came across this structure:

typedef struct MMAL_COMPONENT_T
{
   // Removed irrelevant areas.
   uint32_t    input_num;   /**< Number of input ports */
   MMAL_PORT_T **input;     /**< Array of input ports */
} MMAL_COMPONENT_T;

Without drifting away from the focus of this article too much, this struct represents a component in MMAL, and each component has a number of ports, nothing too complicated at high level. However, I had never come across a pointer being declared like this before MMAL_PORT_T **input;, so a quick Google explained these were “pointers to pointers” or a “double pointer” and is essentially a way of declaring an “array of pointers in C”. Now I had my work cut out as I needed to dereference these “double pointers” to get each individual port from the component. After many attempts, I finally figured out what was needed and the solution can be seen below.

For clarity, here is the C# equivalent struct, again all the irrelevant code has been removed:

[StructLayout(LayoutKind.Sequential)]
public unsafe struct MMAL_COMPONENT_T
{
    private uint inputNum;
    private MMAL_PORT_T** input;
    
    public uint InputNum => this.inputNum;

    public MMAL_PORT_T** Input => this.input;

    public MMAL_COMPONENT_T(uint inputNum,
                            MMAL_PORT_T** input)
    {
        this.inputNum = inputNum;
        this.input = input;
    }
}

Next, you need to loop around the number of pointers you will be expecting to be present, and the dereferencing is done as follows:

&(*this.Ptr->Input[i])

Where this.Ptr is a MMAL_COMPONENT_T* pointer to the MMAL component and its Input struct member is accessed at index i.

I hope that might help someone in a similar situation, and thanks for reading.