在MATLAB中®代码,您可以直接调用外部C/ c++代码,也称为自定义代码或遗留代码。要调用C/ c++函数,请使用coder.ceval
。代码生成器将C / C ++代码集成到从MATLAB生成的C / C ++代码中。当您想要与生成的代码一起使用的C / C ++中开发的外部库,优化的代码或对象文件时,将代码集成在一起。当外部代码使用Matlab未定义或识别的可变类型时,使用coder.opaque
功能与coder.ceval
。若要保留某些标识符名称,以便在您希望与生成的代码集成的自定义C/ c++代码中使用,请使用Coder.ReservedName.
功能。
以下是外部代码集成的一些主要工作流程。有关更多示例,请参阅coder.ceval
参考页面。
笔记
通过使用coder.ceval
,您获得对外部代码的不受限制的访问权限。滥用代码中的这些函数或错误可以稳定MATLAB并导致它停止工作。要调试代码并从编译中分析错误消息,请查看构建日志代码生成报告中的选项卡。
这个例子展示了如何使用MATLAB®代码集成一个简单的C函数coder.ceval
。考虑matlab函数,mathops.
:
函数[添加,Multed] = MathOPS(In1,In2)添加= In1 + In2;multied = In1 * In2;结尾
对于本例,假设您希望通过使用外部C代码实现加法操作。考虑C函数,加法器
,在文件中实现Adder.c.
:
#include#include #include“Adder.h”双加法器(Double In1,Double In2){返回In1 + In2;}
集成加法器
使用MATLAB代码,您需要一个包含函数原型的头文件。查看文件Adder.h.
:
双加法器(双IN1,双IN2);
使用coder.ceval
命令来调用C函数mathOpsIntegrated.m
。通过使用包含头文件coder.cinclude
。
函数[added, multed] = mathOpsIntegrated(in1, in2)% # codegen代码生成的%,以输出变量为例%数据类型,大小和复杂性添加= 0;%在C代码中生成包含coder.cinclude ('adder.h');%计算C函数添加= coder.ceval(“毒蛇”三机一体,in2);multied = In1 * In2;结尾
要生成代码,请使用codegen
命令。指定源文件Adder.c.
作为输入。要测试C代码,请执行MEX函数并检查输出结果。
codegenMathopsintegrated.- args.{1,2}Adder.c.[test1, test2] = mathOpsIntegrated_mex(10, 20)
代码生成成功。test1 = 30 test2 = 200
C语言限制函数返回多个输出。相反,它们只返回单个标量值。MATLAB函数coder.ref
那Coder.Rref.
和coder.wref
允许你从一个外部C/ c++函数返回多个输出。
例如,假设你写了一个MATLAB函数Foo
这需要两个输入X
和y
并返回三个输出一种
那B.
,C
。在MATLAB中,您称此功能如下:
[a, b, c] = foo (x, y)
如果你重写Foo
作为C函数,您不能返回三个独立的值一种
那B.
,C
通过A.返回
陈述。相反,使用多个指针类型参数创建C函数并通过引用传递输出参数。例如:
Void foo(double x,double y,double *a,double *b,double *c)
然后,您可以通过使用MATLAB功能调用C函数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)
通过参数
通过引用,你的外部C/ c++函数必须完全初始化被引用的内存参数
。
此示例显示如何通过引用和从外部C函数传递数据。
通过引用传递是C / C ++代码集成的重要技术。当您通过引用传递数据时,程序不需要将数据从一个函数复制到另一个函数。通过按值传递,C代码只能返回一个标量变量。通过引用通过,C代码可以返回多个变量,包括数组。
考虑MATLAB功能adderRef
。这个函数使用外部C代码添加两个数组。这Coder.Rref.
和coder.wref
命令指示代码生成器将指针传递给阵列,而不是复制它们。
函数out = adderRef(in1, in2)% # codegen= 0(大小(in));%将输入的numel(in1)转换为整数类型%以匹配CADD函数签名Coder.CEVAL(“cAdd”,coder.rref(in1),coder.rref(In2),Coder.Wref(Out),Int32(Numel(In1)));结尾
C代码,cAdd.c
,使用线性索引来访问数组的元素:
#include#include #include "cAdd.h" void cAdd(const double* in1, const double* in2, double* out, int numel) {int i;(我= 0;我<元素个数;I ++) {out[I] = in1[I] + in2[I];}}
要构建C代码,您必须提供一个头文件,cAdd.h
,功能签名:
void cadd(const double *in1,const double * In2,Double * Out,Int Numel);
通过生成MEX功能并将其输出与来自MATLAB中的添加操作的输出进行比较来测试C代码。
一个=兰德(2,2)+ 1;B =兰德(2,2)+ 10;codegenadderRef- args.{A,B}cAdd.ccAdd.h-报告如果(adderRef_mex(A,B) - (A+B) == 0)'\ n''Adderref成功。']);结尾
代码生成成功:要查看报告,打开('codegen/mex/adderRef/html/report.mldatx')。adderRef是成功的。
这个例子展示了如何调用一个C函数,该函数使用的数据类型不是在MATLAB®中本机定义的。
例如,如果C代码在C'文件*类型上执行文件输入或输出,则MATLAB中没有相应的类型。要在MATLAB代码中与此数据类型进行交互,您必须使用该功能初始化它coder.opaque
。对于结构类型,可以使用coder.cstructname
。
例如,考虑Matlab功能addctypes.m.
。此功能使用coder.ceval
使用外部代码中定义的输入类型。这个函数coder.opaque
初始化MATLAB中的类型。
函数[出]= addCTypes (a, b)% # codegen%Generate包括标题文件的语句coder.cinclude ('mystruct.h');coder.cinclude (“createStruct.h”);coder.cinclude ('ustruct.h');在使用前初始化变量在=编码器。kque('mystrict');出= 0;%调用C函数在= coder.ceval(“createStruct”,a,b);OUT = CODER.CEVAL('ustruct',);结尾
这gercestruct.
功能输出C结构类型:
#include#include #include“mystruct.h”#include“createStruct.h”struct mystruct creatstruct(double a,double b){struct mystrict out;out.p1 = a;Out.p2 = b;返回;}
这us
函数在C类型上执行操作:
#include“mystruct.h”#include“ustruct.h”双重ustruct(struct mystruct in){return in.p1 + in.p2;}
要生成代码,请指定源(.c)文件作为输入:
codegenaddctypes.- args.{1,2}-报告createstruct.c.ustruct.c
代码生成成功:要查看报告,请打开('codegen / mex / addctypes / html / export.mldatx')。
此示例显示如何将在C样式阵列上使用MATLAB®代码集成外部代码。外部代码计算阵列数据的求和。您可以自定义代码以更改输入数据或计算。
这个例子展示了如何组合外部代码集成功能的多个不同元素。例如,您:
使用外部结构类型的接口coder.cstructname
使用一个外部指针类型的接口coder.opaque
使用来执行外部代码coder.ceval
通过引用向外部代码传递数据coder.ref
探索集成的代码
extsum函数使用外部C代码来计算32位整数的数组上的求和操作。数组大小由用户输入控制。
函数x = extsum(u)% # codegen%设置输入类型的边界以使用静态内存分配u = int32(u);断言(0 初始化数组temparray = int32 (1): u;%声明一个外部结构并使用它s = makeStruct (u);x = calllextcode (s, temparray);
要简化生成的代码,请在阵列大小上设置绑定。界限可防止在生成的代码中使用动态内存分配。
这个函数mak
声明MATLAB结构类型并通过使用将其中一个字段初始化为指针类型coder.opaque
。与此定义对应的C结构包含在头文件中,您可以使用HeaderFile
参数coder.cstructname
功能。C结构类型为整数数组提供了一个简单的表示。
函数s = makeStruct (u)%创建基于外部标题定义的结构类型s.numel = u;s.vals = coder.opaque ('int32_t *'那'空值');编码器.cstructName(s,'myarraytype'那'extern'那'头球文件'那'ArrayCode.h');
将外部结构类型完全初始化后,将其作为输入传递给callExtCode
功能。此函数初始化数组,调用数组上的操作以返回一个输出,然后释放初始化内存。
函数x = CallextCode(s,temparray)%声明输出类型x = int32(0);%声明外部源文件coder.updateBuildInfo (“addSourceFiles”那'arraycode.c');%调用c代码Coder.CEVAL('ArrayInit',coder.ref(s),coder.ref(temparray));x = coder.ceval(“arraySum”,编码器.ref(s));Coder.CEVAL('arraydest',编码器.ref(s));
功能使用Coder.updateBuildInfo.
将.c文件提供给代码生成器。
生成一个MEX函数
要生成一个可以在MATLAB中运行和测试的MEX函数,输入:
codegenextsum.- args.{10}
代码生成成功。
测试MEX函数。输入:
extsum_mex(10)
ANS = INT32 55
外部C代码,包含在文件中ArrayCode.c.
和ArrayCode.h.
,使用自定义类型定义int32_T
。生成的MEX代码生成并使用此自定义类型定义。如果要生成使用此自定义数据类型的独立(lib,dll或exe)代码,则可以修改DataTypeReplacement
属性的。看到MATLAB类型映射到生成代码中的类型。
codegen
|coder.ceval
|coder.cinclude
|coder.cstructname
|coder.opaque
|coder.ref
|Coder.ReservedName.
|Coder.Rref.
|coder.wref