Вызовите Код C/C++ из кода MATLAB

Из вашего MATLAB® код, можно непосредственно вызвать внешний код C/C++, также названный пользовательским кодом или унаследованным кодом. Чтобы вызвать функции C/C++, использовать coder.ceval. Генератор кода интегрирует ваш код C/C++ в код C/C++, сгенерированный из MATLAB. Интегрируйте код, когда существуют внешние библиотеки, оптимизированный код или объектные файлы, разработанные на C/C++, который вы хотите использовать со своим сгенерированным кодом. Когда внешний код использует типы переменных, которые не заданы или распознаны MATLAB, используют coder.opaque функция в сочетании с coder.ceval. Чтобы зарезервировать определенные имена идентификатора для использования в вашем пользовательском коде C/C++, который вы хотите интегрировать со сгенерированным кодом, используйте coder.reservedName функция.

Следующее является некоторыми первичными рабочими процессами для внешней интеграции кода. Для большего количества примеров смотрите 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)
Code generation successful.


test1 =

    30


test2 =

   200

Возвратите несколько значений от функции C

Язык C ограничивает функции в возвращении нескольких выходных параметров. Вместо этого они возвращают только одно, скалярное значение. Функции MATLAB coder.ref, coder.rref и coder.wref позвольте вам возвращать несколько выходных параметров внешней функции C/C++.

Например, предположите, что вы пишете функции MATLAB foo это берет два входных параметров x и y и возвращает три выходных параметров aB, и c. В MATLAB вы вызываете эту функцию можно следующим образом:

[a,b,c] = foo(x,y)

Если вы переписываете foo как функция C, вы не можете возвратить три отдельных значения aB, и 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}
Code generation successful.

Протестируйте MEX-функцию. Войдите:

extSum_mex(10)
ans =

  int32

   55

Внешний код С, содержавшийся в файлах arrayCode.c и arrayCode.h, использует пользовательское определение типа int32_T. Сгенерированный код MEX производит и использует это пользовательское определение типа. Если вы хотите сгенерировать автономный (lib, dll, или exe) код, который использует этот пользовательский тип данных, то можно изменить DataTypeReplacement свойство вашего объекта настройки. Смотрите Отображение Типы MATLAB к Типам в Сгенерированном коде.

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

| | | | | | | |

Похожие темы