Funções Matlab embarcadas no Simulink: coder.cinclude() sem header para funções C/C++ customizadas
É bem conhecido que você pode usar coder.ceval(...) em conjunto com coder.cinclude(...) para executar funções C/C++ externas a partir de funções matlab embarcadas:
function y = mysquare(x) %#codegen
coder.cinclude('mysquare.h');
y = 0.0;
coder.ceval('mysquare', coder.ref(x), coder.wref(y));
endO que é menos conhecido é que você pode incluir código C/C++ “inline” na chamada coder.cinclude(), embora isso seja um tanto elaborado. Isso é muito útil para que você não precise gerenciar arquivos header.
Note que ao compilar seu modelo, o Simulink/Matlab coder ainda precisa verificar se compila corretamente, então você precisa garantir que a compilação “standalone” do seu código seja possível.
function y = mysquare(x) %#codegen
% Usar coder.cinclude() apenas significa que será incluído no topo do
% arquivo, portanto podemos usá-lo indevidamente para incluir a função inteira em vez de
% apenas o include do header.
coder.cinclude(sprintf(...
['<math.h>\n' ... % Include fictício para terminar a linha #include
'inline void mysquare(const double* x, double* y) {\n' ...
' *y = (*x) * (*x);\n' ...
'}'] ...
));
y = 0.0;
coder.ceval('mysquare', coder.ref(x), coder.wref(y));
endLembre-se que é absolutamente essencial usar o include fictício <math.h> para terminar a linha #include!
Isso gerará o seguinte código no arquivo header:
#include <math.h>
inline void mysquare(const double* x, double* y)
{
*y = (*x) * (*x);
}e, com níveis suficientes de comentários ativados, este é o código do arquivo .cpp gerado
/* MATLAB Function 'Logic/S-Process emulation/MATLAB Function1': '<S7>:1' */
/* '<S7>:1:5' coder.cinclude(sprintf(... */
/* '<S7>:1:6' ['<math.h>\n' ... % Dummy include to terminate the #include line */
/* '<S7>:1:7' 'inline void mysquare(const double* x, double* y) {\n' ... */
/* '<S7>:1:8' ' *y = (*x) * (*x);\n' ... */
/* '<S7>:1:9' '}'] ... */
/* '<S7>:1:10' )); */
/* '<S7>:1:11' y = 0.0; */
/* '<S7>:1:12' coder.ceval('mysquare', coder.ref(x), coder.wref(y)); */
mysquare(&rtb_y_l, &rtb_y);