主要内容

调用C / C ++代码MATLAB代码

在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并导致它停止工作。要调试代码并从编译中分析错误消息,请查看构建日志代码生成报告中的选项卡。

致电C代码

这个例子展示了如何使用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函数返回多个值

C语言限制函数返回多个输出。相反,它们只返回单个标量值。MATLAB函数coder.refCoder.Rref.coder.wref允许你从一个外部C/ c++函数返回多个输出。

例如,假设你写了一个MATLAB函数Foo这需要两个输入Xy并返回三个输出一种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.wrefCoder.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类型映射到生成代码中的类型

也可以看看

||||||||

相关的话题