文档

包生成的代码作为共享库

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

关于已生成的共享库

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

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

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

  • 对执行模型代码至关重要的函数

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

  • 在Windows上,使用Dependency Walker实用程序,可以从下面下载http://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;typedef struct {int32_T输出;} ExternalOutputs_rtwdemo_shrlib;# endif / * _APP_MAIN_HEADER_ * /

应用程序C代码示例

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

#if (define (_WIN32)||define (_WIN64)) /* WINDOWS */ #include < WINDOWS .h> #define GETSYMBOLADDR GetProcAddress #define LOADLIB LoadLibrary #define CLOSELIB FreeLibrary #else /* UNIX */ #include < dlf.com h> #define GETSYMBOLADDR dlsyp #define LOADLIB dlopen #define CLOSELIB dlclose #endif int 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. txt ");所以“RTLD_LAZY);# endif # endif……返回(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_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"); #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系统目标文件只支持C语言(不支持c++金宝app)。当您选择ert_shrlib.tlc,模型配置参数语言是灰色的。

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

相关的话题