主要内容

调用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代码

这个例子展示了如何集成一个简单的C函数与MATLAB®代码使用coder.ceval.考虑MATLAB函数,mathOps

函数[added, multed] = mathOps(in1, in2)乘= in1 * in2;结束

对于本例,假设您希望通过使用外部C代码实现添加操作。考虑C函数,加法器,在文件中实现adder.c

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

集成加法器在MATLAB代码中,需要一个包含函数原型的头文件。看到这个文件adder.h

双加法器(双入1,双入2);

使用coder.ceval命令调用C函数mathOpsIntegrated.m.使用coder.cinclude

函数[added, multed] = mathOpsIntegrated(in1, in2)% # codegen%用于代码生成,预初始化输出变量%数据类型、大小和复杂性添加= 0;%在C代码中生成includecoder.cinclude (“adder.h”);%计算C函数的值添加= coder.ceval (“毒蛇”三机一体,in2);乘= in1 * in2;结束

要生成代码,请使用codegen命令。指定源文件adder.c作为输入。要测试C代码,执行MEX函数并检查输出结果。

codegenmathOpsIntegratedarg游戏{1,2}adder.c[test1, test2] = mathOpsIntegrated_mex(10,20)
代码生成成功。Test1 = 30, test2 = 200

从C函数返回多个值

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

例如,假设您编写一个MATLAB函数喷火这需要两个输入xy并返回三个输出一个b,c.在MATLAB中,你可以这样调用这个函数:

[a, b, c] = foo (x, y)

如果你改写喷火作为C函数,您不能返回三个单独的值一个b,c通过一个返回声明。相反,创建一个带有多个指针类型参数的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.rrefcoder.wref命令指示代码生成器将指针传递到数组,而不是复制它们。

函数out = adderRef(in1, in2)% # codegen= 0(大小(in));%输入的数字(in1)被转换为整数类型%匹配cAdd函数签名coder.ceval (“cAdd”, code .rref(in1), code .rref(in2), code .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;codegenadderRefarg游戏{A、B}cAdd.ccAdd.h报告如果(adderRef_mex(A,B) - (A+B) == 0) fprintf([' \ n '“adderRef成功了。”]);结束
代码生成成功:要查看报告,打开('codegen/mex/adderRef/html/report.mldatx')。adderRef是成功的。

集成使用自定义数据类型的外部代码

这个例子展示了如何调用一个C函数,该函数使用的数据类型不是在MATLAB®中本地定义的。

例如,如果你的C代码在C ' file *'类型上执行文件输入或输出,那么在MATLAB中就没有相应的类型。要在MATLAB代码中与此数据类型交互,必须使用函数初始化它coder.opaque.在结构类型的情况下,可以使用coder.cstructname

例如,考虑MATLAB函数addCTypes.m.这个函数使用coder.ceval在外部代码中定义输入类型。这个函数coder.opaque在MATLAB中初始化类型。

函数[出]= addCTypes (a, b)% # codegen%生成头文件的include语句coder.cinclude (“MyStruct.h”);coder.cinclude (“createStruct.h”);coder.cinclude (“useStruct.h”);%在使用变量之前初始化变量在= coder.opaque (“MyStruct”);= 0;%调用C函数在= coder.ceval (“createStruct”, a, b);= coder.ceval (“useStruct”,);结束

createStruct函数输出一个C结构类型:

#include  #include  #include "MyStruct.h" #include "createStruct " struct MyStruct createStruct(double a, double b) {struct MyStruct out;出去了。p1 =一个;出去了。p2 = b;返回;}

useStruct函数对C类型执行操作:

#include "MyStruct.h" #include "useStruct.h" double useStruct(struct MyStruct in) {return in。p1 + in.p2;}

要生成代码,指定源文件(.c)作为输入:

codegenaddCTypesarg游戏{1,2}报告createStruct.cuseStruct.c
代码生成成功:要查看报告,打开('codegen/mex/addCTypes/html/report.mldatx')。

集成使用指针、结构和数组的外部代码

这个例子展示了如何将操作C风格数组的外部代码与MATLAB®代码集成。外部代码计算数组数据的总和。您可以自定义代码以更改输入数据或计算。

这个示例展示了如何组合外部代码集成功能的多个不同元素。例如,您:

  • 使用coder.cstructname

  • 使用coder.opaque

  • 使用coder.ceval

  • 通过使用引用将数据传递给外部代码coder.ref

探索集成代码

extSum函数使用外部C代码对32位整数数组进行求和操作。数组大小由用户输入控制。

函数x = extSum (u)% # codegen设置使用静态内存分配的输入类型的边界u = int32 (u);断言(0 < u && u < 101);初始化数组temparray = int32 (1): u;%声明一个外部结构并使用它s = makeStruct (u);x = callExtCode(s, temparray);

为了简化生成的代码,可以设置数组的大小限制。边界阻止在生成的代码中使用动态内存分配。

这个函数makeStruct使用。声明MATLAB结构类型,并将其中一个字段初始化为指针类型coder.opaque.属性提供的头文件中包含与此定义相对应的C结构HeaderFile参数coder.cstructname函数。C结构类型为整数数组提供了一种简单的表示。

函数s = makeStruct (u)基于外部头文件定义创建结构类型s.numel = u;s.vals = coder.opaque (“int32_T *”“零”);coder.cstructname(年代,“myArrayType”“外来的”“HeaderFile”“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”coder.ref (s));coder.ceval (“arrayDest”coder.ref (s));

这个函数使用coder.updateBuildInfo将.c文件提供给代码生成器。

生成MEX函数

要生成一个可以在MATLAB中运行和测试的MEX函数,输入:

codegenextSumarg游戏{10}
代码生成成功。

测试MEX函数。输入:

extSum_mex (10)
55 .答案为a

外部C代码,包含在文件中arrayCode.carrayCode.h,使用自定义类型定义int32_T.生成的MEX代码生成并使用这个自定义类型定义。如果您想生成使用此自定义数据类型的独立(lib、dll或exe)代码,则可以修改DataTypeReplacement属性。看到将MATLAB类型映射到生成代码中的类型

另请参阅

||||||||

相关的话题