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

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

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

Globals и Persistents в сгенерированном классе C++

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

Алгоритм 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

Смотрите также

Похожие темы