这个问题是上一个 question 的后续问题。关于在用于 C++ 的 Matlab Data API 中构建 Eigen::Map 到输入 matlab::data::Array 对象。现在我想知道如何实现类似的东西,但要实现一个输出数组,当我循环遍历它时,我将用数据填充该数组。
在上一个问题中,我实现了 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 数据数组的指针的方式存在一些问题?
最佳答案
这只是一个猜测,因为我将放弃相当平庸的 Matlab API 文档,并且没有 Matlab 许可证来测试它。所以请对此持保留态度。
我看到的一个区别是您创建了一个可变迭代器 TypedIterator<T>
而不是 TypedIterator<const T>
在 Matlab 论坛中使用。您可以在一个需要 matlab::data::Array
的函数中执行此操作。按值(value)。这将创建一个 shared data copy 。据我了解,这些是写时复制。
我的假设是,构造该迭代器或以可以修改该共享数组的方式使用它“取消共享”它,从而有效地创建一个拷贝。然而,该拷贝将仅限于参数的生命周期,即函数。函数返回后,它就变成了一个悬空指针。
尝试将函数签名更改为 T* getOutDataPtr(matlab::data::Array& arr)
。或者将代码内联到您的主函数中。
编辑
实际上,这种更改还不够,因为您构造了 TypedArray<T>
来自Array
。这也算作共享拷贝。尝试使用 getWritableElements
来代替:
template <typename T>
T* getOutDataPtr(matlab::data::Array& arr) {
auto range = matlab::data::getWritableElements<T>(arr);
return range.begin().operator->();
}
关于c++ - 如何构建 Eigen::Map 到我打算用数据填充的 matlab::data::Array 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76393248/