gpt4 book ai didi

C++ 对象的 C++ vector 到 mex 中的 mxArray

转载 作者:行者123 更新时间:2023-11-27 23:09:34 25 4
gpt4 key购买 nike

我有以下 C++ vector :

std::vector<myStruct> myVec;

其中 myStruct 包含:

struct myStruct {
Point3D start;
Point3D end;
double lenght;
}
struct Point3D {
double x, y, z;
}

现在在我的 mex 文件中,我想将其转换为 mxArray,同时保持相同的结构。

当前(非功能)代码:

// basic 'out' 
mxArray *out;
mwSize dims[2] = { 1, 1 };
const char *pointField[] = {"point"};
const char *fields[] = {"start", "end","lenght"};
const char *3dFields[] = {"x", "y", "z"};
out = mxCreateStructArray(2,dims,(int)myVec.size(),pointField);
for( int i = 0 ; i < myVec.size() ; ++i)
{
// create struct to fill
mxArray *point = mxCreateStructArray(2, dims, 3, fields);

// create struct for start
mxArray *start= mxCreateStructArray(2, dims, 3, 3dFields);
mxSetField( start, 0, "x", mxCreateDoubleScalar(myVec[i].start.x) );
mxSetField( start, 0, "y", mxCreateDoubleScalar(myVec[i].start.y) );
mxSetField( start, 0, "z", mxCreateDoubleScalar(myVec[i].start.z) );

// create struct for end
mxArray *end= mxCreateStructArray(2, dims, 3, 3dFields);
mxSetField( end, 0, "x", mxCreateDoubleScalar(myVec[i].end.x) );
mxSetField( end, 0, "y", mxCreateDoubleScalar(myVec[i].end.y) );
mxSetField( end, 0, "z", mxCreateDoubleScalar(myVec[i].end.z) );

// add start + end to 'point'
mxSetField( point, 0, "start", start);
mxSetField( point, 0, "end", end);
mxSetField( point, 0, "lenght", mxCreateDoubleScalar(myVec[i].lenght) );

// add completed 'point' struct to out at given index i
mxSetField(out, i, "point", point );
}
plhs[0] = out;

如您所见,重要的是我可以有 1 个输出值,它可以包含多个“点”- 结构,其中每个点都有一个开始(xyz)结构、结束(xyz)结构和长度值。

到目前为止,此代码仅以正确的格式输出 1 个单一结构,但是对于第二次迭代,它仅在“点”所在的级别直接创建一个空的“结束”值。

我必须更改什么才能使其正常工作?

提前致谢!

最佳答案

这是我的实现:

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));
}
}

我们从 MATLAB 编译并调用 MEX 函数:

>> mex -largeArrayDims vec_struct.cpp
>> s = vec_struct()
s =
1x10 struct array with fields:
start
end
length

如您所见,这会创建一个 structure array长度为 10。例如,第 5 个结构被访问为:

>> 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

上述 MEX 文件等效于以下 MATLAB 代码:

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

关于C++ 对象的 C++ vector 到 mex 中的 mxArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21110358/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com