Generate Shared Library for Export to External Code Base
About Generated Shared Libraries
If you have Embedded Coder® software, you can generate a shared library—Windows® dynamic link library (.dll
), UNIX® shared object (.so
), or Macintosh OS X dynamic library (.dylib
)— from a model
component. You or others can integrate the shared library into an application that
runs on a Windows, UNIX, or Macintosh OS X development computer. Uses of shared libraries include:
Adding a software component to an application for system simulation
Reusing software modules among applications on a development computer
Hiding intellectual property associated with software that you share with vendors
When producing a shared library, the code generator exports:
Variables and signals of type
ExportedGlobal
as dataReal-time model structure (
) as datamodel
_MFunctions essential to executing the model code
Workflow
To generate a shared library from a model component and use the library, complete the tasks listed in this table.
Task | Action | More Information |
---|---|---|
1 | Review your assessment of external code characteristics and integration requirements. | |
2 | Configure the model for code generation. | Generate Code That Matches Appearance of External Code Model Configuration Set Customization |
3 | Configure the model for the code generator to produce a shared library and initiate code generation. | |
4 | Verify that the generated shared library meets requirements. For example, review the code generation report and view the list of symbols in the library.
| |
5 | Use the shared library in application code. | Create Application Code That Uses Generated Shared Libraries |
6 | Compile and link application code that loads and uses the generated shared library. | |
7 | Verify that executable program behaves and performs as expected. |
Generate Shared Libraries
When configuring the model for code generation, select the system target file
ert_shrlib.tlc
.Build the model. The code generator produces source code for the model and a shared library version of the code. The code generator places the source code in the code generation folder and the shared library (
.dll
,.so
, or.dylib
file) in your current working folder. The code generator also produces and retains a.lib
file to support implicit linking.
Create Application Code That Uses Generated Shared Libraries
This example application code is generated for the example Interface to a Development Computer Simulator by Using a Shared Library.
Create an application header file that contains type declarations for model external input and output. For example:
#ifndef _APP_MAIN_HEADER_ #define _APP_MAIN_HEADER_ typedef struct { int32_T Input; } ExternalInputs_SharedLibraryCode; typedef struct { int32_T Output; } ExternalOutputs_SharedLibraryCode; #endif /*_APP_MAIN_HEADER_*/
In the application C source code, dynamically load the shared library. Use preprocessing conditional statements to invoke platform-specific commands. For example:
#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("./SharedLibraryCode_win64.dll"); #else #if defined(_WIN32) handleLib = LOADLIB("./SharedLibraryCode_win32.dll"); #else /* UNIX */ handleLib = LOADLIB("./SharedLibraryCode.so", RTLD_LAZY); #endif #endif ... return(CLOSELIB(handleLib)); }
From the application C source code, access exported data and functions generated from the model. The code uses hooks to add user-defined initialization, step, and termination code.
int32_T i; ... void (*mdl_initialize)(boolean_T); void (*mdl_step)(void); void (*mdl_terminate)(void); ExternalInputs_SharedLibraryCode (*mdl_Uptr); ExternalOutputs_SharedLibraryCode (*mdl_Yptr); uint8_T (*sum_outptr); ... #if (defined(BORLANDCDLL)) /* Exported symbols contain leading underscores when DLL is linked with BORLANDC */ mdl_initialize = (void(*)(boolean_T))GETSYMBOLADDR(handleLib , "_SharedLibraryCode_initialize"); mdl_step = (void(*)(void))GETSYMBOLADDR(handleLib , "_SharedLibraryCode_step"); mdl_terminate = (void(*)(void))GETSYMBOLADDR(handleLib , "_SharedLibraryCode_terminate"); mdl_Uptr = (ExternalInputs_SharedLibraryCode*)GETSYMBOLADDR(handleLib , "_SharedLibraryCode_U"); mdl_Yptr = (ExternalOutputs_SharedLibraryCode*)GETSYMBOLADDR(handleLib , "_SharedLibraryCode_Y"); sum_outptr = (uint8_T*)GETSYMBOLADDR(handleLib , "_sum_out"); #else mdl_initialize = (void(*)(boolean_T))GETSYMBOLADDR(handleLib , "SharedLibraryCode_initialize"); mdl_step = (void(*)(void))GETSYMBOLADDR(handleLib , "SharedLibraryCode_step"); mdl_terminate = (void(*)(void))GETSYMBOLADDR(handleLib , "SharedLibraryCode_terminate"); mdl_Uptr = (ExternalInputs_SharedLibraryCode*)GETSYMBOLADDR(handleLib , "SharedLibraryCode_U"); mdl_Yptr = (ExternalOutputs_SharedLibraryCode*)GETSYMBOLADDR(handleLib , "SharedLibraryCode_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); }
Limitations
Code generation for the
ert_shrlib.tlc
system target file exports the following as data:Variables and signals of type
ExportedGlobal
Real-time model structure (
model
_M)
Code generation for the
ert_shrlib.tlc
system target file supports the C language only (not C++). When you selectert_shrlib.tlc
, language selection is unavailable on the Code Generation pane in the Configuration Parameters dialog box.To reconstruct a model simulation by 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 must 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 parameters Support: continuous time and Single output/update function.