Сгенерируйте код С при помощи приложения MATLAB Coder

В этом руководстве вы используете MATLAB® Coder™ приложение, чтобы сгенерировать статическую библиотеку C для функции MATLAB. Сначала вы генерируете код С, который может принимать только входы с фиксированным предварительно присвоенным размером. Затем вы генерируете код С, который может принимать входы многих различных размеров.

Можно также сгенерировать код в командной строке MATLAB при помощи codegen команда. Учебное руководство по этому рабочему процессу смотрите в Генерация кода С в командной строке.

Приложение MATLAB Coder не поддерживается в MATLAB Online™. Чтобы сгенерировать код C/C + + в MATLAB Online, используйте codegen команда.

Учебные файлы

Скопируйте файлы учебника из папки matlabroot\ help\toolbox\coder\examples\euclidean в локальную рабочую папку. Здесь, matlabroot - папка установки MATLAB, например C:\Program Files\MATLAB\R2019a. Чтобы скопировать эти файлы в текущую папку, запустите эту команду MATLAB:

copyfile(fullfile(matlabroot,'help','toolbox','coder','examples','euclidean'))
Локальная рабочая папка не может быть частной папкой или папкой @. Это руководство использует euclidean_data.mat, euclidean.m, и test.m файлы.

  • Файл данных MATLAB euclidean_data.mat содержит две части данных: одну точку в трехмерном евклидовом пространстве и набор нескольких других точек в трехмерном евклидовом пространстве. Более конкретно:

    • x является 3-by- 1 Вектор-столбец, который представляет точку в трехмерном евклидовом пространстве.

    • cb является 3-by- 216 массив. Каждый столбец в cb представляет точку в трехмерном евклидовом пространстве.

  • Файл MATLAB euclidean.m содержит функцию euclidean который реализует основной алгоритм в этом примере. Функция принимает x и cb в качестве входов. Он вычисляет евклидово расстояние между x и каждая точка в cb и возвращает следующие величины:

    • Область вектора-столбца y_min, что равно столбцу в cb который представляет точку, которая ближе всего к x.

    • Область вектора-столбца y_max, что равно столбцу в cb который представляет точку, наиболее удаленную от x.

    • 2мерный вектор idx который содержит индексы столбцов векторов y_min и y_max в cb.

    • 2мерный вектор distance который содержит вычисленные наименьшие и самые большие расстояния до x.

    function [y_min,y_max,idx,distance] = euclidean(x,cb)
    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx(1)=1;
    idx(2)=1;
    
    distance(1)=norm(x-cb(:,1));
    distance(2)=norm(x-cb(:,1));
    
    % Find the vector in cb with minimum distance to x
    % Find the vector in cb with maximum distance to x
    for index=2:size(cb,2)
        d=norm(x-cb(:,index));
        if d < distance(1)
            distance(1)=d;
            idx(1)=index;
        end
        if d > distance(2)
            distance(2)=d;
            idx(2)=index;
        end
    end
    
    % Output the minimum and maximum distance vectors
    y_min=cb(:,idx(1));
    y_max=cb(:,idx(2));
    
    end
  • Скрипт MATLAB test.m загружает файл данных euclidean_data.mat в рабочую область. Затем вызывается функция euclidean для вычисления y_min, y_max, idx, и distance. Затем скрипт отображает вычисленные величины в командной строке.

    Загрузка euclidean_data.mat - шаг предварительной обработки, который выполняется перед вызовом основного алгоритма. Отображение результатов является шагом постобработки.

    % Load test data 
    load euclidean_data.mat
    
    % Determine closest and farthest points and corresponding distances
    [y_min,y_max,idx,distance] = euclidean(x,cb);
    
    % Display output for the closest point
    disp('Coordinates of the closest point are: ');
    disp(num2str(y_min'));
    disp(['Index of the closest point is ', num2str(idx(1))]);
    disp(['Distance to the closest point is ', num2str(distance(1))]);
    
    disp(newline);
    
    % Display output for the farthest point
    disp('Coordinates of the farthest point are: ');
    disp(num2str(y_max'));
    disp(['Index of the farthest point is ', num2str(idx(2))]);
    disp(['Distance to the farthest point is ', num2str(distance(2))]);

Совет

Можно сгенерировать код из функций MATLAB при помощи MATLAB Coder. Генерация кода из скриптов MATLAB не поддерживается.

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

Сгенерируйте код С для функции MATLAB

Запуск оригинального кода MATLAB

Запустите тестовый скрипт test.m в MATLAB. Выходные выходы отображаются y, idx, и distance.

Coordinates of the closest point are: 
0.8         0.8         0.4
Index of the closest point is 171
Distance to the closest point is 0.080374


Coordinates of the farthest point are: 
0  0  1
Index of the farthest point is 6
Distance to the farthest point is 1.2923

Сделайте код MATLAB подходящим для генерации кода

Анализатор кода в редакторе MATLAB постоянно проверяет ваш код при его вводе. Он сообщает о проблемах и рекомендует изменения для максимизации эффективности и поддерживаемости.

  1. Откройте euclidean.m в редакторе MATLAB. Индикатор сообщения Анализатор кода в правом верхнем углу редактора MATLAB зеленый. Анализатор не обнаружил ошибок, предупреждений или возможностей для улучшения кода.

  2. После объявления функции добавьте %#codegen директива:

    function [y,idx,distance] = euclidean(x,cb) %#codegen
    The %#codegen директива предлагает анализатору кода идентифицировать предупреждения и ошибки, характерные для генерации кода.

    Индикатор сообщения анализатора кода становится красным, что указывает на обнаруженные проблемы генерации кода.

  3. Чтобы просмотреть предупреждающие сообщения, переместите курсор на подчеркнутые фрагменты кода. Предупреждения указывают, что генерация кода требует переменных idx и distance будет полностью определено перед индексированием на них. Эти предупреждения появляются, потому что генератор кода должен определить размеры этих переменных при их первом внешнем виде в коде. Чтобы устранить эту проблему, используйте ones функция для одновременного выделения и инициализации этих массивов.

    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx = ones(1,2);
    
    distance = ones(1,2)*norm(x-cb(:,1));

    Индикатор сообщения анализатора кода снова становится зеленым, что указывает на то, что он не обнаруживает больше проблем генерации кода.

    Дополнительные сведения об использовании анализатора кода см. в разделе Проверка кода на ошибки и предупреждения.

  4. Сохраните файл.

    Теперь вы готовы скомпилировать код с помощью приложения MATLAB Coder. Здесь compilation относится к генерации кода C/C + + из вашего кода MATLAB.

Примечание

Компиляция кода MATLAB относится к генерации кода C/C + + из кода MATLAB. В других контекстах термин компиляция может означать действие компилятора C/C + +.

Откройте приложение MATLAB Coder и выберите исходные файлы

  1. На вкладке Apps панель инструментов, в разделе Code Generation, щелкните значок приложения MATLAB Coder. Приложение открывает страницу Select Source Files.

  2. На странице Select Source Files введите или выберите имя функции точки входа euclidean. entry-point function является функцией MATLAB верхнего уровня, из которой вы генерируете код. Приложение создает проект с именем по умолчанию euclidean.prj в текущей папке.

  3. Щелкните Next, чтобы перейти к Define Input Types шагу. Приложение запускает Анализатор Кода (который вы уже запускали на предыдущем шаге) и Инструмент Готовности Генерации Кода на функции точки входа. Code Generation Readiness Tool отображает код MATLAB для функций и функций, которые не поддерживаются для генерации кода. Если приложение определяет проблемы, оно открывает страницу Review Code Generation Readiness, на которой можно просмотреть и исправить проблемы. В этом примере, поскольку приложение не обнаруживает проблемы, он открывает страницу Define Input Types. Для получения дополнительной информации смотрите Генерация Кода Readiness Tool.

    Примечание

    Анализатор кода и инструмент подготовки генерации кода могут обнаружить не все проблемы генерации кода. После устранения ошибок или предупреждений, которые эти два инструмента обнаруживают, сгенерируйте код с MATLAB Coder, чтобы определить, есть ли у вашего кода MATLAB другие проблемы с податливостью.

Определенные встроенные функции MATLAB и функции тулбокса, классы и системные объекты, поддерживаемые для генерации кода C/C + +, имеют определенные ограничения на генерацию кода. Эти ограничения и связанные с ними указания по применению перечислены в Extended Capabilities разделах соответствующих страниц с описанием. Для получения дополнительной информации смотрите Функции и Объекты, Поддерживаемые для Генерации кода C/C + +.

Определите входные типы

Поскольку C использует статическое типирование, генератор кода должен определить класс, размер и сложность всех переменных в файлах MATLAB во время генерации кода, также известного как время компиляции. Поэтому необходимо задать свойства всех входных параметров функции точки входа. Чтобы задать входные свойства, можно:

  • Инструктируйте приложение автоматически определять входные свойства путем предоставления скрипта, который вызывает функции точки входа с выборочными входами.

  • Задайте свойства непосредственно.

В этом примере, чтобы задать свойства входов x и cb, задайте тестовый файл test.m генератор кода может использовать для автоматического определения типов:

  1. Введите или выберите тестовый файл test.m.

  2. Нажмите Autodefine Input Types.

    Тестовый файл, test.m, вызывает функцию точки входа, euclidean, с ожидаемыми типами входов. Приложение определяет, что вход x является double(3x1) и входной cb является double(3x216).

  3. Щелкните Next, чтобы перейти к Check for Run-Time Issues шагу.

Проверяйте на наличие проблем во время выполнения

Шаг Check for Run-Time Issues генерирует файл MEX из функций точки входа, запускает MEX-функцию и сообщает о проблемах. Существует MEX-функция сгенерированного кода, который можно вызвать из MATLAB. Это лучшая практика выполнить этот шаг, потому что вы можете обнаружить и исправить ошибки времени выполнения, которые труднее диагностировать в сгенерированном коде C. По умолчанию MEX-функция включает проверку целостности памяти. Эти проверки выполняют ограничения массивов и проверку размерностей. Проверки обнаруживают нарушения целостности памяти в коде, сгенерированном для функций MATLAB. Для получения дополнительной информации см. раздел Проверки во время выполнения системы управления.

Чтобы преобразовать код MATLAB в эффективный исходный код C/C + +, генератор кода вводит оптимизации, которые в определенных ситуациях заставляют сгенерированный код вести себя по-другому, чем исходный исходный код. Смотрите Различия между сгенерированным кодом и кодом MATLAB.

  1. Чтобы открыть диалоговое окно Check for Run-Time Issues, щелкните стрелу Check for Issues.

  2. В диалоговом окне Check for Run-Time Issues укажите тестовый файл или введите код, который вызывает функцию точки входа с примерами входов. В данном примере используйте тестовый файл test который использовался для определения типов входа.

  3. Нажмите Check for Issues.

    Приложение генерирует MEX-функцию. Он запускает тестовый скрипт test замена вызовов на euclidean с вызовами сгенерированного MEX. Если приложение обнаруживает проблемы во время генерации или выполнения MEX-функции, оно выдает предупреждения и сообщения об ошибке. Щелкните эти сообщения, чтобы перейти к проблемному коду и устранить проблему. В этом примере приложение не обнаруживает проблем.

  4. По умолчанию приложение собирает количество выполнения линии. Эти подсчеты помогают вам увидеть, насколько хорошо тестовый файл test.m осуществил euclidean функция. Чтобы просмотреть счетчики выполнения линий, нажмите View MATLAB line execution counts. Редактор приложений отображает маркированную цветом полосу слева от кода. Чтобы расширить подсветку цвета над кодом и увидеть счетчики выполнения линии, поместите курсор на полосу.

    Конкретный оттенок зеленого цвета указывает, что количество выполнения линии для этого кода падает в определенной области значений. В этом случае for-цикл выполняет 215 раз. Для получения информации о том, как интерпретировать счетчики выполнения линии и отключить набор счетчиков, смотрите Сбор и Просмотр счетчиков выполнения линии для кода MATLAB.

  5. Щелкните Next, чтобы перейти к Generate Code шагу.

Примечание

Перед генерацией автономного кода C/C + + из кода MATLAB сгенерируйте MEX-функцию. Запустите сгенерированную MEX-функцию и убедитесь, что она имеет то же поведение во время выполнения, что и ваша функция MATLAB. Если сгенерированная MEX-функция создает ответы, отличные от MATLAB, или вызывает ошибку, необходимо исправить эти проблемы, прежде чем переходить к автономной генерации кода. В противном случае автономный код, который вы генерируете, может оказаться ненадежным и иметь неопределенное поведение.

Сгенерируйте код С

  1. Чтобы открыть диалоговое окно Generate, щелкните стрелу Generate.

  2. В диалоговом окне Generate установите Build type равным Static Library (.lib) и Language к C. Используйте значения по умолчанию для других настроек строения сборки проекта.

    Вместо генерации статической библиотеки C можно выбрать генерацию MEX-функции или других типов сборки C/C + +. Для типов сборки MEX и C/C + + доступны различные настройки проекта. При переключении между генерацией кода MEX и C/C + + проверьте выбранные настройки.

  3. Нажмите Generate.

    MATLAB Coder генерирует автономную статическую библиотеку C euclidean в work\ codegen\lib\euclidean. work - папка, содержащая ваши обучающие файлы. Приложение MATLAB Coder указывает, что генерация кода выполнена успешно. В нем отображаются исходные файлы MATLAB и сгенерированные выходные файлы в левой части страницы. На вкладке Variables отображается информация о исходных переменных MATLAB. На вкладке Target Build Log отображается журнал сборки, включая предупреждения компилятора C/C + + и ошибки. По умолчанию в окне кода приложение отображает исходные файлы кода C euclidean.c. Чтобы просмотреть другой файл, на панели Source Code или Output Files щелкните имя файла.

  4. Нажмите кнопку View Report, чтобы просмотреть отчет в средстве просмотра. Если генератор кода обнаруживает ошибки или предупреждения во время генерации кода, отчет описывает проблемы и предоставляет ссылки на проблемный код MATLAB. Для получения дополнительной информации см. Отчеты генерации кода.

  5. Щелкните Next, чтобы открыть страницу Finish Workflow.

Проверьте страницу рабочего процесса конец

Страница Finish Workflow указывает, что генерация кода выполнена успешно. В нем содержатся сводные данные проекта и ссылки на сгенерированные выходы.

Сравнение сгенерированного кода C с оригинальным кодом MATLAB

Чтобы сравнить ваш сгенерированный код C с оригинальным кодом MATLAB, откройте файл C, euclidean.c, и euclidean.m файл в редакторе MATLAB.

Важная информация о сгенерированном коде C:

  • Сигнатура функции:

    void euclidean(const double x[3], const double cb[648], double y_min[3], double
                   y_max[3], double idx[2], double distance[2])

    const double x[3] соответствует входу x в коде MATLAB. Размер x является 3, что соответствует общему размеру (3 x 1) примера входа, который вы использовали, когда вы сгенерировали код из кода MATLAB.

    const double cb[648] соответствует входу cb в коде MATLAB. Размер cb является 648, что соответствует общему размеру (3 x 216) примера входа, который вы использовали, когда вы сгенерировали код из кода MATLAB. В этом случае сгенерированный код использует одномерный массив, чтобы представлять двумерный массив в коде MATLAB.

    Сгенерированный код имеет четыре дополнительных входных параметров: массивы y_min, y_max, idx, и distance. Эти массивы используются для возврата выхода значений. Они соответствуют выходным аргументам y_min, y_max, idx, и distance в оригинальный код MATLAB.

  • Генератор кода сохраняет ваши имена функции и комментарии. Когда это возможно, генератор кода сохраняет ваши имена переменных.

    Примечание

    Если для переменной в коде MATLAB задано постоянное значение, она не отображается как переменная в сгенерированном коде C. Вместо этого сгенерированный код C содержит фактическое значение переменной.

С Embedded Coder®, можно интерактивно проследить между кодом MATLAB и сгенерированным кодом C/C + +. Смотрите Интерактивное Отслеживание между Кодом MATLAB и Сгенерированным Кодом C/C + + (Embedded Coder).

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

Функция C, которую вы сгенерировали для euclidean.m может принимать только те входы, которые имеют тот же размер что и выборка входы, которые вы задали во время генерации кода. Однако входные массивы в соответствующую функцию MATLAB могут быть любого размера. В этой части руководства вы генерируете код С из euclidean.m который принимает входы переменного размера.

Предположим, что вам нужны размерности x и cb в сгенерированном коде C, чтобы иметь следующие свойства:

  • Первая размерность обоих x и cb может варьироваться в размере до 3.

  • Второе измерение x является фиксированным и имеет значение 1.

  • Второе измерение cb может варьироваться в размере до 216.

Чтобы задать эти входные свойства:

  1. На Define Input Types шаге введите тестовый файл test.m и нажмите Autodefine Input Types как и прежде. Тестовый файл вызывает функцию точки входа, euclidean.m, с ожидаемыми типами входов. Приложение определяет, что вход x является double(3x1) и входной cb является double(3x216). Эти типы задают входы фиксированного размера.

  2. Щелкните спецификации входного типа и отредактируйте их. Вы можете задать размер переменной, до заданного предела, используя : префикс. Для примера, :3 подразумевает, что соответствующая размерность может варьироваться до 3. Измените типы на double(:3 x 1) для x и double(:3 x :216) для cb.

Теперь можно сгенерировать код, выполнив те же шаги, что и ранее. Сигнатура функции для сгенерированного кода C в euclidean.c теперь читает:

void euclidean(const double x_data[], const int x_size[1], const double cb_data[],
               const int cb_size[2], double y_min_data[], int y_min_size[1],
               double y_max_data[], int y_max_size[1], double idx[2], double
               distance[2])
Аргументы x_data, cb_data, y_min_data, и y_max_data соответствуют входным параметрам x и cb и выходные аргументы y_min и y_max в исходной функции MATLAB. Теперь функция C принимает четыре дополнительных входных параметров x_size, cb_size, y_min_size, и y_max_size которые определяют размеры x_data, cb_data, y_min_data, и y_max_data во время исполнения.

Следующие шаги

ЦельДополнительная информация

Узнайте о поддержке генерации кода для встроенных функций MATLAB и функций тулбокса, классов и системных объектов

Функции и объекты, поддерживаемые для генерации кода C/C + +

Сгенерируйте код С++

Генерация кода С++

Сгенерируйте и измените пример основной функции C и используйте его для создания исполняемой программы C

Использование примера C Main в приложении

Упаковать сгенерированные файлы в сжатый файл

Упаковать код для других сред разработки

Оптимизируйте скорость выполнения или использование памяти сгенерированного кода

Стратегии оптимизации

Интегрируйте свой пользовательский код C/C + + в сгенерированный код

Вызов кода C/C + + из кода MATLAB

Узнайте об отчете генерации кода

Отчеты генерации кода

Интерактивная трассировка между кодом MATLAB и сгенерированным кодом C/C + + (Embedded Coder )