Из вашего кода MATLAB® можно непосредственно вызвать внешний код C/C++, также названный пользовательским кодом или унаследованным кодом. Чтобы вызвать функции C/C++, используйте coder.ceval
. Генератор кода интегрирует ваш код C/C++ в код C/C++, сгенерированный из MATLAB. Интегрируйте код, когда существуют внешние библиотеки, оптимизированный код или объектные файлы, разработанные на C/C++, который вы хотите использовать со своим сгенерированным кодом. Когда внешний код использует типы переменных, которые не заданы или распознаны MATLAB, используют coder.opaque
функция в сочетании с coder.ceval
.
Следующее является некоторыми первичными рабочими процессами для внешней интеграции кода. Для большего количества примеров смотрите coder.ceval
страница с описанием.
При помощи coder.ceval
, вы получаете неограниченный доступ к внешнему коду. Неправильное употребление этих функций или ошибок в вашем коде может дестабилизировать MATLAB и заставить его прекращать работать. Чтобы отладить ваш код и анализировать сообщения об ошибке от компиляции, просмотрите вкладку Build Logs в отчете генерации кода.
В этом примере показано, как объединяться, простой C функционируют с кодом MATLAB® при помощи coder.ceval
. Рассмотрите функцию MATLAB, mathOps
:
function [added, multed] = mathOps(in1, in2) added = in1+in2; multed = in1*in2; end
В данном примере предположите, что вы хотите реализовать операцию сложения при помощи внешнего кода С. Рассмотрите функцию C, adder
, реализованный в файле adder.c
:
#include <stdio.h> #include <stdlib.h> #include "adder.h" double adder(double in1, double in2) { return in1 + in2; }
Интегрировать adder
с вашим кодом MATLAB вам нужен заголовочный файл, который содержит прототипа функции. Смотрите файл adder.h
:
double adder(double in1, double in2);
Используйте coder.ceval
команда, чтобы вызвать функцию C в mathOpsIntegrated.m
. Включайте заголовочный файл при помощи coder.cinclude
.
function [added, multed] = mathOpsIntegrated(in1, in2) %#codegen % for code generation, preinitialize the output variable % data type, size, and complexity added = 0; % generate an include in the C code coder.cinclude('adder.h'); % evaluate the C function added = coder.ceval('adder', in1, in2); multed = in1*in2; end
Чтобы сгенерировать код, используйте codegen
команда. Задайте исходный файл adder.c
как вход. Чтобы протестировать код С, выполните MEX-функцию и смотрите выходные результаты.
codegen mathOpsIntegrated -args {1, 2} adder.c [test1, test2] = mathOpsIntegrated_mex(10, 20)
test1 = 30 test2 = 200
Язык C ограничивает функции в возвращении нескольких выходных параметров. Вместо этого они возвращают только одно, скалярное значение. Функции MATLAB coder.ref
, coder.rref
и coder.wref
позвольте вам возвращать несколько выходных параметров внешней функции C/C++.
Например, предположите, что вы пишете функции MATLAB foo
это берет два входных параметров x
и y
и возвращает три выходных параметров a
B
, и c
. В MATLAB вы вызываете эту функцию можно следующим образом:
[a,b,c] = foo(x,y)
Если вы переписываете foo
как функция C, вы не можете возвратить три отдельных значения a
B
, и c
через return
оператор. Вместо этого создайте функцию C с несколькими аргументами типа указателя и передайте выходные параметры ссылкой. Например:
void foo(double x,double y,double *a,double *b,double *c)
Затем можно вызвать функцию C от функции MATLAB при помощи coder.ceval
функция.
coder.ceval('foo',x,y,coder.ref(a),coder.ref(b),coder.ref(c));
Если ваша внешняя функция C только пишет в или только читает из памяти, которая передается ссылкой, можно использовать coder.wref
или coder.rref
функции вместо coder.ref
. При определенных обстоятельствах эти функции могут включить дальнейшую оптимизацию сгенерированного кода. Когда вы используете coder.wref(arg)
передать arg
ссылкой ваша внешняя функция C/C++ должна полностью инициализировать память, на которую ссылается arg
.
В этом примере показано, как передать данные в отношении и от внешней функции C.
Передача ссылкой является важным методом для интеграции кода C/C++. Когда вы передаете данные ссылкой, программа не должна копировать данные от одной функции до другого. С передачей значением код С может возвратить только одну скалярную переменную. С передачей ссылкой код С может возвратить несколько переменных, включая массивы.
Считайте функцию MATLAB adderRef
. Эта функция использует внешний код С, чтобы добавить два массива. coder.rref
и coder.wref
команды дают генератору кода команду передавать указатели на массивы, вместо того, чтобы копировать их.
function out = adderRef(in1, in2) %#codegen out = zeros(size(in1)); % the input numel(in1) is converted to integer type % to match the cAdd function signature coder.ceval('cAdd', coder.rref(in1), coder.rref(in2), coder.wref(out), int32(numel(in1)) ); end
Код С, cAdd.c
, использует линейную индексацию, чтобы получить доступ к элементам массивов:
#include <stdio.h> #include <stdlib.h> #include "cAdd.h" void cAdd(const double* in1, const double* in2, double* out, int numel) { int i; for (i=0; i<numel; i++) { out[i] = in1[i] + in2[i]; } }
Чтобы создать код С, необходимо обеспечить заголовочный файл, cAdd.h
, с функциональной подписью:
void cAdd(const double* in1, const double* in2, double* out, int numel);
Протестируйте код С путем генерации MEX-функции и сравнения ее выхода с выходом от операции сложения в MATLAB.
A = rand(2,2)+1; B = rand(2,2)+10; codegen adderRef -args {A, B} cAdd.c cAdd.h -report if (adderRef_mex(A,B) - (A+B) == 0) fprintf(['\n' 'adderRef was successful.']); end
Code generation successful: To view the report, open('codegen/mex/adderRef/html/report.mldatx'). adderRef was successful.
В этом примере показано, как вызвать функцию C, которая использует типы данных, которые исходно не заданы в MATLAB®.
Например, если ваш код С выполняет ввод или вывод файла на C 'ФАЙЛ *' тип, в MATLAB нет никакого соответствующего типа. Чтобы взаимодействовать с этим типом данных в вашем коде MATLAB, необходимо инициализировать его при помощи функционального coder.opaque
. В случае типов структуры можно использовать coder.cstructname
.
Например, считайте функцию MATLAB addCTypes.m
. Эта функция использует coder.ceval
с входными типами, заданными во внешнем коде. Функциональный coder.opaque
инициализирует тип в MATLAB.
function [out] = addCTypes(a,b) %#codegen % generate include statements for header files coder.cinclude('MyStruct.h'); coder.cinclude('createStruct.h'); coder.cinclude('useStruct.h'); % initialize variables before use in = coder.opaque('MyStruct'); out = 0; % call C functions in = coder.ceval('createStruct',a,b); out = coder.ceval('useStruct',in); end
createStruct
функционируйте выводит тип структуры C:
#include <stdio.h> #include <stdlib.h> #include "MyStruct.h" #include "createStruct.h" struct MyStruct createStruct(double a, double b) { struct MyStruct out; out.p1 = a; out.p2 = b; return out; }
useStruct
функция выполняет операцию на типе C:
#include "MyStruct.h" #include "useStruct.h" double useStruct(struct MyStruct in) { return in.p1 + in.p2; }
Чтобы сгенерировать код, задайте источник (.c) файлы как входные параметры:
codegen addCTypes -args {1,2} -report createStruct.c useStruct.c
Code generation successful: To view the report, open('codegen/mex/addCTypes/html/report.mldatx').
В этом примере показано, как интегрировать внешний код, который работает с массивом стиля C с кодом MATLAB®. Внешний код вычисляет суммирование по данным массива. Можно настроить код, чтобы изменить входные данные или расчет.
В этом примере показано, как объединить несколько различных элементов внешней функциональности интеграции кода. Например, вы:
Интерфейс с внешней структурой вводит при помощи coder.cstructname
Интерфейс с внешним типом указателя при помощи coder.opaque
Выполните внешний код при помощи coder.ceval
Передайте данные в отношении внешнего кода при помощи coder.ref
Исследуйте интегрированный код
Функция extSum использует внешний код С, чтобы вычислить операцию суммирования на массиве 32-битных целых чисел. Размером массивов управляет ввод данных пользователем.
function x = extSum(u) %#codegen % set bounds on input type to use static memory allocation u = int32(u); assert(0 < u && u < 101); % initialize an array temparray = int32(1):u; % declare an external structure and use it s = makeStruct(u); x = callExtCode(s, temparray);
Чтобы упростить сгенерированный код, вы устанавливаете границы на размере массива. Границы предотвращают использование динамического выделения памяти в сгенерированном коде.
Функциональный makeStruct
объявляет, что структура MATLAB вводит, и инициализирует одно из полей к типу указателя при помощи coder.opaque
. Структура C, соответствующая этому определению, содержится в заголовочном файле, который вы обеспечиваете при помощи HeaderFile
параметр в coder.cstructname
функция. Тип структуры C обеспечивает простое представление для массива целых чисел.
function s = makeStruct(u) % create structure type based on external header definition s.numel = u; s.vals = coder.opaque('int32_T *','NULL'); coder.cstructname(s,'myArrayType','extern','HeaderFile','arrayCode.h');
С внешним типом структуры, полностью инициализированным, вы передаете его как вход к внешнему коду в callExtCode
функция. Эта функция инициализирует массив, вызывает операцию на массиве, чтобы возвратить один выходной параметр, и затем освобождает инициализированную память.
function x = callExtCode(s, temparray) % declare output type x = int32(0); % declare external source file coder.updateBuildInfo('addSourceFiles','arrayCode.c'); % call c code coder.ceval('arrayInit',coder.ref(s),coder.ref(temparray)); x = coder.ceval('arraySum',coder.ref(s)); coder.ceval('arrayDest',coder.ref(s));
Функция использует coder.updateBuildInfo
предоставлять.c файл генератору кода.
Сгенерируйте MEX-функцию
Сгенерировать MEX-функцию, которую можно запустить и протестировать в MATLAB, введите:
codegen extSum -args {10}
Протестируйте MEX-функцию. Войдите:
extSum_mex(10)
ans = int32 55
Внешний код С, содержавшийся в файлах arrayCode.c
и arrayCode.h
, использует пользовательское определение типа int32_T
. Сгенерированный код MEX производит и использует это пользовательское определение типа. Если вы хотите сгенерировать автономный (lib, dll, или exe) код, который использует этот пользовательский тип данных, то можно изменить DataTypeReplacement
свойство вашего объекта настройки. Смотрите Отображение Типы MATLAB к Типам в Сгенерированном коде.
codegen
| coder.ceval
| coder.cinclude
| coder.cstructname
| coder.opaque
| coder.ref
| coder.rref
| coder.wref