主要内容

从 MATLAB 函数生成 C/C++ 代码

此示例说明从 MATLAB® 函数生成 C/C++ 代码的建议工作流。此工作流包括以下步骤:

  1. 为代码生成准备 MATLAB 代码。

  2. 生成并测试 MEX 函数。

  3. 生成和检查 C/C++ 代码。

此示例在命令行中使用 codegen 命令生成 C/C++ 代码。要了解如何使用 MATLAB Coder™ 生成代码,请参阅使用 MATLAB Coder 生成 C 代码

创建 MATLAB 代码和样本数据

对于此示例的目的来说,此步骤是必需的,但它不是代码生成工作流中的典型步骤。

创建一个 MATLAB 函数 averagingFilterML,用作输入信号的平均值滤波器。此函数接受由信号值组成的输入向量,并返回由滤波后的值组成的输出向量。输出向量的大小与输入向量相同。averagingFilterML 函数使用变量 slider 来表示包含 16 个信号值的滑动窗,并计算每个窗位置的平均信号值。

type averagingFilterML
function y = averagingFilterML(x)
slider = zeros(16,1);
y = zeros(size(x));
for i = 1:numel(x)
    slider(2:end) = slider(1:end-1); % move one position in the buffer
    slider(1) = x(i); % Add a new sample value to the buffer
    y(i) = sum(slider)/numel(slider); % write the average of the current window to y
end
end

生成含噪正弦波作为样本数据,并使用 averagingFilterML 对含噪数据进行滤波。在同一图窗窗口中绘制含噪数据和滤波后的数据。

v = 0:0.00614:2*pi;
x = sin(v) + 0.3*rand(1,numel(v));
y = averagingFilterML(x);
plot(x,"red");
hold on
plot(y,"blue");
hold off;

Figure contains an axes object. The axes object contains 2 objects of type line.

步骤 1:为代码生成准备 MATLAB 代码

averagingFilterML 函数重命名为 averagingFilterCG。将 %#codegen 指令添加到 averagingFilterCG 以提示 MATLAB 代码分析器识别特定于代码生成的警告和错误。要进行代码生成,必须定义输入变量类型。使用 arguments 模块将输入指定为 doubles 的无界向量。

type averagingFilterCG
function y = averagingFilterCG(x) %#codegen
arguments
    x (1,:) double
end
slider = zeros(16,1);
y = zeros(size(x));
for i = 1:numel(x)
    slider(2:end) = slider(1:end-1); % move one position in the buffer
    slider(1) = x(i); % Add a new sample value to the buffer
    y(i) = sum(slider)/numel(slider); % write the average of the current window to y
end
end

步骤 2:生成并测试 MEX 函数

在生成 C/C++ 代码之前,必须生成并测试 MEX 函数。在生成 C/C++ 代码之前,在 MATLAB 中运行 MEX 函数可以检测并修复运行时错误,而在生成的代码中诊断这些错误要难得多。此外,您还可以使用 MEX 函数来验证您生成的代码与您的原始 MATLAB 代码在功能上相似。

使用 codegen 命令从 averagingFilterCG 生成一个 MEX 函数。使用传递给原始 MATLAB 函数的相同输入来测试 MEX 函数,并比较结果。MEX 函数产生相同的输出。

codegen averagingFilterCG
Code generation successful.
z = averagingFilterCG_mex(x);
plot(x,"red");
hold on
plot(z,"blue");
hold off;

Figure contains an axes object. The axes object contains 2 objects of type line.

步骤 3:生成和检查 C/C++ 代码

使用带 -config:lib 选项的 codegen 命令生成独立 C 库。检查生成的 C 代码中的 averagingFilterCG 函数。

codegen -config:lib averagingFilterCG
Code generation successful.
type(fullfile("codegen","lib","averagingFilterCG","averagingFilterCG.c"))
/*
 * File: averagingFilterCG.c
 *
 * MATLAB Coder version            : 25.2
 * C/C++ source code generated on  : 09-Aug-2025 10:00:43
 */

/* Include Files */
#include "averagingFilterCG.h"
#include "averagingFilterCG_emxutil.h"
#include "averagingFilterCG_types.h"
#include <string.h>

/* Function Definitions */
/*
 * Arguments    : const emxArray_real_T *x
 *                emxArray_real_T *y
 * Return Type  : void
 */
void averagingFilterCG(const emxArray_real_T *x, emxArray_real_T *y)
{
  double slider[16];
  double b_slider[15];
  const double *x_data;
  double *y_data;
  int i;
  int k;
  int loop_ub;
  x_data = x->data;
  memset(&slider[0], 0, 16U * sizeof(double));
  loop_ub = y->size[0] * y->size[1];
  y->size[0] = 1;
  y->size[1] = x->size[1];
  emxEnsureCapacity_real_T(y, loop_ub);
  y_data = y->data;
  loop_ub = x->size[1];
  for (i = 0; i < loop_ub; i++) {
    y_data[i] = 0.0;
  }
  loop_ub = x->size[1];
  for (i = 0; i < loop_ub; i++) {
    double b_y;
    memcpy(&b_slider[0], &slider[0], 15U * sizeof(double));
    /*  move one position in the buffer */
    b_y = x_data[i];
    slider[0] = b_y;
    /*  Add a new sample value to the buffer */
    for (k = 0; k < 15; k++) {
      double d;
      d = b_slider[k];
      slider[k + 1] = d;
      b_y += d;
    }
    y_data[i] = b_y / 16.0;
    /*  write the average of the current window to y */
  }
}

/*
 * File trailer for averagingFilterCG.c
 *
 * [EOF]
 */

或者,使用带 -config:lib-lang:C++ 选项的 codegen 命令生成独立 C++ 库。将生成的 C++ 代码中的 averagingFilterCG 函数与生成的 C 代码中的函数进行比较。

codegen -config:lib -lang:c++ averagingFilterCG
Code generation successful.
type(fullfile("codegen","lib","averagingFilterCG","averagingFilterCG.cpp"))
//
// File: averagingFilterCG.cpp
//
// MATLAB Coder version            : 25.2
// C/C++ source code generated on  : 09-Aug-2025 10:00:49
//

// Include Files
#include "averagingFilterCG.h"
#include "coder_array.h"
#include <algorithm>
#include <cstring>

// Function Definitions
//
// Arguments    : const coder::array<double, 2U> &x
//                coder::array<double, 2U> &y
// Return Type  : void
//
void averagingFilterCG(const coder::array<double, 2U> &x,
                       coder::array<double, 2U> &y)
{
  double slider[16];
  double b_slider[15];
  int loop_ub;
  std::memset(&slider[0], 0, 16U * sizeof(double));
  y.set_size(1, x.size(1));
  loop_ub = x.size(1);
  for (int i{0}; i < loop_ub; i++) {
    double b_y;
    y[i] = 0.0;
    std::copy(&slider[0], &slider[15], &b_slider[0]);
    //  move one position in the buffer
    b_y = x[i];
    slider[0] = b_y;
    //  Add a new sample value to the buffer
    for (int k{0}; k < 15; k++) {
      double d;
      d = b_slider[k];
      slider[k + 1] = d;
      b_y += d;
    }
    y[i] = b_y / 16.0;
    //  write the average of the current window to y
  }
}

//
// File trailer for averagingFilterCG.cpp
//
// [EOF]
//

另请参阅

主题