使用遗留代码工具将外部代码调用导入到生成的代码中
遗留代码工具和代码生成
您可以使用Simulink®遗留代码工具为遗留代码或自定义代码生成完全内联的C MEX s函数。s函数针对嵌入式组件(如设备驱动程序和查找表)进行了优化,并且它们调用现有的C或c++函数。
请注意
遗留代码工具可以与c++函数交互,但不能与c++对象交互。要解决这个问题,以便该工具能够与c++对象交互,请参见遗留代码工具的限制.
您可以使用该工具:
如果您想在您打算为其生成代码的模型中包含这些类型的s函数,请使用该工具生成TLC块文件。TLC块文件指定为模型生成的代码如何调用现有的C或c++函数。
如果s -函数依赖于除包含s -函数动态加载可执行文件的文件夹之外的文件夹中的文件,则使用该工具生成一个sFunction
_makecfg.m
或rtwmakecfg.m
文件的s函数。当您构建包含s函数的模型时,生成文件将维护这些依赖关系。例如,对于一些应用程序,例如自定义目标,您可能希望将文件定位到目标特定的位置。构建过程寻找sFunction
_makecfg.m
或rtwmakecfg.m
在与S-function动态加载可执行文件相同的文件夹中,并调用文件中的函数。
有关更多信息,请参见使用遗留代码工具集成C函数.
为代码生成生成内联的S-Function文件
根据应用程序的代码生成需求,为使用s函数的模型生成代码,请执行以下任一操作:
生成一个
. cpp
文件的内联s函数。在“遗留代码工具”数据结构中,设置Options.singleCPPMexFile
字段真正的
然后再从已有的C函数生成s函数源文件。例如:def.Options.singleCPPMexFile = true;legacy_code (sfcn_cmex_generate, def);
为内联s函数生成一个源文件和一个TLC块文件。例如:
def.Options.singleCPPMexFile = false;legacy_code (sfcn_cmex_generate, def);legacy_code (sfcn_tlc_generate, def);
singleCPPMexFile局限性
您不能设置singleCPPMexFile
字段真正的
如果
Options.language =“c++”
对象使用下列Simulink对象之一
IsAlias
属性设置为真正的
:仿真软件。公共汽车
仿真软件。AliasType
仿真软件。NumericType
遗留代码工具功能规范包括
void *
或void * *
表示状态参数的标量工作数据HeaderFiles
遗留代码工具结构的字段指定多个头文件
将代码样式设置应用到遗留函数
将代码样式的模型配置参数应用到遗留函数:
初始化遗留代码工具数据结构。例如:
Def = legacy_code('初始化');
在数据结构中设置
Options.singleCPPMexFile
字段真正的
.例如:def.Options.singleCPPMexFile = true;
要检查设置,输入:
def.Options.singleCPPMexFile
singleCPPMexFile局限性
您不能设置singleCPPMexFile
字段真正的
如果
Options.language =“c++”
对象使用下列Simulink对象之一
IsAlias
属性设置为真正的
:仿真软件。公共汽车
仿真软件。AliasType
仿真软件。NumericType
遗留代码工具功能规范包括
void *
或void * *
表示状态参数的标量工作数据HeaderFiles
遗留代码工具结构的字段指定多个头文件
地址依赖于不同位置的文件
默认情况下,遗留代码工具假定s函数所依赖的文件与s函数可动态加载的可执行文件位于同一文件夹中。如果s函数依赖于驻留在其他地方的文件,并且您正在使用模板makefile构建过程,则生成一个sFunction
_makecfg.m
或rtwmakecfg.m
文件对于s函数。例如,如果遗留代码工具数据结构将编译资源定义为路径名,则可能生成此文件。
来生成sFunction
_makecfg.m
或rtwmakecfg.m
文件,调用legacy_code
函数与“sfcn_makecfg_generate”
或“rtwmakecfg_generate”
作为第一个参数,遗留代码工具数据结构的名称作为第二个参数。例如:
legacy_code (sfcn_makecfg_generate, lct_spec);
如果您在同一个文件夹中使用多个注册文件,并为每个文件生成一个s函数,只需对legacy_code
,呼唤legacy_code
指定“sfcn_makecfg_generate”
或“rtwmakecfg_generate”
必须对所有注册文件通用。有关更多信息,请参见处理多个注册文件.
例如,如果你定义def
作为遗留代码工具结构的数组,您调用legacy_code
与“sfcn_makecfg_generate”
一次。
Defs = [defs1(:);defs2(:);defs3(:)];legacy_code (sfcn_makecfg_generate, def);
有关更多信息,请参见构建对s - function的支持.
为模拟和代码生成部署s函数
您可以部署s函数您用遗留代码工具生成的,以便其他人可以使用它们。要部署s函数进行模拟和代码生成,请共享以下文件:
注册文件
编译后可动态加载的可执行文件
TLC块文件
sFunction
_makecfg.m
或rtwmakecfg.m
文件生成的s函数所依赖的头文件、源文件和包含文件
当你使用这些部署文件时:
在使用Simulink模型中部署的文件之前,将包含s函数文件的文件夹添加到MATLAB中®路径。
如果遗留代码工具数据结构将所需文件注册为绝对路径,且文件的位置发生更改,则重新生成
sFunction
_makecfg.m
或rtwmakecfg.m
文件。
集成外部c++对象
遗留代码工具可以与c++函数交互,但不能与c++对象交互。使用前面的示例作为起点,下面是如何绕过此限制的示例。
的类定义
加法器
在一个新文件中adder_cpp.hpp
.添加三个新宏,动态分配新的加法器
对象,调用该方法add_one ()
,释放分配的内存。每个宏都有一个指向对象的指针加法器
对象。因为遗留代码工具调用的每个函数都必须具有类似c的签名,所以指针被缓存并作为void *
.然后必须显式转换为加法器*
在宏中。的新类定义加法器
:#ifndef _ADDER_CPP_ #定义_ADDER_CPP_类加法器{private: int int_state;Public: adder(): int_state(0) {};Int add_one(Int increment);Int get_val(){返回int_state;};};//实现为宏的方法包装器#define createAdder(work1) \ *(work1) = new addder #define deleteAdder(work1) \ delete(static_cast
(*(work1))) #define adderOutput(work1, u1) \ (static_cast ((work1)))->add_one(u1) #endif /* _ADDER_CPP_ */ 更新
adder_cpp.cpp
.通过类修改,而不是一个全局实例,每个生成的s函数都管理自己的实例加法器
对象。#include " adder_cppp .hpp" int addder::add_one(int increment) {int_state += increment;返回int_state;}
更新
rtwdemo_sfun_adder_cpp.cpp
更改如下:StartFcnSpec
调用分配新对象的宏加法器
对象,并缓存指针。def.StartFcnSpec = 'createAdder(void **work1)';
OutputFcnSpec
调用调用该方法的宏add_one ()
并提供特定的s函数加法器
对象的指针。def.OutputFcnSpec = 'int32 y1 = adderOutput(void *work1, int32 u1)';
TerminateFcnSpec
调用释放内存的宏。def.TerminateFcnSpec = 'deleteAdder(void **work1)';
另请参阅
相关的话题
- 使用遗留代码工具集成C函数
- 遗留代码工具示例
- 从模型和生成代码调用外部C代码(嵌入式编码)