主要内容

包生成的代码作为共享库

如果你有一个嵌入式编码器®许可,您可以通过将代码构建为共享库(windows),将从模型组件生成的源代码打包,以便于分发和共享使用®动态链接库(. dllUNIX),®共享对象(所以),或Macintosh OS X动态库(. dylib).您或其他人可以将共享库集成到运行在Windows、UNIX或Windows上的应用程序中Macintosh OS X开发计算机。生成的. dll所以,或. dylib文件可在不同的应用程序之间共享,并且无需重新编译使用它的应用程序即可升级。

关于生成的共享库

通过将代码生成器配置为使用系统目标文件来构建共享库ert_shrlib.tlc。系统目标文件导出的代码生成:

  • 类型的变量和信号ExportedGlobal作为数据

  • 实时模型结构(模型_M)作为数据

  • 执行模型代码所必需的函数

查看生成的共享库中包含的符号列表:

  • 在Windows上,使用Dependency Walker实用程序,可从https://www.dependencywalker.com

  • 在UNIX上,使用nm - d模型所以

  • Macintosh OS X,使用nm - g模型. dylib

生成和使用共享库。

  1. 生成模型代码的共享库版本

  2. 创建应用程序代码来加载和使用共享库文件

生成模型代码的共享库版本

生成模型代码的共享库版本:

  1. 打开您的模型并将其配置为使用ert_shrlib.tlc系统目标文件。

    选择ert_shrlib.tlc系统目标文件导致构建过程将模型代码的共享库版本生成到当前工作文件夹中。选择不会更改代码生成器为您的模型生成的代码。

  2. 构建模型。

  3. 构建完成后,检查模型子文件夹中生成的代码,并检查. dll所以,或. dylib文件在当前文件夹中。

创建应用程序代码以使用共享库

为了说明应用程序代码如何加载共享库文件并访问其函数和数据,MathWorks提供了这个模型rtwdemo_shrlib

请注意

操作之前导航到一个可写的工作文件夹rtwdemo_shrlib脚本。

在模型中,单击蓝色按钮以运行脚本。脚本:

  1. 从模型构建共享库文件(例如,rtwdemo_shrlib_win64.dll在64位Windows上)。

  2. 编译并链接示例应用程序;rtwdemo_shrlib_app,它加载并使用共享库文件。

  3. 执行示例应用程序。

提示

显式链接是可移植性的首选。然而,在Windows系统上,ert_shrlib系统目标文件生成并保留. lib文件以支持隐式链金宝app接。

要使用隐式链接,生成的头文件需要稍加修改,以便与生成的C文件一起使用。例如,如果您正在使用Visual c++®,声明使用__declspec (dllimport)要从共享库文件隐式导入的数据前面。

该模型使用以下示例应用程序文件,这些文件位于文件夹中matlabroot/工具箱/ rtw / rtwdemos / shrlib_demo开放).

文件 描述
rtwdemo_shrlib_app.h 示例应用程序头文件
rtwdemo_shrlib_app.c 加载并使用为模型生成的共享库文件的示例应用程序
run_rtwdemo_shrlib_app.m 用于编译、链接和执行示例应用程序的脚本

您可以通过单击模型窗口中的白色按钮来查看这些文件。另外,运行脚本会将相关的源代码和生成的代码文件放在当前文件夹中。这些文件可以用作模板,用于为您自己的ERT共享库文件编写应用程序代码。

以下各节提供示例应用程序文件的关键摘录。

应用程序头文件示例

示例应用程序头文件rtwdemo_shrlib_app.h包含模型外部输入和输出的类型声明。

#ifndef _APP_MAIN_HEADER_ #define _APP_MAIN_HEADER_ typedef struct {int32_T输入;} ExternalInputs_rtwdemo_shrlib;int32_T输出;} ExternalOutputs_rtwdemo_shrlib;# endif / * _APP_MAIN_HEADER_ * /

示例应用程序C代码

示例应用程序rtwdemo_shrlib_app.c包括以下用于动态加载共享库文件的代码。注意,根据平台的不同,代码会调用Windows或UNIX库命令。

#if (defined(_WIN32)||defined(_WIN64)) /* WINDOWS */ #include < WINDOWS .h> #define GETSYMBOLADDR GetProcAddress #define LOADLIB LoadLibrary #define CLOSELIB FreeLibrary #else /* UNIX */ #include < dlfcnh > #define GETSYMBOLADDR dlsym #define LOADLIB dlopen #define CLOSELIB dlclose # endifint main() {void* handleLib;…#if define (_WIN64) handleLib = LOADLIB("./rtwdemo_shrlib_win64.dll");#else #if define (_WIN32) handleLib = LOADLIB("./rtwdemo_shrlib_win32.dll");#else /* UNIX */ handleLib = LOADLIB("./rtwdemo_shrlib. "所以“RTLD_LAZY);#结束#结束…返回(CLOSELIB (handleLib));}

下面的代码摘录显示了C应用程序如何访问模型导出的数据和函数。请注意用于添加用户定义初始化、步骤和终止代码的钩子。

int32_T我;…空白(* mdl_initialize) (boolean_T);空白(* mdl_step)(空白);空白(* mdl_terminate)(空白);ExternalInputs_rtwdemo_shrlib (* mdl_Uptr);ExternalOutputs_rtwdemo_shrlib (* mdl_Yptr);uint8_T (* sum_outptr);…#if (defined(LCCDLL)||defined(BORLANDCDLL)) /*当DLL链接到LCC或BORLANDC */ mdl_initialize =(void(*)(boolean))GETSYMBOLADDR(handleLib, "_rtwdemo_shrlib_initialize"); mdl_step =(void(*)(void))GETSYMBOLADDR(handleLib , "_rtwdemo_shrlib_step"); mdl_terminate =(void(*)(void))GETSYMBOLADDR(handleLib , "_rtwdemo_shrlib_terminate"); mdl_Uptr =(ExternalInputs_rtwdemo_shrlib*)GETSYMBOLADDR(handleLib , "_rtwdemo_shrlib_U"); mdl_Yptr =(ExternalOutputs_rtwdemo_shrlib*)GETSYMBOLADDR(handleLib , "_rtwdemo_shrlib_Y"); sum_outptr =(uint8_T*)GETSYMBOLADDR(handleLib , "_sum_out"); #else mdl_initialize =(void(*)(boolean_T))GETSYMBOLADDR(handleLib , "rtwdemo_shrlib_initialize"); mdl_step =(void(*)(void))GETSYMBOLADDR(handleLib , "rtwdemo_shrlib_step"); mdl_terminate =(void(*)(void))GETSYMBOLADDR(handleLib , "rtwdemo_shrlib_terminate"); mdl_Uptr =(ExternalInputs_rtwdemo_shrlib*)GETSYMBOLADDR(handleLib , "rtwdemo_shrlib_U"); mdl_Yptr =(ExternalOutputs_rtwdemo_shrlib*)GETSYMBOLADDR(handleLib , "rtwdemo_shrlib_Y"); sum_outptr =(uint8_T*)GETSYMBOLADDR(handleLib , "sum_out"); #endif if ((mdl_initialize && mdl_step && mdl_terminate && mdl_Uptr && mdl_Yptr && sum_outptr)) { /* === user application initialization function === */ mdl_initialize(1); /* insert other user defined application initialization code here */ /* === user application step function === */ for(i=0;i<=12;i++){ mdl_Uptr->Input = i; mdl_step(); printf("Counter out(sum_out): %d\tAmplifier in(Input): %d\tout(Output): %d\n", *sum_outptr, i, mdl_Yptr->Output); /* insert other user defined application step function code here */ } /* === user application terminate function === */ mdl_terminate(); /* insert other user defined application termination code here */ } else { printf("Cannot locate the specified reference(s) in the shared library.\n"); return(-1); }

示例应用脚本

应用程序脚本run_rtwdemo_shrlib_app加载并重建模型,然后编译、链接并执行模型的共享库目标文件。您可以通过打开查看脚本源文件rtwdemo_shrlib并单击白色按钮查看源代码。该脚本为编译、链接和执行构建平台相关的命令字符向量,这些命令字符向量可能适用于您的开发环境。要运行脚本,请单击蓝色按钮。

请注意

运行run_rtwdemo_shrlib_app脚本,而不首先打开rtwdemo_shrlib模型,导航到一个可写的工作文件夹,并发出以下MATLAB®命令:

目录(fullfile (matlabroot,“工具箱”,“环球套票”、“rtwdemos”,“shrlib_demo”))

请注意

在一行中两次调用terminate函数是无效的。terminate函数清除指针并将其设置为NULL。第二次调用该函数将取消对空指针的引用,并导致程序失败。

共享库限制

以下限制适用于构建共享库:

  • 的代码生成ert_shrlib.tlc系统目标文件导出如下数据:

    • 类型的变量和信号ExportedGlobal

    • 实时模型结构(模型_M

  • 对于包含函数调用子系统的模型,为函数调用子系统生成代码ert_shrlib.tlc系统目标文件只向共享库导出与initialize和terminate入口点函数相关的符号。

  • 的代码生成ert_shrlib.tlc系统目标文件只支持C语言(不支持c++金宝app)。当你选择ert_shrlib.tlc、型号配置参数语言是灰色的。

  • 要使用生成的共享库重建模型仿真,应用程序作者必须在原始应用程序中维护系统和共享库函数调用之间的时序。时间需要保持一致,以便您可以比较模拟和集成结果。如果从支持模型配置参数的模型生成共享库,则需要考虑其他仿真问题金宝app支持:连续时间单个输出/更新功能。有关更多信息,请参见单个输出/更新功能依赖关系。

相关的话题