Hauptinhalt

Generieren von C/C++ Code aus einer MATLAB-Funktion

Dieses Beispiel stellt den empfohlenen Workflow für die Generierung von C/C++ Code aus einer MATLAB®-Funktion dar. Die Schritte dieses Workflows umfassen:

  1. Vorbereiten von MATLAB Programmcode für die Codegenerierung.

  2. Generieren und Testen der MEX-Funktion.

  3. Generieren und Untersuchen des C/C++ Codes.

Dieses Beispiel generiert C/C++ Code über die Befehlszeile mit dem Befehl codegen. Informationen zum Generieren von Code mit der MATLAB Coder™-App finden Sie unter Generate C Code by Using the MATLAB Coder App.

Erstellen von MATLAB Programmcode und Beispieldaten

Dieser Schritt wird für dieses Beispiel benötigt und ist kein typischer Schritt im Codegenerierungs-Workflow.

Erstellen Sie eine MATLAB-Funktion averagingFilterML, die als Durchschnittswertfilter für ein Eingangssignal fungiert. Diese Funktion erfasst einen Eingangsvektor mit Signalwerten und gibt einen Ausgangsvektor mit gefilterten Werten aus. Der Ausgangsvektor hat dieselbe Größe wie der Eingangsvektor. Die averagingFilterML-Funktion verwendet die Variable slider zur Darstellung eines Zeitfensters mit 16 Signalwerten und berechnet für jede Fensterposition den Signal-Durchschnittswert.

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

Generieren Sie eine verrauschte Sinuswelle als Beispieldaten und verwenden Sie averagingFilterML, um die verrauschten Daten zu filtern. Plotten Sie die verrauschten Daten und die gefilterten Daten im selben Fenster.

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.

Schritt 1: Vorbereiten von MATLAB Programmcode für die Codegenerierung

Benennen Sie die Funktion averagingFilterML in averagingFilterCG um. Fügen Sie die Anweisung %#codegen zu averagingFilterCG hinzu, damit der MATLAB Code Analyzer Warn- und Fehlermeldungen für die Codegenerierung ausgibt. Für die Codegenerierung müssen die Eingangsvariablentypen definiert sein. Legen Sie den Eingang als unbeschränkten Vektor doubles mit einem arguments-Block fest.

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

Schritt 2: Generieren und Testen der MEX-Funktion

Es ist wichtig, eine MEX-Funktion zu generieren und zu testen, bevor Sie C/C++ Code generieren. Wenn Sie die MEX-Funktion in MATLAB ausführen, bevor Sie C/C++ Code erstellen, können Sie Laufzeitfehler erkennen und beheben, die im generierten Code erheblich schwerer zu diagnostizieren sind. Zudem können Sie mit der MEX-Funktion verifizieren, dass Ihr generierter Code ähnlich wie der ursprüngliche MATLAB Programmcode funktioniert.

Verwenden Sie den Befehl codegen, um eine MEX-Funktion aus averagingFilterCG zu generieren. Testen Sie die MEX-Funktion mit derselben Eingabe, die Sie an die ursprüngliche MATLAB-Funktion übergeben haben, und vergleichen Sie die Ergebnisse. Die MEX-Funktion erzeugt dieselbe Ausgabe.

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.

Schritt 3: Generieren und Untersuchen von C/C++ Code

Verwenden Sie den Befehl codegen mit der Option -config:lib, um eine eigenständige C Bibliothek zu generieren. Untersuchen Sie die Funktion averagingFilterCG im generierten C Code.

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]
 */

Alternativ können Sie den Befehl codegen mit den Optionen -config:lib und -lang:C++ verwenden, um eine eigenständige C++ Bibliothek zu generieren. Vergleichen Sie die Funktion averagingFilterCG im generierten C++ Code mit der Funktion im generierten C Code.

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]
//

Siehe auch

Themen