Creating and Using Host-Based Shared Libraries

Overview

The Real-Time Workshop Embedded Coder software provides an ERT target, ert_shrlib.tlc, for generating a host-based shared library from your Simulink model. Selecting this target allows you to generate a shared library version of your model code that is appropriate for your host platform, either a Microsoft Windows dynamic link library (.dll) file or a UNIX[1] shared object (.so) file. This feature can be used to package your source code securely for easy distribution and shared use. The generated .dll or .so file is shareable among different applications and upgradeable without having to recompile the applications that use it.

Code generation for the ert_shrlib.tlc target exports

To view a list of symbols contained in a generated shared library file, you can

To generate and use a host-based shared library, you

  1. Generate a shared library version of your model code

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

Generating a Shared Library Version of Your Model Code

This section summarizes the steps needed to generate a shared library version of your model code.

  1. To configure your model code for shared use by applications, open your model and select the ert_shrlib.tlc target on the Real-Time Workshop pane of the Configuration Parameters dialog box. Click OK.

    Selecting the ert_shrlib.tlc target causes the build process to generate a shared library version of your model code into your current working directory. The selection does not change the code that is generated for your model.

  2. Build the model.

  3. After the build completes, you can examine the generated code in the model subdirectory, and the .dll file or .so file that has been generated into your current directory.

Creating Application Code to Load and Use Your Shared Library File

To illustrate how application code can load an ERT shared library file and access its functions and data, The MathWorks provides the demo model rtwdemo_shrlib. Clicking the blue button in the demo model runs a script that:

  1. Builds a shared library file from the model (for example, rtwdemo_shrlib_win32.dll on 32-bit Windows platforms)

  2. Compiles and links an example application, rtwdemo_shrlib_app, that will load and use the shared library file

  3. Executes the example application

The demo model uses the following example application files, which are located in matlabroot/toolbox/rtw/rtwdemos/shrlib_demo.

FileDescription
rtwdemo_shrlib_app.hExample application header file
rtwdemo_shrlib_app.cExample application that loads and uses the shared library file generated for the demo model
run_rtwdemo_shrlib_app.mScript to compile, link, and execute the example application

You can view each of these files by clicking white buttons in the demo model window. Additionally, running the script places the relevant source and generated code files in your current directory. 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 file rtwdemo_shrlib_app.h contains type declarations for the demo 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 application rtwdemo_shrlib_app.c includes 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 <windows.h>
#define GETSYMBOLADDR GetProcAddress
#define LOADLIB LoadLibrary
#define CLOSELIB FreeLibrary

#else /* UNIX */
#include <dlfcn.h>
#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 demo 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 M Script

The application script run_rtwdemo_shrlib_app.m loads and rebuilds the demo model, and then compiles, links, and executes the demo model's shared library target file. You can view the script source file by opening rtwdemo_shrlib and clicking the appropriate white button. The script constructs platform-dependent command strings for compilation, linking, and execution that may apply to your development environment. To run the script, click the blue button.

Host-Based Shared Library Limitations

The following limitations apply to using ERT host-based shared libraries:


[1] UNIX is a registered trademark of The Open Group in the United States and other countries.

  


 © 1984-2008- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS