Contenu principal

La traduction de cette page n'est pas à jour. Cliquez ici pour voir la dernière version en anglais.

Générer du code C/C++ à partir d’une fonction MATLAB

Cet exemple illustre le workflow recommandé pour générer du code C/C++ à partir d’une fonction MATLAB®. Les étapes de ce workflow sont les suivantes :

  1. Préparer le code MATLAB pour la génération de code.

  2. Générer et tester une fonction MEX.

  3. Générer et inspecter le code C/C++.

Cet exemple génère du code C/C++ à la ligne de commande avec la commande codegen. Pour découvrir comment générer du code avec l’application MATLAB Coder™, consultez Generate Deployable Standalone Code by Using the MATLAB Coder App.

Créer du code MATLAB et des données d’exemple

Cette étape a été ajoutée pour les besoins de l’exemple. Elle ne fait pas partie du workflow classique de génération de code.

Créez une fonction MATLAB averagingFilterML qui applique un filtre moyenneur à un signal d’entrée. Cette fonction reçoit un vecteur de valeurs de signal en entrée et renvoie un vecteur de valeurs filtrées en sortie. Le vecteur en sortie est de la même taille que celui en entrée. La fonction averagingFilterML utilise la variable slider pour représenter une fenêtre glissante de 16 valeurs de signal et calcule la valeur moyenne du signal pour chaque position de la fenêtre.

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

Générez une onde sinusoïdale bruitée comme données d’exemple puis utilisez averagingFilterML pour filtrer ces données bruitées. Tracez les données bruitées et les données filtrées dans une même figure.

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.

Étape 1 : préparer le code MATLAB pour la génération de code

Renommez la fonction averagingFilterML avec le nom averagingFilterCG. Ajoutez l’instruction %#codegen à averagingFilterCG pour demander à MATLAB Code Analyzer d’identifier les avertissements et les erreurs spécifiques à la génération de code. Pour la génération de code, le type des variables en entrée doit être défini. Spécifiez l’entrée comme un vecteur de doubles non borné avec un bloc arguments.

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

Étape 2 : générer et tester une fonction MEX

Il est important de générer et tester une fonction MEX avant de générer le code C/C++. En exécutant cette fonction MEX dans MATLAB avant de générer le code C/C++, vous pouvez détecter et corriger les erreurs run-time qui sont beaucoup plus difficiles à diagnostiquer dans le code généré. Vous pouvez également utiliser cette fonction MEX pour vérifier que le code généré fonctionne de la même manière que le code MATLAB d’origine.

Utilisez la commande codegen pour générer une fonction MEX à partir de averagingFilterCG. Testez cette fonction MEX avec la même entrée que celle passée à la fonction MATLAB d’origine, puis comparez les résultats. La fonction MEX produit la même sortie.

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.

Étape 3 : générer et inspecter le code C/C++

Utilisez la commande codegen avec l’option -config:lib pour générer une bibliothèque C autonome. Inspectez la fonction averagingFilterCG dans le code C généré.

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

Vous pouvez également utiliser la commande codegen avec les options -config:lib et -lang:C++ pour générer une bibliothèque C++ autonome. Comparez la fonction averagingFilterCG dans le code C++ généré à celle du code C généré.

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

Voir aussi

Rubriques