exponenta event banner

Создание кода C++ с интерфейсом класса

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

  • Вы получаете более объектно-ориентированный код.

  • Генератор кода создает конструктор класса и деструктор, которые автоматически выполняют инициализацию и завершение памяти.

  • Память выделяется для каждого экземпляра класса отдельно. Методы для каждого экземпляра класса безопасны для потоков и повторно вводятся.

  • Несколько функций точки входа становятся методами в одном классе C++.

Вы можете сгенерировать код с интерфейсом класса из командной строки или из приложения MATLAB Coder™. Из командной строки используйте CppInterfaceStyle и CppInterfaceClassName параметры конфигурации. В приложении на шаге Создать код выберите Язык как C++, выберите Стиль интерфейса как Методы, а затем укажите имя класса интерфейса C++.

В этих примерах показан рабочий процесс командной строки.

Создание кода C++ с интерфейсом класса

В этом примере показано, как генерируемый код C++ отличается при использовании интерфейса класса.

Алгоритм MATLAB

Рассмотрим простую функцию MATLAB, которая выполняет операции над матрицей и выводит результат.

function out = foog %#codegen
I = eye(447);
out = ones(447)*I + 7;

Создание кода C++ с интерфейсом класса и без него

Чтобы создать код C++ с интерфейсом класса, используйте CppInterfaceStyle и CppInterfaceClassName параметры. Сохраните выходные данные в withClass папка.

cfg = coder.config('lib');
cfg.GenCodeOnly = true;
cfg.TargetLang = 'C++';
cfg.CppInterfaceStyle = 'Methods';
cfg.CppInterfaceClassName = 'myClass';
codegen foog -config cfg -report -d withClass
Code generation successful: To view the report, open('withClass/html/report.mldatx').

Затем создайте новый объект конфигурации и создайте код C++, который не использует интерфейс класса.

cfg = coder.config('lib');
cfg.GenCodeOnly = true;
cfg.TargetLang = "C++";
codegen foog -config cfg -report -d withoutClass
Code generation successful: To view the report, open('withoutClass/html/report.mldatx').

Проверьте созданную основную функцию примера. Сравните версии с интерфейсом класса и без него. С помощью интерфейса класса основная функция вызывает функцию точки входа в качестве метода класса.

type withClass/examples/main.cpp

Определение класса и реализация в сгенерированном коде

Когда генератор кода создает код для класса интерфейса C++, он обеспечивает повторный ввод методов функции. Если методы функции используют переменные, которые могут превышать предел памяти локального стека, задается параметром конфигурации StackUsageMax, то генератор кода создает частные структуры данных для переменных (идентифицируемых суффиксом StackData), а не объявлять переменные как static. Статические переменные сохраняются между вызовами функций и не вводятся повторно. Для получения информации о создании кода С для повторного ввода см. Создание кода для повторного ввода и вызова.

Для изучения созданных реализаций класса измените функцию. foog такая, что она содержит переменную, которая превышает максимальное использование стека, указанное параметром конфигурации StackUsageMax.

function out = foogBig %#codegen
I = eye(448);
out = ones(448)*I + 7;

Значение по умолчанию для StackUsageMax в байтах:

cfg.StackUsageMax
ans =

  int32

   200000

Поскольку fooBig использует переменную из элементов 448 ^ 2 (200704), и генератор кода создает 8-битный целочисленный массив для представления переменной, предел использования стека по умолчанию превышен на 704 байт. Создать код дляfoogBig.

cfg = coder.config('lib','ecoder',false);
cfg.GenCodeOnly = true;
cfg.TargetLang = 'C++';
cfg.CppInterfaceStyle = 'Methods';
cfg.CppInterfaceClassName = 'myBigClass';
codegen foogBig -config cfg -report -d withBigClass
Code generation successful: To view the report, open('withBigClass/html/report.mldatx').

Проверка созданных определений классов интерфейсов

Проверьте определения классов для foogBig проект и для foog. foogBig класс хранит переменные, которые могут превышать максимальное использование стека в свойстве частного класса, тогда как foog класс создает только локальные переменные в стеке.

При работе с определением класса, содержащим StackData структура, указывающая на то, что класс требует данных, превышающих локальный предел использования стека, а затем выделяет кучную память для экземпляра класса с помощью new. Пример см. в основном файле созданного кода.

Глобалы и персистенты в сгенерированном классе C++

При создании кода C++ с интерфейсом класса доступ к глобальным и постоянным данным осуществляется как к членам класса. Этот пример показывает, как взаимодействовать с глобальными и постоянными в классе.

Алгоритм MATLAB

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

function [po,go] = countCalls %#codegen
% increment persistent & global variable
persistent p
global g
if isempty(p)
    p = 0;
end
p = p+1;
g = g+1;
% set output variables 
po = double(p);
go = double(g);

Создание кода C++ с интерфейсом класса

Для создания кода инициализируйте глобальную переменную в рабочей области.

global g;
g = 0;

Создать код в классе с именем countClass.

cfg = coder.config('lib');
cfg.GenCodeOnly = true;
cfg.TargetLang = 'C++';
cfg.CppInterfaceStyle = 'Methods';
cfg.CppInterfaceClassName = "countClass";
codegen countCalls -config cfg -report
Code generation successful: To view the report, open('codegen/lib/countCalls/html/report.mldatx').

Проверка определения класса

В сгенерированном коде C++ функция инициализации устанавливает для глобальной переменной значение, указанное в рабочей области. Можно также указать начальное глобальное значение с помощью codegen -globals синтаксис.

Проверьте код определения класса в файле заголовка countClass.h.

type codegen/lib/countCalls/countClass.h

Глобальная переменная является открытым членом класса. При необходимости получите доступ к этой переменной из основной функции. Постоянная переменная хранится в частной структуре данных класса.

Поместить несколько функций точек входа в один класс

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

Функции точек входа MATLAB

Разорвать функцию countCalls в предыдущем примере на два, так что одна функция подсчитывает вызовы с постоянной переменной, а другая - с глобальной переменной. Проверьте две функции.

function po = countPersistent %#codegen
% increment persistent variable
persistent p
if isempty(p)
    p = 0;
end
p = p+1;
% set output variable
po = double(p);

function go = countGlobal %#codegen
% increment global variable
global g
g = g+1;
% set output variable
go = double(g);

Создать код C++

Используйте codegen и укажите начальное значение глобальной переменной в качестве входного значения.

cfg = coder.config('lib');
cfg.GenCodeOnly = true;
cfg.TargetLang = 'C++';
cfg.CppInterfaceStyle = 'Methods';
cfg.CppInterfaceClassName = 'countClassMulti';
codegen countGlobal countPersistent -config cfg -report -globals {'g',0}
Code generation successful: To view the report, open('codegen/lib/countGlobal/html/report.mldatx').

Проверка созданного кода

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

type codegen/lib/countGlobal/countClassMulti.h

См. также

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