这个问题是上一个关于在Matlab Data API for C++中构建输入matlab::data::Array对象的Eigen::Map问题的后续问题。现在我想知道如何实现类似的东西,但是要实现一个输出数组,在循环遍历它时用数据填充它。
在上一个问题中,我从Matlab's forums实现了链接解决方案。在这里,我尝试使用以下方法来获取一个非常量指针:
template <typename T>
T* getOutDataPtr(matlab::data::Array arr) {
matlab::data::TypedArray<T> arr_t = arr;
matlab::data::TypedIterator<T> it(arr_t.begin());
return it.operator->();
}
它的用法是这样的:
// Initialize input parameters
long int numEl = inputs[0][0];
long int na = inputs[0][1];
long int nPoints = inputs[0][2];
// Preallocate output and define map to output array
outputs[0] = factory.createArray<double>
({static_cast<size_t>(nPoints),static_cast<size_t>(numEl*na)});
auto ptrRecon = getOutDataPtr<double>(outputs[0]);
Eigen::Map<Eigen::MatrixXd> Recon(ptrRecon,nPoints,numEl*na);
for(int i = 0; i < nPoints; i++) {
for(int n = 0; n < na; n++) {
for (int j = 0; j < numEl; j++) {
Recon(i,n*numEl + j) = 5.0;
}
}
}
然而,即使是这样一个简单的赋值,我也会在编译和Matlab崩溃后遇到运行时错误。到底出了什么问题?
其他试验我还尝试了以下的内部循环,似乎确实有效:
for(int i = 0; i < nPoints; i++) {
for(int n = 0; n < na; n++) {
for (int j = 0; j < numEl; j++) {
outputs[0][i][n*numEl + j] = 5.0;
}
}
}
我怀疑这意味着我获取输出matlab数据数组指针的方式有问题?
1条答案
按热度按时间e0bqpujr1#
这只是一个猜测,因为我将离开相当平庸的Matlab API文档,并且没有Matlab许可证来测试它。所以请你对这件事持保留态度。
我看到的一个区别是,您创建了一个可变迭代器
TypedIterator<T>
,而不是Matlab论坛中使用的TypedIterator<const T>
。你可以在一个函数中实现这一点,该函数接受matlab::data::Array
的值。这将创建共享数据副本。据我所知,这些是写时复制。我的假设是,无论是构造迭代器还是以一种可以修改共享数组的方式使用迭代器,都会“取消共享”它,从而有效地创建一个副本。但是,该副本将被限制在参数的生命周期内,即函数。函数返回后,它就变成了一个悬空指针。
尝试将函数签名更改为
T* getOutDataPtr(matlab::data::Array& arr)
。或者将代码内联到主函数中。编辑
实际上,这种改变是不够的,因为您要从
Array
构造TypedArray<T>
。这也算作共享副本。尝试使用getWritableElements
: