Сгенерированный код пакета как разделяемые библиотеки

Если у вас есть лицензия 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

Сгенерировать и пользоваться разделяемой библиотекой:

  1. Сгенерируйте разделяемую версию библиотеки своего типового кодекса

  2. Создайте код приложения, чтобы загрузить и использовать ваш совместно использованный файл библиотеки

Сгенерируйте разделяемую версию библиотеки типового кодекса

Сгенерировать разделяемую версию библиотеки вашего типового кодекса:

  1. Откройте свою модель и сконфигурируйте ее, чтобы использовать системный конечный файл ert_shrlib.tlc.

    Выбор системного конечного файла ert_shrlib.tlc заставляет процесс сборки генерировать разделяемую версию библиотеки вашего типового кодекса в вашу текущую рабочую папку. Выбор не изменяет код, который генератор кода производит для вашей модели.

  2. Создайте модель.

  3. После того, как сборка завершается, исследуйте сгенерированный код в образцовой подпапке и исследуйте .dll, .so или файл .dylib в вашей текущей папке.

Создайте код приложения, чтобы пользоваться разделяемой библиотекой

Чтобы проиллюстрировать, как код приложения может загрузить совместно использованный файл библиотеки и получить доступ к его функциям и данным, MathWorks предоставляет модель rtwdemo_shrlib.

Примечание

Перейдите к перезаписываемой рабочей папке прежде, чем запустить скрипт rtwdemo_shrlib.

В модели нажмите синюю кнопку, чтобы запустить скрипт. Скрипт:

  1. Создает совместно использованный файл библиотеки из модели (например, rtwdemo_shrlib_win64.dll на 64-битном Windows).

  2. Компиляции и ссылки пример приложения, rtwdemo_shrlib_app, который загружает и использует совместно использованный файл библиотеки.

  3. Выполняет пример приложения.

Совет

Явное соединение предпочтено для мобильности. Однако в системах 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) зависимости.

Похожие темы