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:
Vorbereiten von MATLAB Programmcode für die Codegenerierung.
Generieren und Testen der MEX-Funktion.
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;
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;
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] //