Here is my implementation:
vec_struct.cpp
#include "mex.h"
#include <vector>
// C++ struct
struct Point3D {
double x, y, z;
};
struct myStruct {
Point3D start;
Point3D end;
double length;
};
const char *fieldsPoint[] = {"x", "y", "z"};
const char *fieldsStruct[] = {"start", "end", "length"};
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nrhs != 0 || nlhs > 1) {
mexErrMsgIdAndTxt("MATLAB:MEX", "Wrong number of arguments.");
}
// create C++ vector of structs
std::vector<myStruct> v;
for (int i=0; i<10; i++) {
myStruct s = {
{1.0+i, 2.0+i, 3.0+i},
{4.0+i, 5.0+i, 6.0+i},
i
};
v.push_back(s);
}
// convert it to MATLAB struct array and return it as output
mxArray *p;
plhs[0] = mxCreateStructMatrix(1, v.size(), 3, fieldsStruct);
for (int i=0; i<v.size(); i++) {
// start point
p = mxCreateStructMatrix(1, 1, 3, fieldsPoint);
mxSetField(p, 0, "x", mxCreateDoubleScalar(v[i].start.x));
mxSetField(p, 0, "y", mxCreateDoubleScalar(v[i].start.y));
mxSetField(p, 0, "z", mxCreateDoubleScalar(v[i].start.z));
mxSetField(plhs[0], i, "start", p);
// end point
p = mxCreateStructMatrix(1, 1, 3, fieldsPoint);
mxSetField(p, 0, "x", mxCreateDoubleScalar(v[i].end.x));
mxSetField(p, 0, "y", mxCreateDoubleScalar(v[i].end.y));
mxSetField(p, 0, "z", mxCreateDoubleScalar(v[i].end.z));
mxSetField(plhs[0], i, "end", p);
// length
mxSetField(plhs[0], i, "length", mxCreateDoubleScalar(v[i].length));
}
}
We compile and call the MEX-function from MATLAB:
>> mex -largeArrayDims vec_struct.cpp
>> s = vec_struct()
s =
1x10 struct array with fields:
start
end
length
As you can see, this creates a structure array of length 10. For instance the 5th structure is accessed as:
>> s(5)
ans =
start: [1x1 struct]
end: [1x1 struct]
length: 4
>> s(5).start
ans =
x: 5
y: 6
z: 7
>> s(5).start.x
ans =
5
The above MEX-file is equivalent to the following MATLAB code:
ss = struct();
for i=1:10
ss(i).start = struct('x',1+i-1, 'y',2+i-1, 'z',3+i-1);
ss(i).end = struct('x',4+i-1, 'y',5+i-1, 'z',6+i-1);
ss(i).length = i-1;
end