Вызовите Код C/C++ из КОДА MATLAB

Из вашего кода MATLAB® можно непосредственно вызвать внешний код C/C++, также названный пользовательским кодом или унаследованным кодом. Генератор кода интегрирует ваш код C/C++ в код C/C++, сгенерированный от MATLAB. Интегрируйте код, когда у вас будут внешние библиотеки, оптимизированный код или объектные файлы, разработанные на C/C++. Следующее является некоторыми первичными рабочими процессами для внешней интеграции кода. Для большего количества примеров смотрите страницу с описанием 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 c:

#include <stdio.h>
#include <stdlib.h>
#include "adder.h"

double adder(double in1, double in2)
{
  return in1 + in2;
}

Чтобы интегрировать adder с вашим кодом MATLAB, вам нужен заголовочный файл, который содержит прототипа функции. Смотрите файл adder.h h:

double adder(double in1, double in2);

Используйте команду coder.ceval, чтобы вызвать функцию C в mathOpsIntegrated.m 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

Язык 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 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 к Типам в Сгенерированном коде.

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

| | | | | | |

Похожие темы

Была ли эта тема полезной?