主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

使用 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> 对象,即 temperaturespressures。每次调用 factory.createArray<double>() 都会指定数组维度并使用给定的值初始化数组。这里,两个数组都是一维的,每个数组有 5 元素,分别代表温度和压力数据。

  • 再次使用 factory 对象创建一个名为 inputStructStructArraycreateStructArray 方法使用两个参量进行调用:

    • 第一个指定结构体数组的维度。在这种情况下,为 1x1 结构体数组。

    • 第二个是定义结构字段名称的字符串初始化列表:"temperatures""pressures"

  • 最后,inputStruct 中第一个(也是唯一一个)结构体的字段被填充 temperaturespressures 数组。语法 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());
    

另请参阅

主题