exponenta event banner

Код, созданный в пакете, как общие библиотеки

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

Сведения о созданных общих библиотеках

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

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

  • Структура модели в реальном времени (model_M) в качестве данных

  • Функции, необходимые для выполнения кода модели

Чтобы просмотреть список символов, содержащихся в созданной общей библиотеке:

  • В Windows используйте утилиту Dependency Walker, которую можно загрузить из http://www.dependencywalker.com

  • В UNIX используйте nm -D model.so

  • На Macintosh OS X используйте 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. Например, если вы используете Visual 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_*/

Пример кода приложения C

Пример приложения 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 затемнен.

  • Чтобы реконструировать моделирование модели с использованием созданной общей библиотеки, автор приложения должен поддерживать время между вызовами системных и общих библиотечных функций в исходном приложении. Время должно быть согласованным, чтобы можно было сравнить результаты моделирования и интеграции. Дополнительные рекомендации по моделированию применяются при создании общей библиотеки из модели, которая включает параметры конфигурации модели Поддержка: непрерывное время и Функция единого вывода/обновления. Дополнительные сведения см. в разделе Зависимости отдельных функций вывода/обновления.

Связанные темы