c #include如何找到文件_使用 MATLAB Function 模块集成 C 代码

0e521bf60c50539594f32313d1987c1e.png

检索   使用 MATLAB Function 模块集成 C 代码

从 Simulink 模型中调用 C 代码

您可以使用 MATLAB Function 模块从 Simulink® 模型中调用外部 C 代码。请执行下列简要步骤:

首先找到包含源 (.c) 和头 (.h) 文件的现有 C 代码。

在 MATLAB Function 模块中,输入调用 C 代码的 MATLAB® 代码。使用函数 coder.ceval。要通过引用传递数据,请使用 coder.ref、coder.rref 或 coder.wref。

在 Model Configuration Parameters 对话框的 Simulation Target 窗格中,指定用于仿真的 C 源文件和头文件。使用双引号引起头文件,例如 #include "program.h"。如果需要访问位于工作文件夹之外的 C 源文件和头文件,请在 Simulation Target 窗格的 Include Directories 文本框中列出文件的路径。

或者,使用 coder.cinclude 和 coder.updateBuildInfo 函数在 MATLAB 代码中指定源文件和头文件。要开发与外部代码的接口,您可以使用 coder.ExternalDependency 类。要查看支持的工作流,请参阅Import custom code。

测试 Simulink 模型并确保它正常工作。

如果您拥有 Simulink Coder™ 许可证,则可以使用此方法为目标生成代码。要使用相同的源文件和头文件进行代码生成,请在 Code Generation > Custom Code 窗格中点击 Use the same custom code settings as Simulation Target。还可以指定不同的源文件和头文件。

要条件化您的代码以执行仿真的不同命令和代码生成,可以使用 coder.target 函数。

在 MATLAB Function 模块中使用 coder.ceval

此示例说明如何从 MATLAB Function 模块中调用简单的 C 程序 doubleIt。

1.在当前工作文件夹中创建源文件 doubleIt.c。

#include "doubleIt.h"

double doubleIt(double u)

{

return(u*2.0);

}

2.在当前工作文件夹中创建头文件 doubleIt.h。

#ifndef MYFN

#define MYFN

double doubleIt(double u);

#endif

3.新建一个 Simulink 模型。将其保存为 myModel。

4.在 Library Browser 的 User-Defined Functions 中,将 MATLAB Function 模块添加到模型中,然后双击该模块打开编辑器。

5.输入调用 doubleIt 程序的代码:

function y = callingDoubleIt(u)

y = 0.0;

y = coder.ceval('doubleIt',u);

6.将值为 3.5 的 Constant 模块连接到 MATLAB Function 模块的输入端口。

7.将 Display 模块连接到输出端口。

30c1a491ab233342b564c4bfcd765c8c.png

8.在 Model Configuration Parameters 对话框中,打开 Simulation Target 窗格。

9.在 Insert custom C code in generated 部分,从列表中选择 Header file,然后在 Header file 文本框中输入 #include "doubleIt.h"。

10.在 Additional build information 部分中,从列表中选择 Source files,在 Source files 文本框中输入 doubleIt.c,然后点击 OK。

8779fda90d14cb60d9ba1cab7a6347b6.png

11.运行仿真。值 7 将出现在 Display 模块上。

控制导入的总线和枚举类型定义

此过程仅适用于仿真。

Simulink 会为 MATLAB Function 模块和 Stateflow® 生成代码以进行模型仿真。使用 MATLAB Function 模块或 Stateflow 调用外部 C 代码时,您可以控制在模型仿真中导入的总线和枚举的类型定义。

Simulink 可以生成类型定义,您也可以提供包含类型定义的头文件。您可以使用 Model Configuration Parameters 对话框中的 Generate typedefs for imported bus and enumeration types 复选框来控制此行为。

要提供定义枚举和总线类型的自定义头文件,请执行以下操作:

清除 Generate typedefs for imported bus and enumeration types 复选框。

在 Simulation Target 窗格上的 Header file 文本框中列出头文件。

要配置 Simulink 自动生成类型定义,请执行以下操作:

选中 Generate typedefs for imported bus and enumeration types 复选框。

不要列出与总线或枚举对应的头文件。

coder.ceval

调用外部 C/C++ 函数全页折叠

语法

coder.ceval(cfun_name)

coder.ceval(cfun_name,cfun_arguments)

coder.ceval('-global',cfun_name)

coder.ceval('-global',cfun_name,cfun_arguments)

cfun_return = coder.ceval(___)

说明

示例

coder.ceval(cfun_name) 执行 cfun_name 指定的外部 C/C++ 函数。在外部 C/C++ 源文件或库中定义 cfun_name。将外部源代码、库和头文件提供给代码生成器。

示例

coder.ceval(cfun_name,cfun_arguments) 使用参数 cfun_arguments 执行 cfun_name。cfun_arguments 是按照 cfun_name 要求的顺序排列的逗号分隔的输入参数列表。

默认情况下,只要 C/C++ 支持按值传递参数,coder.ceval 就会按值向 C/C++ 函数传递参数。要使 coder.ceval 按引用传递参数,请使用 coder.ref、coder.rref 和 coder.wref 构造。如果 C/C++ 不支持按值传递参数,例如说参数是一个数组,则 coder.ceval 将按引用传递参数。如果您不使用 coder.ref、coder.rref 或 coder.wref,则生成的代码中可能会出现参数的副本,以强制执行用于数组的 MATLAB® 语义。

示例

coder.ceval('-global',cfun_name) 执行 cfun_name,并指示 cfun_name 使用一个或多个 MATLAB 全局变量。然后,代码生成器可以产生与此全局变量用法一致的代码。

coder.ceval('-global',cfun_name,cfun_arguments) 使用参数 cfun_arguments 执行 cfun_name,并指示 cfun_name 使用一个或多个 MATLAB 全局变量。

示例

cfun_return = coder.ceval(___) 执行 cfun_name 并返回单个标量值 cfun_return,它对应于 C/C++ 函数在 return 语句中返回的值。为了与 C/C++ 保持一致,coder.ceval 只能返回标量值。它不能返回数组。可以将此选项与前面语法中的任何输入参数组合一起使用。

示例

调用外部 C 函数

从要从其生成 C 代码的 MATLAB 函数调用 C 函数 foo(u)。

为函数 foo 创建 C 头文件 foo.h,该函数接受两个 double 类型的输入参数,并返回 double 类型的值。

double foo(double in1, double in2);

编写 C 函数 foo.c。

#include

#include

#include "foo.h"

double foo(double in1, double in2)

{

return in1 + in2;

}

编写使用 coder.ceval 调用 foo 的函数 callfoo。将源代码和头文件提供给函数中的代码生成器。

function y = callfoo  %#codegen

y = 0.0;

if coder.target('MATLAB')

% Executing in MATLAB, call MATLAB equivalent of

% C function foo

y = 10 + 20;

else

% Executing in generated code, call C function foo

coder.updateBuildInfo('addSourceFiles','foo.c');

coder.cinclude('foo.h');

y = coder.ceval('foo', 10, 20);

end

end

为函数 callfoo 生成 C 库代码。codegen 函数在 \codegen\lib\callfoo 子文件夹中生成 C 代码。

codegen -config:lib callfoo -report

调用 C 库函数

从 MATLAB 代码中调用 C 库函数:

编写 MATLAB 函数 myabsval。

function y = myabsval(u)

%#codegen

y = abs(u);

通过使用 -args 选项指定输入参数的大小、类型和复/实性,为 myabsval 生成 C 静态库。

codegen -config:lib myabsval -args {0.0}

codegen 函数在文件夹 \codegen\lib\myabsval 中创建库文件 myabsval.lib 和头文件 myabsval.h。(库文件扩展名可以根据您的平台而有所不同。)它在同一个文件夹中生成函数 myabsval_initialize 和 myabsval_terminate。

编写一个 MATLAB 函数,以使用 coder.ceval 调用生成的 C 库函数。

function y = callmyabsval(y)

%#codegen

% Check the target. Do not use coder.ceval if callmyabsval is

% executing in MATLAB

if coder.target('MATLAB')

% Executing in MATLAB, call function myabsval

y = myabsval(y);

else

% add the required include statements to generated function code

coder.updateBuildInfo('addIncludePaths','$(START_DIR)\codegen\lib\myabsval');

coder.cinclude('myabsval_initialize.h');

coder.cinclude('myabsval.h');

coder.cinclude('myabsval_terminate.h');

% Executing in the generated code.

% Call the initialize function before calling the

% C function for the first time

coder.ceval('myabsval_initialize');

% Call the generated C library function myabsval

y = coder.ceval('myabsval',y);

% Call the terminate function after

% calling the C function for the last time

coder.ceval('myabsval_terminate');

end

生成 MEX 函数 callmyabsval_mex。在命令行中提供生成的库文件。

codegen -config:mex callmyabsval codegen\lib\myabsval\myabsval.lib -args {-2.75}

您可以使用 coder.updateBuildInfo 在函数中指定该库,而不是在命令行中提供库。使用此选项可预配置编译。将以下行添加到 else 模块中:

coder.updateBuildInfo('addLinkObjects','myabsval.lib','$(START_DIR)\codegen\lib\myabsval',100,true,true);

运行调用库函数 myabsval 的 MEX 函数 callmyabsval_mex。

callmyabsval_mex(-2.75)

ans =

2.7500

调用 MATLAB 函数 callmyabsval。

callmyabsval(-2.75)

ans =

2.7500

callmyabsval 函数在 MATLAB 和代码生成中的执行均展示出了预期的行为。

调用使用全局变量的 C 函数

调用修改全局变量的 C 函数时,请使用 '-global' 标志。

编写调用 C 函数 addGlobal 的 MATLAB 函数 useGlobal。使用 '-global' 标志向代码生成器指示 C 函数使用全局变量。

function y = useGlobal()

global g;

t = g;

% compare execution with/without '-global' flag

coder.ceval('-global','addGlobal');

y = t;

end

为函数 addGlobal 创建 C 头文件 addGlobal.h。

void addGlobal(void);

在文件 addGlobal.c 中编写 C 函数 addGlobal。此函数包含代码生成器在您为函数 useGlobal 生成代码时创建的头文件 useGlobal_data.h。此头文件包含 g 的全局变量声明。

#include "addGlobal.h"

#include "useGlobal_data.h"

void addGlobal(void) {

g++;

}

为 useGlobal 生成 MEX 函数。要定义代码生成器的输入,请在工作区中声明全局变量。

global g;

g = 1;

codegen useGlobal -report addGlobal.h addGlobal.c

y = useGlobal_mex();

使用 '-global' 标志时,MEX 函数产生结果 y = 1。'-global' 标志向代码生成器指示 C 函数可能修改全局变量。对于 useGlobal,代码生成器产生以下代码:

real_T useGlobal(const emlrtStack *sp)

{

real_T y;

(void)sp;

y = g;

addGlobal();

return y;

}

如果没有 '-global' 标志,MEX 函数将产生 y = 2。因为没有关于 C 函数修改 g 的指示,代码生成器假定 y 和 g 是相同的。将生成以下 C 代码:

real_T useGlobal(const emlrtStack *sp)

{

(void)sp;

addGlobal();

return g;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值