Search code examples
c++arraysmatlabstructmex

How Do I access data in a Matlab Array of Structures in a mex file


I am writing a C++ mex function in order to improve the performance of a larger matlab code. As part of the mex function I am trying to read from an array of structures that was created in MATLAB. Each item in the array contains a struct that is made up of arrays of complex numbers. The code I am writing would ideally access each struct within the array individually.

The function I am trying to write would be passed the entire data structure and an array index. Using that information I want to get pointers to the real and imaginary parts of the complex number arrays within the matlab structure at that array index.

I fully accept that I am not understanding something about how MATLAB structures are read in c/c++ mex files.

This is what I have tried

    void read_struct(int i, const mxArray* AoS, double *real, double *imag)
{
    /*
        read_struct: reads real and imaginary parts of complex number array from
                 within a Matlab Structure within an array of Structures.

        INPUTS:     i = index of the structure to be accessed
                AoS = Array of Structures

        OUTPUTS:    real - pointer to real part of complex number array
                imag - pointer to imaginary part of complex number array

    */

    // Declare pointers to mxArray
    const mxArray *p_ph_F1, *p_ph_XF1, *p_ph_F2, *p_ph_YF2, *p_ph_F3, *p_ph_ZF3,
              *p_ph_F4, *p_ph_XF4, *p_ph_F5, *p_ph_YF5, *p_ph_F6, *p_ph_ZF6;
    // Declare pointers to real and imaginary parts of Matlab Complex values
        // Real Parts
    double *p_ph_F1_r, *p_ph_XF1_r, *p_ph_F2_r, *p_ph_YF2_r, *p_ph_F3_r, *p_ph_ZF3_r,
           *p_ph_F4_r, *p_ph_XF4_r, *p_ph_F5_r, *p_ph_YF5_r, *p_ph_F6_r, *p_ph_ZF6_r;

    // Find pointer to correct array cell
    const mxArray* ph = mxGetCell(AoS, i);

    //Pointers to complex number arrays
    p_ph_F1 = mxGetField(ph,0,'ph_F1');
    p_ph_XF1 = mxGetField(ph,1,'ph_XF1');
    p_ph_F2 = mxGetField(ph,2,'ph_F2');
    p_ph_YF2 = mxGetField(ph,3,'ph_YF2');
    p_ph_F3 = mxGetField(ph,4,'ph_F3');
    p_ph_ZF3 = mxGetField(ph,5,'ph_ZF4');
    p_ph_F4 = mxGetField(ph,6,'ph_F4');
    p_ph_XF4 = mxGetField(ph,7,'ph_XF4');
    p_ph_F5 = mxGetField(ph,8,'ph_F5');
    p_ph_YF5 = mxGetField(ph,9,'ph_YF5');
    p_ph_F6 = mxGetField(ph,10,'ph_F6');
    p_ph_ZF6 = mxGetField(ph,11,'ph_ZF6');
}

at the moment I get the following error when trying to compile the code:

error: argument of type "int" is incompatible with parameter of type "const char *"

I've been through the MATLAB help and example files but am struggling to find/understand the solution.

Any help would be greatly appreciated.

Thanks!


Solution

  • There are two things going on:

    1. In C, strings use double quotes. Write mxGetField(ph,0,"ph_F1"), not mxGetField(ph,0,'ph_F1').

    2. You are getting the elements ph(1).ph_F1, ph(2).ph_XF1, etc., which is probably not what you intended. I think you intend to read the given fields from the same struct index:

      mxArray const* p_ph_F1  = mxGetField(ph,0,"ph_F1");
      mxArray const* p_ph_XF1 = mxGetField(ph,0,"ph_XF1");
      mxArray const* p_ph_F2  = mxGetField(ph,0,"ph_F2");
      mxArray const* p_ph_YF2 = mxGetField(ph,0,"ph_YF2");
      // etc.
      

    Do make sure that you test the returned pointers, if the field doesn't exist, you'll get a NULL pointer back.