В большинстве случаев, когда вы генерируете код для MATLAB® функция, которая принимает или возвращает массив, существует массив в интерфейсе сгенерированной функции C/C + +. Для размера массива, который неизвестен во время компиляции или чья граница превышает предопределенный порог, память для сгенерированного массива динамически выделяется на куче. В противном случае память сгенерированного массива статически выделяется в стеке. См. Раздел «Управление выделением памяти» для массивов переменного размера.
Если вы выбираете C++ в качестве целевого языка для генерации кода, по умолчанию динамически выделенный массив реализуется как шаблон класса, называемый coder::array в сгенерированном коде. Чтобы использовать динамически выделенные массивы в пользовательском коде С++, который вы интегрируете с сгенерированными функциями C++, научитесь использовать coder::array шаблон.
По умолчанию сгенерированный код С++ использует coder::array шаблон для реализации динамически выделенных массивов. Вместо этого можно выбрать генерацию кода С++, который использует стиль C emxArray структура данных для реализации динамически выделенных массивов. Чтобы сгенерировать стиль C emxArray структуры данных выполните одно из следующих действий:
В объекте строения кода (coder.MexCodeConfig, coder.CodeConfig, или coder.EmbeddedCodeConfig), установите DynamicMemoryAllocationInterface параметр в 'C'.
В приложении MATLAB Coder™ на вкладке Memory установите Dynamic memory allocation interface Use C style EmxArray.
Чтобы узнать больше о статически выделенных массивах или динамически выделенных массивах, реализованных с помощью стиля C emxArray структура данных, см. Использование массивов C в Сгенерированных функциональных интерфейсах.
В этой таблице перечислены два типичных случая для представления динамического массива в сгенерированном коде С++. Для определения coder::array шаблон, который реализует динамические массивы в сгенерированном коде, см. Использование шаблона класса coder:: array.
Описание алгоритма и размер массива | Функция MATLAB | Сгенерированный функциональный интерфейс C++ |
|---|---|---|
Нажмите таковые на вектор-строку переменного размера, ограниченную 30 000 элементами. Переменный размер, не ограниченный порогом. |
function B = create_vec2 %#codegen B = zeros(1,0); coder.varsize('B',[1 30000],[0 1]); for i = 1:500 if round(rand) B = [1 B]; end end |
void create_vec2(coder::array<double, 2U> &B) |
Создайте массив с размером, определенным неограниченным целым входом. Неизвестно во время компиляции. |
function y = create_vec3(n) %#codegen y = int8(ones(1,n)); |
void create_vec3(double n, coder::array<signed char, 2U> &y) |
coder::array Шаблон классаКогда вы генерируете код С++ для функций MATLAB, генератор кода создает файл заголовка coder_array.h в папке сборки. Этот файл заголовка содержит определение шаблона класса array в пространстве имен coder. The coder::array шаблон реализует динамически выделенные массивы в сгенерированном коде. Декларация для этого шаблона:
template <typename T, int32_T N> class array
T и имеет N размерности. Для примера объявить двумерный динамический массив myArray который содержит элементы типа int32_T в пользовательских Кодах С++ используйте:coder::array<int32_T, 2> myArray
Чтобы использовать динамически выделенные массивы в своем пользовательском Коде С++, который вы хотите интегрировать с сгенерированным кодом (для примера, пользовательская основная функция), включите coder_array.h заголовочный файл в пользовательском .cpp файлы. В этой таблице показан API, который вы используете для создания и взаимодействия с динамическими массивами в ваших пользовательских Кодах С++.
Действие | Инструкции |
|---|---|
Объявить динамический массив | Используйте coder::array<int32_T, 2> myArray |
Выделите память для | Используйте myArray.set_size(1, 100) Если размерность |
Доступ к вектору размера | Доступ к myArray.size(1) |
Индексируйте в динамический | Используйте стандартный синтаксис C++ для индексации массива. Для примера установите myArray[i] = i |
Задайте функцию MATLAB xTest1 который принимает массив X, добавляет скаляр A к каждому из его элементов и возвращает получившийся массив Y.
function Y = xTest1(X, A) Y = X; for i = 1:numel(X) Y(i) = X(i) + A; end
Вы стремитесь сгенерировать исполняемый файл C++ для xTest1 который может принять и вернуть массив int32_T элементы. Вы хотите, чтобы первая размерность массива была синглтоном, а второе измерение было неограниченным.
Задайте основную функцию C++ в файле xTest1_main.cpp в текущей рабочей папке.
#include<iostream>
#include<coder_array.h>
#include<xTest1.h>
int main(int argc, char *argv[])
{
static_cast<void>(argc);
static_cast<void>(argv);
coder::array<int32_T, 2> myArray;
myArray.set_size(1, 100);
for (int i = 0; i < myArray.size(1); i++) {
myArray[i] = i;
}
coder::array<int32_T, 2> myResult;
xTest1(myArray, 1000, myResult);
for (int i = 0; i < myResult.size(1); i++) {
if (i > 0) std::cout << " ";
std::cout << myResult[i];
if (((i+1) % 10) == 0) std::cout << std::endl;
}
std::cout << std::endl;
return 0;
}Эта основная функция включает заголовочный файл coder_array.h который содержит coder::array определение шаблона класса. Основная функция использует API, описанный в таблице в предыдущем разделе, чтобы выполнить следующие действия:
Объявить myArray и myResult как двумерные динамические массивы int32_T элементы.
Динамически устанавливайте размеры двух размерностей myArray на 1 и 100 при помощи set_size способ.
Доступ к вектору размера myResult при помощи myResult.size.
Сгенерируйте код, запустив этот скрипт. Замените 'C:\work' с путем к текущей рабочей папке.
cfg = coder.config('exe'); cfg.TargetLang = 'C++'; cfg.CustomSource = 'xTest1_main.cpp'; cfg.CustomInclude = 'C:\work'; codegen -config cfg -args { coder.typeof(int32(0), [1 inf]), int32(0)} xTest1_main.cpp xTest1.m -report
Генератор кода создает исполняемый файл xTest1.exe в текущей рабочей папке.
Задайте функцию MATLAB xStringTest который принимает вектор символов str, вставки str между векторами символов 'hello ' и ' world!', и возвращает результат. Ваша цель - сгенерировать исполняемый файл C++ из xStringTest.
function y = xStringTest(str) assert(isa(str, 'char')); assert(size(str,1) == 1); assert(size(str,2) >= 0); y = ['hello ' str ' world!'];
Задайте основную функцию C++ в файле xStringTest_main.cpp в текущей рабочей папке. Эта основная функция использует std::vector чтобы объявить вектор vec от char_T элементы, которые вы передаете сгенерированной функции C++ xStringTest.
#include<iostream>
#include<coder_array.h>
#include<xTest1.h>
int main(int, char *[])
{
coder::array<char_T, 2> result;
std::vector<char_T> vec;
vec.resize(10);
for (size_t i = 0; i < 10; i++) {
vec[i] = static_cast<char_T>('A' + i);
}
xStringTest(vec, result);
std::cout << "Result is " << static_cast<std::string>(result) << std::endl;
return 0;
}
Сгенерируйте код, запустив этот скрипт. Замените 'C:\work' с текущей рабочей папкой.
cfg = coder.config('exe'); cfg.TargetLang = 'C++'; cfg.CustomSource = 'xStringTest_main.cpp'; cfg.CustomInclude = 'C:\work'; codegen -config cfg -args {coder.typeof(char('X'), [1 inf])} xStringTest_main.cpp xStringTest.m -report
Генератор кода создает исполняемый файл xStringTest.exe в текущей рабочей папке.