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

Если у вас есть лицензия Embedded Coder®, можно группировать сгенерированный исходный код от компонента модели для легкого распределения и совместно использованного использования путем создания кода как разделяемая библиотека — динамически подключаемая библиотека Windows® (.dll), общий объект UNIX® (.so), или OS X Macintosh динамическая библиотека (.dylib). Вы или другие можете интегрировать разделяемую библиотеку в приложение, которое работает на Windows, UNIX или компьютере разработчика OS X Macintosh. Сгенерированный .dll, .so, или .dylib файл является общим среди различных приложений и обновляемым, не имея необходимость перекомпилировать приложения, которые используют его.

О сгенерированных разделяемых библиотеках

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

  • Переменные и сигналы типа ExportedGlobal как данные

  • Структура модели реального времени (modelM) как данные

  • Функции, важные для выполнения вашего типового кода

Просмотреть список символов, содержавшихся в сгенерированной разделяемой библиотеке:

  • На 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

    • Структура модели реального времени (modelM)

  • Генерация кода для ert_shrlib.tlc системный конечный файл поддерживает язык C только (не C++). Когда вы выбираете ert_shrlib.tlc, параметр конфигурации модели Language отображается серым.

  • Чтобы восстановить симуляцию модели, пользующуюся сгенерированной разделяемой библиотекой, автор приложения должен обеспечить синхронизацию между системой и совместно использованными вызовами библиотечной функции в исходном приложении. Синхронизация должна быть сопоставимой так, чтобы можно было сравнить результаты симуляции и интегрирования. Факторы дополнительной симуляции применяются при генерации разделяемой библиотеки из модели, которая включает параметрам конфигурации модели Support: continuous time и Single output/update function. Для получения дополнительной информации смотрите, что выход/обновление Single функционирует (Simulink Coder) зависимости.

Похожие темы