Main Content

coder.ceval

Call external C/C++ function

Description

example

coder.ceval(cfun_name)executes the external C/C++ function specified bycfun_name.Definecfun_namein an external C/C++ source file or library. Provide the external source, library, and header files to the code generator.

example

coder.ceval(cfun_name,cfun_arguments)executescfun_namewith argumentscfun_argumentscfun_argumentsis a comma-separated list of input arguments in the order thatcfun_namerequires.

By default,coder.cevalpasses arguments by value to the C/C++ function whenever C/C++ supports passing arguments by value. To makecoder.cevalpass arguments by reference, use the constructscoder.ref,coder.rref, andcoder.wref.If C/C++ does not support passing arguments by value, for example, if the argument is an array,coder.cevalpasses arguments by reference. If you do not usecoder.ref,coder.rreforcoder.wref, a copy of the argument can appear in the generated code to enforce MATLAB®semantics for arrays.

example

coder.ceval('-global',cfun_name)executescfun_nameand indicates thatcfun_nameuses one or more MATLAB global variables. The code generator can then produce code that is consistent with this global variable usage.

Note

The-globalflag is only supported for code generation. You cannot include this flag while callingcoder.cevalin MATLAB Function blocks.

coder.ceval('-global',cfun_name,cfun_arguments)executescfun_namewith argumentscfun_argumentsand indicates thatcfun_nameuses one or more MATLAB global variables.

coder.ceval('-gpudevicefcn',devicefun_name,devicefun_arguments)allows you to call CUDA®GPU__device__functions from within kernels.'-gpudevicefcn'indicates tocoder.cevalthat the target function is on the GPU device.devicefun_nameis the name of the__device__function anddevicefun_argumentsis a comma-separated list of input arguments in the order thatdevicefun_namerequires. This option requires the GPU Coder™ product.

example

coder.ceval('-layout:rowMajor',cfun_name,cfun_arguments)executescfun_namewith argumentscfun_argumentsand passes data stored in row-major layout. When called from a function that uses column-major layout, the code generator converts inputs to row-major layout and converts outputs back to column-major layout. For a shorter syntax, usecoder.ceval('-row',...)

coder.ceval('-layout:columnMajor',cfun_name,cfun_arguments)executescfun_namewith argumentscfun_argumentsand passes data stored in column-major layout. When called from a function that uses row-major layout, the code generator converts inputs to column-major layout and converts outputs back to row-major layout. For a shorter syntax, usecoder.ceval('-col',...)

coder.ceval('-layout:any',cfun_name,cfun_arguments)executescfun_namewith argumentscfun_argumentsand passes data with its current array layout, even when array layouts do not match. The code generator does not convert the array layout of the input or output data.

example

cfun_return = coder.ceval(___)executescfun_nameand returns a single scalar value,cfun_return, corresponding to the value that the C/C++ function returns in thereturnstatement. To be consistent with C/C++,coder.cevalcan return only a scalar value. It cannot return an array. Use this option with any of the input argument combinations in the previous syntaxes.

Examples

collapse all

Call a C functionfoo(u)from a MATLAB function from which you intend to generate C code.

Create a C header filefoo.hfor a functionfoothat takes two input parameters of typedoubleand returns a value of typedouble

double foo(double in1, double in2);

Write the C functionfoo.c

#include  #include  #include "foo.h" double foo(double in1, double in2) { return in1 + in2; }

Write a functioncallfoothat callsfooby usingcoder.ceval.Provide the source and header files to the code generator in the function.

functiony = callfoo%#codegeny = 0.0;ifcoder.target('MATLAB')% Executing in MATLAB, call MATLAB equivalent of% C function fooy = 10 + 20;else% Executing in generated code, call C function foocoder.updateBuildInfo('addSourceFiles','foo.c'); coder.cinclude('foo.h'); y = coder.ceval('foo', 10, 20);endend

Generate C library code for functioncallfoo.Thecodegenfunction generates C code in the\codegen\lib\callfoosubfolder.

codegen-config:libcallfoo-report

Call a C library function from MATLAB code.

Write a MATLAB functionmyabsval

functiony = myabsval(u)%#codegeny = abs(u);

Generate a C static library formyabsval, using the-argsoption to specify the size, type, and complexity of the input parameter.

codegen-config:libmyabsval-args{0.0}
Thecodegenfunction creates the library filemyabsval.liband header filemyabsval.hin the folder\codegen\lib\myabsval.(The library file extension can change depending on your platform.) It generates the functionsmyabsval_initializeandmyabsval_terminatein the same folder.

编写一个MATLAB函数调用生成的Cbrary function usingcoder.ceval

functiony = callmyabsval(y)%#codegen%切ck the target. Do not use coder.ceval if callmyabsval is% executing in MATLABifcoder.target('MATLAB')% Executing in MATLAB, call function myabsvaly = myabsval(y);else% add the required include statements to generated function codecoder.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 timecoder.ceval('myabsval_initialize');% Call the generated C library function myabsvaly = coder.ceval('myabsval',y);% Call the terminate function after% calling the C function for the last timecoder.ceval('myabsval_terminate');end

Generate the MEX functioncallmyabsval_mex.Provide the generated library file at the command line.

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

Rather than providing the library at the command line, you can usecoder.updateBuildInfoto specify the library within the function. Use this option to preconfigure the build. Add this line to theelseblock:

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

Note

TheSTART_DIRmacro is only supported for generating code withMATLAB Coder™

Run the MEX functioncallmyabsval_mexwhich calls the library functionmyabsval

callmyabsval_mex(-2.75)
ans = 2.7500

Call the MATLAB functioncallmyabsval

callmyabsval(-2.75)
ans = 2.7500
Thecallmyabsvalfunction exhibits the desired behavior for execution in MATLAB and in code generation.

Use the'-global'flag when you call a C function that modifies a global variable.

Write a MATLAB functionuseGlobalthat calls a C functionaddGlobal.Use the'-global'flag to indicate to the code generator that the C function uses a global variable.

functiony = useGlobal()globalg; t = g;% compare execution with/without '-global' flagcoder.ceval('-global','addGlobal'); y = t;end

Create a C header fileaddGlobal.hfor the functionaddGlobal

void addGlobal(void);

Write the C functionaddGlobalin the fileaddGlobal.c.This function includes the header fileuseGlobal_data.hthat the code generator creates when you generate code for the functionuseGlobal.This header file contains the global variable declaration forg

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

Generate the MEX function foruseGlobal.To define the input to the code generator, declare the global variable in the workspace.

globalg; g = 1; codegenuseGlobal-reportaddGlobal.haddGlobal.cy = useGlobal_mex();

With the'-global'flag, the MEX function produces the resulty = 1.The'-global'flag indicates to the code generator that the C function possibly modifies the global variable. ForuseGlobal, the code generator produces this code:

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

Without the'-global'flag, the MEX function producesy = 2.Because there is no indication that the C function modifiesg, the code generator assumes thatyandgare identical. This C code is generated:

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

Suppose that you have a C functiontestRMthat is designed to use row-major layout. You want to integrate this function into a MATLAB functionbarthat operates on arrays. The functionbaris designed to use column-major layout, employing thecoder.columnMajordirective.

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

In the generated code, the code generator inserts a layout conversion from column-major layout to row-major layout on the variableinbefore passing it totestRM.On the output variableout, the code generator inserts a layout conversion back to column-major.

In general, if you do not specify thelayoutoption forcoder.ceval, the external function arguments are assumed to use column-major.

假设您有一个MATLAB函数调用custom C code that takes complex number inputs. You must define your C code input parameters so that the complex number inputs from your MATLAB function can map to your C code.

In generated code, complex numbers are defined as astructthat has two fields,reandim, which are the real and imaginary part of a complex number respectively. Thisstructis defined in the header filertwtypes.h, which you can find in thecodegen\lib\functionNamefolder of your current path. Thestructis defined as follows:

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

For more information, seeMapping MATLAB Types to Types in Generated Code

The C code that you want to integrate must include thertwtypes.hheader file. An example C codefoo.cis shown below:

#include "foo.h" #include #include #include "rtwtypes.h" double foo(creal_T x) { double z = 0.0; z = x.re*x.re + x.im*x.im; return (z); }

Thestructis namedcreal_T.A header filefoo.hmust also be defined as:

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

The MATLAB code executesfoo.cby using thecoder.cevalfunction that has a complex numbers input:

functiony = complexCeval%#codegeny = 0.0; coder.updateBuildInfo('addSourceFiles','foo.c'); coder.cinclude('foo.h'); y = coder.ceval('foo', 10+20i);end
Thecoder.cevalcommand takes the complex number input. The code generator maps the complex number to thestruct creal_Tvariablexand its fieldsreandim

Generate code for the functioncomplexCevalby running this command:

codegen-config:lib-reportcomplexCeval

Input Arguments

collapse all

Name of external C/C++ function to call.

Example:coder.ceval('foo')

Data Types:char|string

Comma-separated list of input arguments in the order thatcfun_namerequires.

Example:coder.ceval('foo', 10, 20);

Example:coder.ceval('myFunction', coder.ref(x));

Data Types:single|double|int8|int16|int32|int64|uint8|uint16|uint32|uint64|logical|char|struct
Complex Number Support:Yes

Limitations

  • You cannot usecoder.cevalon functions that you declare extrinsic withcoder.extrinsic

  • When the LCC compiler creates a library, it adds a leading underscore to the library function names. If the compiler for the library was LCC and your code generation compiler is not LCC, you must add the leading underscore to the function name, for example,coder.ceval('_mylibfun').If the compiler for a library was not LCC, you cannot use LCC to generate code from MATLAB code that calls functions from that library. Those library function names do not have the leading underscore that the LCC compiler requires.

  • If a property has a get method, a set method, or validators, or is a System object™ property with certain attributes, then you cannot pass the property by reference to an external function. SeePassing By Reference Not Supported for Some Properties

  • Variable-size matrices as entry-point parameters are not supported for row-major code generation.

Tips

  • For code generation, before callingcoder.ceval, you must specify the type, size, and complexity data type of return values and output arguments.

  • To applycoder.cevalto a function that accepts or returns variables that do not exist in MATLAB code, such as pointers,FILEtypes for file I/O, and C/C++ macros, use thecoder.opaquefunction.

  • Usecoder.cevalonly in MATLAB for code generation.coder.cevalgenerates an error in uncompiled MATLAB code. To determine if a MATLAB function is executing in MATLAB, usecoder.target.如果函数执行在MATLAB调用MATLAB version of the C/C++ function.

  • External code called by usingcoder.cevaland the generated code run within the same process and share memory. If external code erroneously writes to the memory that contains data structures used by the generated code, it might cause the process to behave unexpectedly or crash. For example, if the external code attempts to write data to an array after its end point, the process might behave unexpectedly or crash.

  • MATLAB uses UTF-8 as its system encoding on Windows®platform. As a result, system calls made from within a generated MEX function accept and return UTF-8 encoded strings. By contrast, the code generated byMATLAB Coderencodes text data by using the encoding specified by the Windows locale. So, if your MATLAB entry-point function usescoder.cevalto call external C/C++ functions that assume a different system encoding, then the generated MEX function might produce garbled text. If this happens, you must update the external C/C++ functions to handle this situation.

Extended Capabilities

C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.

GPU Code Generation
Generate CUDA® code for NVIDIA® GPUs using GPU Coder™.

Version History

Introduced in R2011a

Baidu
map