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