Если у вас есть лицензия Embedded Coder®, можно группировать сгенерированный исходный код от компонента модели для легкого распределения и совместно использованного использования путем создания кода как разделяемая библиотека — динамически подключаемая библиотека Windows® (.dll
), общий объект UNIX® (.so
) или OS X Macintosh динамическая библиотека (.dylib
). Вы или другие можете интегрировать разделяемую библиотеку в приложение, которое работает на Windows, UNIX или компьютере разработчика OS X Macintosh. Сгенерированный .dll
, .so
или файл .dylib
являются общими среди различных приложений и обновляемыми, не имея необходимость перекомпилировать приложения, которые используют его.
Вы создаете разделяемую библиотеку путем конфигурирования генератора кода, чтобы использовать системный конечный файл ert_shrlib.tlc
. Генерация кода для того системного конечного файла экспорт:
Переменные и сигналы типа ExportedGlobal
как данные
Структура модели реального времени (
) как данныеmodel_M
Функции, важные для выполнения вашего типового кода
Просмотреть список символов, содержавшихся в сгенерированной разделяемой библиотеке:
На Windows используйте Зависимость утилита Уокера, загружаемая под эгидой http://www.dependencywalker.com
На UNIX используйте nm -D model.so
На OS X Macintosh используйте nm -g model.dylib
Сгенерировать и пользоваться разделяемой библиотекой:
Сгенерируйте разделяемую версию библиотеки своего типового кодекса
Создайте код приложения, чтобы загрузить и использовать ваш совместно использованный файл библиотеки
Сгенерировать разделяемую версию библиотеки вашего типового кодекса:
Откройте свою модель и сконфигурируйте ее, чтобы использовать системный конечный файл ert_shrlib.tlc
.
Выбор системного конечного файла ert_shrlib.tlc
заставляет процесс сборки генерировать разделяемую версию библиотеки вашего типового кодекса в вашу текущую рабочую папку. Выбор не изменяет код, который генератор кода производит для вашей модели.
Создайте модель.
После того, как сборка завершается, исследуйте сгенерированный код в образцовой подпапке и исследуйте .dll
, .so
или файл .dylib
в вашей текущей папке.
Чтобы проиллюстрировать, как код приложения может загрузить совместно использованный файл библиотеки и получить доступ к его функциям и данным, MathWorks предоставляет модель rtwdemo_shrlib
.
Перейдите к перезаписываемой рабочей папке прежде, чем запустить скрипт rtwdemo_shrlib
.
В модели нажмите синюю кнопку, чтобы запустить скрипт. Скрипт:
Создает совместно использованный файл библиотеки из модели (например, rtwdemo_shrlib_win64.dll
на 64-битном Windows).
Компиляции и ссылки пример приложения, rtwdemo_shrlib_app
, который загружает и использует совместно использованный файл библиотеки.
Выполняет пример приложения.
Явное соединение предпочтено для мобильности. Однако в системах Windows, системный конечный файл ert_shrlib
генерирует и сохраняет файл .lib
, чтобы поддержать неявное соединение.
Чтобы использовать неявное соединение, сгенерированному заголовочному файлу нужна маленькая модификация для вас, чтобы использовать его со сгенерированным файлом C. Например, если вы используете Визуальный C ++®, объявляете, что __declspec(dllimport)
перед данными импортируется неявно из совместно использованного файла библиотеки.
Модель использует следующие файлы примера приложения, которые расположены в (открытой)
папке
.matlabroot/toolbox/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 Input; } ExternalInputs_rtwdemo_shrlib; typedef struct { int32_T Output; } ExternalOutputs_rtwdemo_shrlib; #endif /*_APP_MAIN_HEADER_*/
Пример приложения rtwdemo_shrlib_app.c
включает следующий код для того, чтобы динамически загрузить совместно использованный файл библиотеки. Заметьте, что, в зависимости от платформы, код вызывает команды библиотеки Windows или UNIX.
#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)); }
Следующая выборка кода показывает как доступы к приложениям C экспортированные данные и функции модели. Заметьте рычаги для добавления пользовательской инициализации, шага и кода завершения.
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); }
Сценарий приложений run_rtwdemo_shrlib_app
загружает и восстанавливает модель, и затем компилирует, соединяет и выполняет совместно использованный конечный файл библиотеки модели. Можно просмотреть исходный файл скрипта путем открытия rtwdemo_shrlib
и нажатия белой кнопки, чтобы просмотреть исходный код. Скрипт создает зависимые платформой векторы управляющего символа для компиляции, соединения и выполнения, которое может примениться к вашей среде разработки. Чтобы запустить скрипт, нажмите синюю кнопку.
Чтобы запустить скрипт run_rtwdemo_shrlib_app
без первого открытия модель rtwdemo_shrlib
, перейдите к перезаписываемой рабочей папке и дайте следующую команду MATLAB®:
addpath(fullfile(matlabroot,'toolbox','rtw','rtwdemos','shrlib_demo'))
Это недопустимо, чтобы вызвать оконечную функцию дважды подряд. Оконечная функция очищает указатели и устанавливает их в NULL. При вызове функции второй раз разыменовывает нулевых указателей и приводит к отказу программы.
Следующие ограничения применяются к созданию разделяемых библиотек:
Генерация кода для системного конечного файла ert_shrlib.tlc
экспортирует следующее как данные:
Переменные и сигналы типа ExportedGlobal
Структура модели реального времени (
)model_M
Генерация кода для системного конечного файла ert_shrlib.tlc
поддерживает язык C только (не C++). Когда вы выбираете ert_shrlib.tlc
, выбор языка отображается серым на панели Code Generation диалогового окна Configuration Parameters.
Чтобы восстановить симуляцию модели, пользующуюся сгенерированной разделяемой библиотекой, автор приложения должен поддержать синхронизацию между системой и совместно использованными вызовами библиотечной функции в исходном приложении. Синхронизация должна быть сопоставимой так, чтобы можно было сравнить результаты симуляции и интегрирования. Факторы дополнительной симуляции применяются при генерации разделяемой библиотеки из модели, которая включает параметрам Support: continuous time и Single output/update function. Для получения дополнительной информации смотрите, что вывод/обновление Single функционирует (Simulink Coder) зависимости.