使用 MATLAB 结构体数组
在 MATLAB® 中,您可以通过动态分配字段名称和值来创建结构体数组。相比之下,C++ 是一种静态类型语言,要求预先声明结构的所有字段及其类型。本讨论使用示例部署接受结构体数组作为输入参量的 MATLAB 函数解释如何在 C++ 代码中处理 MATLAB 结构。
结构体输入
在 MATLAB 中,可以通过动态分配字段名称和值来创建结构体数组。C++ 是一种静态类型语言,要求预先声明结构的所有字段及其类型。
当 C++ 代码调用需要 MATLAB 结构作为输入的 MATLAB 函数时,必须通过 MATLAB Data API 使用适当的数据类型在 C++ 中明确创建该结构。例如:
% MATLAB
data = struct();
data.temperatures = [72, 75, 69, 68, 70];
data.pressures = [30, 29.5, 30.2, 29.9, 30.1]; |
// C++
matlab::data::ArrayFactory factory;
matlab::data::TypedArray<double> temperatures = factory.createArray<double>({ 5 }, { 72, 75, 69, 68, 70 });
matlab::data::TypedArray<double> pressures = factory.createArray<double>({ 5 }, { 30, 29.5, 30.2, 29.9, 30.1 });
matlab::data::StructArray inputStruct = factory.createStructArray({ 1 }, { "temperatures", "pressures" });
inputStruct[0]["temperatures"] = temperatures;
inputStruct[0]["pressures"] = pressures; |
创建一个名为 factory 的
ArrayFactory对象。该对象用于在 C++ 中创建 MATLAB 数据数组。它是一个工厂类,提供创建各种类型的 MATLAB 数据数组的方法。MATLAB Data API 中的
matlab::data::TypedArray<T>类是一个模板类,旨在表示特定类型的数组<T>在与 MATLAB 交互的 C++ 代码中。该类允许 C++ 程序创建与 MATLAB 数据类型兼容的数组,促进 C++ 和 MATLAB 环境之间的数据交换。使用工厂对象创建了两个
TypedArray<double>对象,即temperatures和pressures。每次调用factory.createArray<double>()都会指定数组维度并使用给定的值初始化数组。这里,两个数组都是一维的,每个数组有5元素,分别代表温度和压力数据。再次使用
factory对象创建一个名为inputStruct的StructArray。createStructArray方法使用两个参量进行调用:第一个指定结构体数组的维度。在这种情况下,为 1x1 结构体数组。
第二个是定义结构字段名称的字符串初始化列表:
"temperatures"和"pressures"。
最后,
inputStruct中第一个(也是唯一一个)结构体的字段被填充temperatures和pressures数组。语法inputStruct[0]["temperatures"]访问第一个结构的"temperatures"字段并将温度数组分配给它。类似地,"pressures"字段也由pressures数组填充。
结构体输出
当从 C++ 调用的 MATLAB 函数返回 MATLAB 结构时,它将作为 C++ 代码中的 matlab::data::Array 返回。为了检索字段名称和字段值,需要进行一些处理。例如:
// Function to print the MATLAB computation results
void printMatlabResults(matlab::data::Array outputArray) {
matlab::data::StructArray structArray = outputArray;
auto topLevelStructFieldNamesIterable = structArray.getFieldNames();
std::vector<matlab::data::MATLABFieldIdentifier>
topLevelStructFieldNames(topLevelStructFieldNamesIterable.begin(), topLevelStructFieldNamesIterable.end());
for (const matlab::data::MATLABFieldIdentifier& fieldName : topLevelStructFieldNames) {
std::string outerFieldName(fieldName);
std::cout << "Field: " << outerFieldName << std::endl;
matlab::data::TypedArrayRef<matlab::data::Struct> nestedStruct = outputArray[0][fieldName];
auto nestedStructFieldNamesIterable = nestedStruct.getFieldNames();
std::vector<matlab::data::MATLABFieldIdentifier>
nestedStructFieldNames(nestedStructFieldNamesIterable.begin(), nestedStructFieldNamesIterable.end());
for (const matlab::data::MATLABFieldIdentifier& fieldName : nestedStructFieldNames) {
std::string innerFieldName(fieldName);
matlab::data::TypedArrayRef<double> fieldValue = nestedStruct[0][fieldName];
double value = fieldValue[0];
std::cout << " " << innerFieldName << ": " << std::fixed << std::setprecision(4) << value << std::endl;
}
}
}从 MATLAB 函数返回的 MATLAB 结构体为
matlab::data::Array需要转换为matlab::data::StructArray。无法直接访问结构字段。matlab::data::StructArray structArray = outputArray;
从结构体数组中检索字段名称的可迭代对象。
auto topLevelStructFieldNamesIterable = structArray.getFieldNames(); std::vector<matlab::data::MATLABFieldIdentifier> topLevelStructFieldNames(topLevelStructFieldNamesIterable.begin(), topLevelStructFieldNamesIterable.end());使用循环处理结构中的每个字段。这涉及通过名称访问每个字段并处理其内容。
for (const matlab::data::MATLABFieldIdentifier& fieldName : topLevelStructFieldNames) { std::string outerFieldName(fieldName); std::cout << "Field: " << outerFieldName << std::endl; ... }如果字段本身包含结构,则重复获取字段名称并对其进行迭代的过程。
matlab::data::TypedArrayRef<matlab::data::Struct> nestedStruct = outputArray[0][fieldName]; auto nestedStructFieldNamesIterable = nestedStruct.getFieldNames(); std::vector<matlab::data::MATLABFieldIdentifier> nestedStructFieldNames(nestedStructFieldNamesIterable.begin(), nestedStructFieldNamesIterable.end());