exponenta event banner

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.

Создание файла заголовка 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 функция генерирует код C в \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
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. '-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 идентичны. Генерируется код C:

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, которая вызывает пользовательский код C, который принимает ввод комплексных чисел. Необходимо определить параметры ввода кода C таким образом, чтобы вводимые комплексные номера из функции MATLAB могли отображаться на код C.

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

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

Дополнительные сведения см. в разделе Сопоставление типов MATLAB типам в сгенерированном коде.

Код C, который требуется интегрировать, должен включать rtwtypes.h файл заголовка. Пример кода C 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);
}

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
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 или средства проверки или является свойством 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