Если у вас есть лицензия 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
системный конечный файл экспортирует в разделяемую библиотеку только символы, сопоставленные с инициализированием и оконечными функциями точки входа.
Генерация кода для ert_shrlib.tlc
системный конечный файл поддерживает язык C только (не C++). Когда вы выбираете ert_shrlib.tlc
, параметр конфигурации модели Language отображается серым.
Чтобы восстановить симуляцию модели, пользующуюся сгенерированной разделяемой библиотекой, автор приложения должен обеспечить синхронизацию между системой и совместно использованными вызовами библиотечной функции в исходном приложении. Синхронизация должна быть сопоставимой так, чтобы можно было сравнить результаты симуляции и интегрирования. Факторы дополнительной симуляции применяются при генерации разделяемой библиотеки из модели, которая включает параметрам конфигурации модели Support: continuous time и Single output/update function. Для получения дополнительной информации смотрите, что выход/обновление Single функционирует (Simulink Coder) зависимости.