生成用于导出到外部代码库的共享库
R2026b关于生成的共享库
如果您有 Embedded Coder® 软件,您可以从模型组件生成共享库 - Windows® 动态链接库 (.dll)、UNIX® 共享对象 (.so) 或 Macintosh OS X 动态库 (.dylib)。您或其他人可以将该共享库集成到在 Windows、UNIX 或 Macintosh OS X 开发计算机上运行的应用程序中。共享库的用途包括:
将软件组件添加到应用程序以进行系统仿真
在开发计算机上的应用程序之间重用软件模块
隐藏与您和供应商共享的软件相关联的知识产权
生成共享库时,代码生成器将执行以下操作:
将
ExportedGlobal类型的变量和信号导出为数据将实时模型结构体 (
) 导出为数据model_M导出执行模型代码所必需的函数
工作流
要从模型组件生成共享库并使用此库,请完成下表中列出的任务。
| 任务 | 操作 | 更多信息 |
|---|---|---|
| 1 | 检查您对外部代码特性和集成要求的评估。 | |
| 2 | 配置模型以进行代码生成。 | Generate Code That Matches Appearance of External Code 模型配置集自定义 |
| 3 | 配置模型,使代码生成器生成共享库并启动代码生成。 | |
| 4 | 验证生成的共享库满足要求。例如,查看代码生成报告并查看库中的符号列表。
| |
| 5 | 在应用程序代码中使用共享库。 | |
| 6 | 编译并链接加载和使用生成的共享库的应用程序代码。 | |
| 7 | 验证可执行程序的行为和性能是否符合预期。 |
生成共享库
为代码生成配置模型时,选择系统目标文件
ert_shrlib.tlc。编译模型。代码生成器为模型生成源代码以及代码的共享库版本。代码生成器将源代码和共享库(
.dll、.so或.dylib文件)放在代码生成文件夹中。代码生成器还生成并保留.lib文件以支持隐式链接。
创建使用生成的共享库的应用程序代码
此示例应用程序代码是为示例通过使用共享库对接在开发计算机上运行的仿真器生成的。
创建一个包含模型外部输入和输出的类型声明的应用程序头文件。例如:
#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_*/在应用程序 C 源代码中,动态加载共享库。使用预处理条件语句调用特定于平台的命令。例如:
#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)); }从应用程序 C 源代码访问从模型导出的数据和生成的函数。代码使用钩子添加用户定义的初始化、步进和终止代码。
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); }