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 то, что целевая функция находится на устройстве графического процессора. 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
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 идентичны. Этот код С сгенерирован:

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 папка вашего текущего пути. struct определяется следующим образом:

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

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

Код С, который вы хотите интегрировать, должен включать 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);
}

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.

  • Если свойство имеет получить метод, метод установки или блоки проверки допустимости, или является Системой 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++.

  • Внешний код, названный при помощи coder.ceval и сгенерированный код, запущенный в рамках того же процесса и памяти доли. Если внешний код ошибочно пишет в память, которая содержит структуры данных, используемые сгенерированным кодом, это может заставить процесс неожиданно вести себя или отказывать. Например, если внешний код пытается записать данные к массиву после того, как его конечная точка, процесс сможет неожиданно вести себя или катастрофический отказ.

Расширенные возможности

Генерация кода C/C++
Генерация кода C и C++ с помощью MATLAB® Coder™.

Генерация кода графического процессора
Сгенерируйте код CUDA® для NVIDIA® графические процессоры с помощью GPU Coder™.

Введенный в R2011a
Для просмотра документации необходимо авторизоваться на сайте