## 从生成的代码中调用自定义 C/C++ 代码

`coder.ceval` 只能在 MATLAB 代码中用于代码生成。在未编译的 MATLAB 代码中，`coder.ceval` 将生成错误。要确定 MATLAB 函数是否在 MATLAB 中执行，请使用 `coder.target`。如果函数在 MATLAB 中执行，请调用 MATLAB 版本的 C/C++ 函数。

### 调用 C 代码

```function [added, multed] = mathOps(in1, in2) added = in1+in2; multed = in1*in2; end ```

```#include <stdio.h> #include <stdlib.h> #include "adder.h" double adder(double in1, double in2) { return in1 + in2; } ```

```double adder(double in1, double in2); ```

```function [added, multed] = mathOpsIntegrated(in1, in2) %#codegen % for code generation, preinitialize the output variable % data type, size, and complexity added = 0; % generate an include in the C code coder.cinclude('adder.h'); % evaluate the C function added = coder.ceval('adder', in1, in2); multed = in1*in2; end ```

```codegen mathOpsIntegrated -args {1, 2} adder.c [test1, test2] = mathOpsIntegrated_mex(10, 20) ```
```Code generation successful. test1 = 30 test2 = 200 ```

### 从一个 C 函数返回多个值

C 语言限制函数返回多个输出。函数只能返回单个标量值。您可以使用 MATLAB 函数 `coder.ref``coder.rref``coder.wref` 从一个外部 C/C++ 函数返回多个输出。

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

`void foo(double x,double y,double *a,double *b,double *c)`

`coder.ceval('foo',x,y,coder.ref(a),coder.ref(b),coder.ref(c));`

### 按引用传递数据

```function out = adderRef(in1, in2) %#codegen out = zeros(size(in1)); % the input numel(in1) is converted to integer type % to match the cAdd function signature coder.ceval('cAdd', coder.rref(in1), coder.rref(in2), coder.wref(out), int32(numel(in1)) ); end ```

C 代码 `cAdd.c` 使用线性索引来访问数组的元素：

```#include <stdio.h> #include <stdlib.h> #include "cAdd.h" void cAdd(const double* in1, const double* in2, double* out, int numel) { int i; for (i=0; i<numel; i++) { out[i] = in1[i] + in2[i]; } } ```

```void cAdd(const double* in1, const double* in2, double* out, int numel); ```

```A = rand(2,2)+1; B = rand(2,2)+10; codegen adderRef -args {A, B} cAdd.c cAdd.h -report if (adderRef_mex(A,B) - (A+B) == 0) fprintf(['\n' 'adderRef was successful.']); end ```
```Code generation successful: To view the report, open('codegen/mex/adderRef/html/report.mldatx') adderRef was successful.```

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

```function [out] = addCTypes(a,b) %#codegen % generate include statements for header files coder.cinclude('MyStruct.h'); coder.cinclude('createStruct.h'); coder.cinclude('useStruct.h'); % initialize variables before use in = coder.opaque('MyStruct'); out = 0; % call C functions in = coder.ceval('createStruct',a,b); out = coder.ceval('useStruct',in); end ```

`createStruct` 函数输出 C 结构体类型：

```#include <stdio.h> #include <stdlib.h> #include "MyStruct.h" #include "createStruct.h" struct MyStruct createStruct(double a, double b) { struct MyStruct out; out.p1 = a; out.p2 = b; return out; } ```

`useStruct` 函数对该 C 类型执行操作：

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

```codegen addCTypes -args {1,2} -report createStruct.c useStruct.c ```
```Code generation successful: To view the report, open('codegen/mex/addCTypes/html/report.mldatx') ```

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

• 使用 `coder.cstructname` 对接外部结构体类型

• 使用 `coder.opaque` 对接外部指针类型

• 使用 `coder.ceval` 执行外部代码

• 使用 `coder.ref` 按引用将数据传递到外部代码

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

```function x = extSum(u) %#codegen % set bounds on input type to use static memory allocation u = int32(u); assert(0 < u && u < 101); % initialize an array temparray = int32(1):u; % declare an external structure and use it s = makeStruct(u); x = callExtCode(s, temparray); ```

```function s = makeStruct(u) % create structure type based on external header definition s.numel = u; s.vals = coder.opaque('int32_T *','NULL'); coder.cstructname(s,'myArrayType','extern','HeaderFile','arrayCode.h'); ```

```function x = callExtCode(s, temparray) % declare output type x = int32(0); % declare external source file coder.updateBuildInfo('addSourceFiles','arrayCode.c'); % call c code coder.ceval('arrayInit',coder.ref(s),coder.ref(temparray)); x = coder.ceval('arraySum',coder.ref(s)); coder.ceval('arrayDest',coder.ref(s)); ```

```codegen extSum -args {10} ```
```Code generation successful. ```

```extSum_mex(10) ```
```ans = int32 55 ```