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

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

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

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

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

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

Можно сгенерировать код с интерфейсом класса из командной строки или из MATLAB Coder™ приложения. Из командной строки используйте CppInterfaceStyle и CppInterfaceClassName параметры конфигурации. В приложении на Generate Code шаге выберите Language как C++, выберите Interface style как Methods и затем укажите C++ interface class name.

Эти примеры показывают рабочий процесс командной строки.

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

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

Алгоритм MATLAB

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

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

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

Чтобы сгенерировать код С++ с интерфейсом класса, используйте 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').

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

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. The foogBig класс хранит переменные, которые могут превысить максимальное использование стека в свойстве частного класса, в то время как foog класс создает только локальные переменные в стеке.

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

Глобалы и персистенты в сгенерированном классе 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);

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

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

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').

Смотрите определение класса

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

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

type codegen/lib/countCalls/countClass.h

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

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

Когда вы генерируете код С++ для нескольких функций точки входа и используете настройку интерфейса класса, то каждая функция становится общедоступным методом одного и того же класса. Можно использовать этот метод, чтобы создать более простой интерфейс для вашего проекта с несколькими функциями точки входа.

Функции точки входа 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);

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

Используйте 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

См. также

Похожие темы