Main Content

Package Generated Code as Shared Libraries

If you have an Embedded Coder®license, you can package generated source code from a model component for easy distribution and shared use by building the code as a shared library—Windows®dynamic link library (.dll), UNIX®shared object (.so), orMacintosh OS Xdynamic library (.dylib). You or others can integrate the shared library into an application that runs on a Windows, UNIX, orMacintosh OS Xdevelopment computer. The generated.dll,.so, or.dylibfile is shareable among different applications and upgradeable without having to recompile the applications that use it.

About Generated Shared Libraries

You build a shared library by configuring the code generator to use the system target fileert_shrlib.tlc. Code generation for that system target file exports:

  • Variables and signals of typeExportedGlobalas data

  • Real-time model structure (model_M) as data

  • Functions essential to executing your model code

To view a list of symbols contained in a generated shared library:

  • On Windows, use the Dependency Walker utility, downloadable fromhttp://www.dependencywalker.com

  • On UNIX, usenm -Dmodel.so

  • OnMacintosh OS X, usenm -gmodel.dylib

生成和使用共享库:

  1. Generate a shared library version of your model code

  2. Create application code to load and use your shared library file

Generate Shared Library Version of Model Code

To generate a shared library version of your model code:

  1. 打开你的模型和配置它se theert_shrlib.tlcsystem target file.

    Selecting theert_shrlib.tlcsystem target file causes the build process to generate a shared library version of your model code into your current working folder. The selection does not change the code that the code generator produces for your model.

  2. Build the model.

  3. After the build completes, examine the generated code in the model subfolder and examine the.dll,.so, or.dylibfile in your current folder.

Create Application Code to Use Shared Library

为了演示应用程序代码可以加载一个莎尔ed library file and access its functions and data, MathWorks provides the modelrtwdemo_shrlib.

Note

Navigate to a writable working folder before running thertwdemo_shrlibscript.

In the model, click the blue button to run a script. The script:

  1. Builds a shared library file from the model (for example,rtwdemo_shrlib_win64.dllon 64-bit Windows).

  2. Compiles and links an example application,rtwdemo_shrlib_app, that loads and uses the shared library file.

  3. Executes the example application.

Tip

Explicit linking is preferred for portability. However, on Windows systems, theert_shrlibsystem target file generates and retains the.libfile to support implicit linking.

To use implicit linking, the generated header file needs a small modification for you to use it with the generated C file. For example, if you are using Visual C++®,声明__declspec(dllimport)in front of data to be imported implicitly from the shared library file.

The model uses the following example application files, which are located in the foldermatlabroot/toolbox/rtw/rtwdemos/shrlib_demo(open).

File Description
rtwdemo_shrlib_app.h Example application header file
rtwdemo_shrlib_app.c Example application that loads and uses the shared library file generated for the model
run_rtwdemo_shrlib_app.m Script to compile, link, and execute the example application

You can view each of these files by clicking white buttons in the model window. Additionally, running the script places the relevant source and generated code files in your current folder. The files can be used as templates for writing application code for your own ERT shared library files.

The following sections present key excerpts of the example application files.

Example Application Header File

The example application header filertwdemo_shrlib_app.hcontains type declarations for the model's external input and output.

#ifndef _APP_MAIN_HEADER_ #define _APP_MAIN_HEADER_ typedef struct { int32_T Input; } ExternalInputs_rtwdemo_shrlib; typedef struct { int32_T Output; } ExternalOutputs_rtwdemo_shrlib; #endif /*_APP_MAIN_HEADER_*/

Example Application C Code

The example applicationrtwdemo_shrlib_app.cincludes the following code for dynamically loading the shared library file. Notice that, depending on platform, the code invokes Windows or UNIX library commands.

#if (defined(_WIN32)||defined(_WIN64)) /* WINDOWS */ #include  #define GETSYMBOLADDR GetProcAddress #define LOADLIB LoadLibrary #define CLOSELIB FreeLibrary #else /* UNIX */ #include  #define GETSYMBOLADDR dlsym #define LOADLIB dlopen #define CLOSELIB dlclose #endif int main() { void* handleLib; ... #if defined(_WIN64) handleLib = LOADLIB("./rtwdemo_shrlib_win64.dll"); #else #if defined(_WIN32) handleLib = LOADLIB("./rtwdemo_shrlib_win32.dll"); #else /* UNIX */ handleLib = LOADLIB("./rtwdemo_shrlib.so", RTLD_LAZY); #endif #endif ... return(CLOSELIB(handleLib)); }

The following code excerpt shows how the C application accesses the model's exported data and functions. Notice the hooks for adding user-defined initialization, step, and termination code.

int32_T i; ... void (*mdl_initialize)(boolean_T); void (*mdl_step)(void); void (*mdl_terminate)(void); ExternalInputs_rtwdemo_shrlib (*mdl_Uptr); ExternalOutputs_rtwdemo_shrlib (*mdl_Yptr); uint8_T (*sum_outptr); ... #if (defined(LCCDLL)||defined(BORLANDCDLL)) /* Exported symbols contain leading underscores when DLL is linked with LCC or 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); }

Example Application Script

The application scriptrun_rtwdemo_shrlib_apploads and rebuilds the model, and then compiles, links, and executes the model's shared library target file. You can view the script source file by openingrtwdemo_shrliband clicking a white button to view source code. The script constructs platform-dependent command character vectors for compilation, linking, and execution that may apply to your development environment. To run the script, click the blue button.

Note

To run therun_rtwdemo_shrlib_appscript without first opening thertwdemo_shrlibmodel, navigate to a writable working folder and issue the following MATLAB®command:

addpath(fullfile(matlabroot,'toolbox','rtw','rtwdemos','shrlib_demo'))

Note

It is invalid to invoke the terminate function twice in a row. The terminate function clears pointers and sets them to NULL. Invoking the function a second time dereferences null pointers and results in a program failure.

Shared Library Limitations

The following limitations apply to building shared libraries:

  • Code generation for theert_shrlib.tlcsystem target file exports the following as data:

    • Variables and signals of typeExportedGlobal

    • Real-time model structure (model_M)

  • For a model that contains a function-call subsystem, code generation for theert_shrlib.tlcsystem target file exports to the shared library only symbols associated with the initialize and terminate entry-point functions.

  • Code generation for theert_shrlib.tlcsystem target file supports the C language only (not C++). When you selectert_shrlib.tlc, model configuration parameterLanguageis greyed out.

  • To reconstruct a model simulation using a generated shared library, the application author must maintain the timing between system and shared library function calls in the original application. The timing needs to be consistent so that you can compare the simulation and integration results. Additional simulation considerations apply if generating a shared library from a model that enables model configuration parametersSupport: continuous timeandSingle output/update function. For more information, seeSingle output/update functiondependencies.

Related Topics