coder.ceval

Вызов внешней функции C/C + +

Описание

пример

coder.ceval(cfun_name) выполняет внешнюю функцию C/C + +, заданную cfun_name. Определите cfun_name во внешнем исходном файле C/C + + или библиотеке. Предоставьте генератору кода файлы внешнего источника, библиотеки и заголовков.

пример

coder.ceval(cfun_name,cfun_arguments) выполняет cfun_name с аргументами cfun_arguments. cfun_arguments является список , разделенный запятыми входных параметров в том порядке, в котором cfun_name требует.

По умолчанию, coder.ceval передает аргументы по значению в функцию C/C + + всякий раз, когда C/C + + поддерживает передачу аргументов по значению. Сделатьcoder.ceval передайте аргументы по ссылке, используйте конструкции coder.ref, coder.rref, и coder.wref. Если C/C + + не поддерживает передачу аргументов по значению, например, если аргумент является массивом,coder.ceval передает аргументы по ссылке. Если вы не используете coder.ref, coder.rref или coder.wrefкопия аргумента может появиться в сгенерированном коде для принудительного применения MATLAB® семантика для массивов.

пример

coder.ceval('-global',cfun_name) выполняет cfun_name и указывает, что cfun_name использует одну или несколько глобальных переменных MATLAB. Генератор кода может затем получить код, который согласуется с этим глобальным использованием переменной.

coder.ceval('-global',cfun_name,cfun_arguments) выполняет cfun_name с аргументами cfun_arguments и указывает, что cfun_name использует одну или несколько глобальных переменных MATLAB.

coder.ceval('-gpudevicefcn',devicefun_name,devicefun_arguments) позволяет вызывать CUDA® Графический процессор __device__ функции из ядер. '-gpudevicefcn' указывает на coder.ceval что целевая функция находится на устройстве GPU. devicefun_name - имя объекта __device__ функции и devicefun_arguments является список , разделенный запятыми входных параметров в том порядке, в котором devicefun_name требует. Для этой опции требуется продукт GPU Coder™.

пример

coder.ceval('-layout:rowMajor',cfun_name,cfun_arguments) выполняет cfun_name с аргументами cfun_arguments и передает данные, сохраненные в основном размещении. При вызове из функции, которая использует размещение основного столбца, генератор кода преобразует входы в размещение основной строки и преобразует выходы обратно в размещение основного столбца. Для более короткого синтаксиса используйте coder.ceval('-row',...).

coder.ceval('-layout:columnMajor',cfun_name,cfun_arguments) выполняет cfun_name с аргументами cfun_arguments и передает данные, хранимые в размещении столбца. При вызове из функции, которая использует размещение основной строки, генератор кода преобразует входы в размещение основной строки и преобразует выходы обратно в размещение основной строки. Для более короткого синтаксиса используйте coder.ceval('-col',...).

coder.ceval('-layout:any',cfun_name,cfun_arguments) выполняет cfun_name с аргументами cfun_arguments и передает данные с текущим размещением массива, даже когда размещения массива не совпадают. Генератор кода не преобразует размещение массива входных или выходных данных.

пример

cfun_return = coder.ceval(___) выполняет cfun_name и возвращает одно скалярное значение, cfun_return, соответствующее значению, которое функция C/C + + возвращает в return оператор. Чтобы соответствовать C/C + +,coder.ceval может вернуть только скалярное значение. Он не может вернуть массив. Используйте эту опцию с любыми комбинациями входных аргументов в предыдущих синтаксисах.

Примеры

свернуть все

Вызовите функцию C foo(u) из функции MATLAB, из которой вы намереваетесь сгенерировать код С

Создайте файл заголовка C foo.h для функционального foo который принимает два входных параметра типа double и возвращает значение типа double.

double foo(double in1, double in2);

Напишите функцию C foo.c.

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

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

Напишите функцию callfoo который вызывает foo при помощи coder.ceval. Предоставьте исходный код и заголовочные файлы генератору кода в функции.

function y = callfoo  %#codegen
y = 0.0;
if coder.target('MATLAB')
    % Executing in MATLAB, call MATLAB equivalent of
    % C function foo
    y = 10 + 20;
else
    % Executing in generated code, call C function foo
    coder.updateBuildInfo('addSourceFiles','foo.c');
    coder.cinclude('foo.h');
    y = coder.ceval('foo', 10, 20);
end
end

Сгенерируйте код библиотеки C для callfoo функций. codegen функция генерирует код С в \codegen\lib\callfoo подпапка.

codegen -config:lib callfoo -report

Вызовите функцию библиотеки на C из кода MATLAB.

Написание функции MATLAB myabsval.

function y = myabsval(u)   
%#codegen
y = abs(u);

Сгенерируйте статическую библиотеку на C для myabsval, с использованием -args опция для задания размера, типа и сложности входного параметра.

codegen -config:lib myabsval -args {0.0}
codegen функция создает файл библиотеки myabsval.lib и заголовочный файл myabsval.h в папке \codegen\lib\myabsval. (Расширение файла библиотеки может измениться в зависимости от вашей платформы.) Он генерирует функции myabsval_initialize и myabsval_terminate в той же папке.

Написание функции MATLAB для вызова сгенерированной функции библиотеки C с помощью coder.ceval.

function y = callmyabsval(y)  
%#codegen
% Check the target. Do not use coder.ceval if callmyabsval is
% executing in MATLAB
if coder.target('MATLAB')
  % Executing in MATLAB, call function myabsval
  y = myabsval(y);
else
  % add the required include statements to generated function code
  coder.updateBuildInfo('addIncludePaths','$(START_DIR)\codegen\lib\myabsval');
  coder.cinclude('myabsval_initialize.h');
  coder.cinclude('myabsval.h');
  coder.cinclude('myabsval_terminate.h');

  % Executing in the generated code. 
  % Call the initialize function before calling the 
  % C function for the first time
  coder.ceval('myabsval_initialize');

  % Call the generated C library function myabsval
  y = coder.ceval('myabsval',y);
  
  % Call the terminate function after
  % calling the C function for the last time
  coder.ceval('myabsval_terminate');
end

Сгенерируйте MEX-функцию callmyabsval_mex. Предоставьте сгенерированный файл библиотеки в командной строке.

codegen -config:mex callmyabsval codegen\lib\myabsval\myabsval.lib -args {-2.75}

Вместо предоставления библиотеки в командной строке можно использовать coder.updateBuildInfo для задания библиотеки в функции. Используйте эту опцию для предварительной настройки сборки. Добавьте эту линию к else блок:

coder.updateBuildInfo('addLinkObjects','myabsval.lib','$(START_DIR)\codegen\lib\myabsval',100,true,true);

Запуск MEX-функции callmyabsval_mex который вызывает функцию библиотеки myabsval.

callmyabsval_mex(-2.75)
ans =

    2.7500

Вызовите функцию MATLAB callmyabsval.

callmyabsval(-2.75)
ans =

    2.7500
The callmyabsval функция показывает желаемое поведение для выполнения в MATLAB и в генерации кода.

Используйте '-global' флаг при вызове функции C, которая изменяет глобальную переменную.

Написание функции MATLAB useGlobal который вызывает функцию C addGlobal. Используйте '-global' флаг для указания генератору кода, что функция C использует глобальную переменную.

function y = useGlobal()
global g;
t = g;
% compare execution with/without '-global' flag
coder.ceval('-global','addGlobal'); 
y = t;
end

Создайте файл заголовка C addGlobal.h для функции addGlobal.

void addGlobal(void);

Напишите функцию C addGlobal в файле addGlobal.c. Эта функция включает заголовочный файл useGlobal_data.h который генератор кода создает, когда вы генерируете код для функции useGlobal. Этот файл заголовка содержит объявление глобальной переменной для g.

#include "addGlobal.h"
#include "useGlobal_data.h"
void addGlobal(void) {
    g++;
}

Сгенерируйте MEX-функцию для useGlobal. Чтобы определить вход в генератор кода, объявите глобальную переменную в рабочей области.

global g;
g = 1;
codegen useGlobal -report addGlobal.h addGlobal.c
y = useGlobal_mex();

С '-global' флаг, MEX-функция создает результат y = 1. The '-global' флаг указывает генератору кода, что функция C, возможно, изменяет глобальную переменную. Для useGlobalгенератор кода производит этот код:

real_T useGlobal(const emlrtStack *sp)
{
  real_T y;
  (void)sp;
  y = g;
  addGlobal();
  return y;
}

Без '-global' флаг, MEX-функция создает y = 2. Потому что нет никаких признаков того, что функция C изменяется gГенератор кода принимает, что y и g идентичны. Этот код С генерируется:

real_T useGlobal(const emlrtStack *sp)
{
  (void)sp;
  addGlobal();
  return g;
}

Предположим, что у вас есть функция C testRM который предназначен для использования размещения с основной строкой. Вы хотите интегрировать эту функцию в функцию MATLAB bar который работает с массивами. Функция bar предназначен для использования основного размещения столбца, используя coder.columnMajor директива.

function out = bar(in)
%#codegen
coder.columnMajor;
coder.ceval('-layout:rowMajor','testRM', ...
    coder.rref(in),coder.wref(out));
end

В сгенерированном коде генератор кода вставляет преобразование размещения из основного размещения столбца в основное размещение строки переменной in прежде чем передать его в testRM. На переменном выходе outгенератор кода вставляет преобразование размещения назад в основной столбец.

В целом, если вы не задаете layout опция для coder.ceval, внешние аргументы функции приняты, чтобы использовать основной столбец.

Предположим, у вас есть функция MATLAB, которая вызывает пользовательский код С, который принимает входные входы комплексного числа. Вы должны задать параметры Кода С входа, чтобы входные параметры комплексного числа из функции MATLAB могли сопоставиться с вашими Кодами С.

В сгенерированном коде комплексные числа заданы как struct который имеет два поля, re и im, которые являются вещественной и мнимой частью комплексного числа соответственно. Этот struct определяется в заголовочном файле rtwtypes.h, который вы можете найти в codegen\lib\functionName папка текущего пути. The struct определяется следующим образом:

typedef struct {
    real32_T re; /*Real Component*/
    real32_T im; /*Imaginary Component*/
} creal32_T;

Для получения дополнительной информации смотрите Отображение типов MATLAB с типами в Сгенерированном коде (MATLAB Coder).

Код С, который вы хотите интегрировать, должен включать rtwtypes.h заголовочный файл. Пример кода С foo.c показано ниже:

#include "foo.h"
#include<stdio.h>
#include<stdlib.h>
#include "rtwtypes.h"

double foo(creal32_T x) {
    double z = 0.0;
    z = x.re*x.re + x.im*x.im;
    return (z);
}

The struct называется creal32_T. Файл заголовка foo.h также должно быть определено как:

#include "rtwtypes.h"
double foo(creal32_T x);

Код MATLAB выполняет foo.c при помощи coder.ceval функция, которая имеет вход комплексных чисел:

function y = complexCeval  %#codegen
y = 0.0;
coder.updateBuildInfo('addSourceFiles','foo.c');
coder.cinclude('foo.h');
y = coder.ceval('foo', 10+20i);
end
The coder.ceval команда принимает вход комплексного числа. Генератор кода отображает комплексное число на struct creal32_T переменная x и его полей re и im.

Сгенерируйте код для функции complexCeval при выполнении этой команды:

codegen -config:lib -report complexCeval

Входные параметры

свернуть все

Имя внешней функции C/C + + для вызова.

Пример: coder.ceval('foo')

Типы данных: char | string

Список , разделенный запятыми входных параметров в том порядке, в котором cfun_name требует.

Пример: coder.ceval('foo', 10, 20);

Пример: coder.ceval('myFunction', coder.ref(x));

Типы данных: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical | char | struct
Поддержка комплексного числа: Да

Ограничения

  • Вы не можете использовать coder.ceval на функциях, которые вы объявляете внешними coder.extrinsic.

  • Когда компилятор LCC создает библиотеку, он добавляет начальное подчеркивание к именам функции библиотеки. Если компилятором для библиотеки был LCC, а ваш компилятор генерации кода - не LCC, необходимо добавить начальный символ подчеркивания в имя функции, например coder.ceval('_mylibfun'). Если компилятор для библиотеки не был LCC, вы не можете использовать LCC для генерации кода из кода MATLAB, который вызывает функции из этой библиотеки. Эти имена функции библиотеки не имеют начального подчеркивания, которое требуется компилятору LCC.

  • Если свойство имеет метод get, метод set, или validators, или является свойством System object™ с определенными атрибутами, то вы не можете передать свойство по ссылке на внешнюю функцию. Для некоторых свойств см. Раздел «Передача по ссылке» не поддерживается.

Совет

  • Для генерации кода, перед вызовом coder.cevalнеобходимо задать тип, размер и тип данных сложности значений возврата и выходных аргументов.

  • Подавать coder.ceval в функцию, которая принимает или возвращает переменные, которые не существуют в коде MATLAB, такие как указатели, FILE типы для файловых макросов ввода-вывода и C/C + +, используйте coder.opaque функция.

  • Использовать coder.ceval только в MATLAB для генерации кода. coder.ceval генерирует ошибку в нескомпилированном коде MATLAB. Чтобы определить, выполняется ли функция MATLAB в MATLAB, используйте coder.target. Если функция выполняется в MATLAB, вызовите версию MATLAB функции C/C + +.

Введенный в R2011a