Main Content

coder.opaque

在生成的代码中声明变量

说明

y = coder.opaque(type) 在生成的代码中使用指定的类型声明变量 y 且不设置初始值。

  • y 可以是变量或结构体字段。

  • MATLAB® 代码不能设置或访问 y,但外部 C 函数可以接受 y 作为参量。

  • y 可以是:

    • coder.rrefcoder.wrefcoder.ref 的参量

    • coder.ceval 的输入或输出参量

    • 用户编写的 MATLAB 函数的输入或输出参量

    • 支持代码生成的 MATLAB 部分工具箱函数的输入

  • 来自 y 的赋值在生成的代码中使用相同的类型声明另一个变量。例如:

    y = coder.opaque('int');
    z = y;
    在生成的代码中声明类型为 int 的变量 z

  • 您可以基于使用 coder.opaque 声明的另一个变量对 y 赋值,或基于使用 coder.opaque 声明的变量进行赋值。变量必须具有相同的类型。

  • 您可以将 y 与使用 coder.opaque 声明的另一个变量进行比较,或与基于使用 coder.opaque 声明的变量赋值进行比较。变量必须具有相同的类型。

示例

y = coder.opaque(type,value) 指定 y 的类型和初始值。

示例

y = coder.opaque(___,'Size',Size) 指定 y 的大小(以字节为单位)。您可以使用上述任何语法指定大小。

示例

y = coder.opaque(___,'HeaderFile',HeaderFile) 指定包含类型定义的头文件。代码生成器为生成的代码中需要 #include 语句的头文件生成该语句。您可以使用上述任何语法指定头文件。

示例

全部折叠

为函数 valtest 生成代码,如果调用 myfun 成功,该函数将返回 1。此函数使用 coder.opaque 声明变量 x1,该变量具有类型 int 和初始值 0。赋值 x2 = x1x2 声明为具有 x1 的类型和初始值的变量。

编写函数 valtest

function y = valtest
%codegen
%declare x1 to be an integer with initial value '0'
x1 = coder.opaque('int','0');
%Declare x2 to have same type and initial value as x1 
x2 = x1;
x2 = coder.ceval('myfun');
%test the result of call to 'myfun' by comparing to value of x1
if x2 == x1
  y = 0;
else
  y = 1;
end
end

为 MATLAB 函数 filetest 生成代码,该函数使用 fopen/fread/fclose 返回它自己的源代码。此函数使用 coder.opaque 声明存储 fopen/fread/fclose 使用的文件指针的变量。对 coder.opaque 的调用使用类型 FILE *、初始值 NULL 和头文件 <stdio.h> 声明变量 f

编写 MATLAB 函数 filetest

function buffer = filetest 
%#codegen

% Declare 'f' as an opaque type 'FILE *' with initial value 'NULL"
%Specify the header file that contains the type definition of 'FILE *';

f = coder.opaque('FILE *', 'NULL','HeaderFile','<stdio.h>');
% Open file in binary mode
f = coder.ceval('fopen', cstring('filetest.m'), cstring('rb'));

% Read from file until end of file is reached and put
% contents into buffer
n = int32(1);
i = int32(1);
buffer = char(zeros(1,8192));
while n > 0
    % By default, MATLAB converts constant values
    % to doubles in generated code
    % so explicit type conversion to int32 is inserted.
    n = coder.ceval('fread', coder.ref(buffer(i)), int32(1), ...
        int32(numel(buffer)), f);
    i = i + n;
end
coder.ceval('fclose',f);

buffer = strip_cr(buffer);

% Put a C termination character '\0' at the end of MATLAB character vector
function y = cstring(x)
    y = [x char(0)];

% Remove all character 13 (CR) but keep character 10 (LF)
function buffer = strip_cr(buffer)
j = 1;
for i = 1:numel(buffer)
    if buffer(i) ~= char(13)
        buffer(j) = buffer(i);
        j = j + 1;
    end
end
buffer(i) = 0;

比较使用 coder.opaque 声明的变量来测试是否成功打开文件。

使用 coder.opaque 声明变量 null,该变量具有类型 FILE * 和初始值 NULL

null = coder.opaque('FILE *', 'NULL', 'HeaderFile', '<stdio.h>');

使用赋值声明与 null 具有相同的类型和值的另一个变量 ftmp

ftmp = null;
ftmp = coder.ceval('fopen', ['testfile.txt', char(0)], ['r', char(0)]);

对这两个变量进行比较。

if ftmp == null
		%error condition
end

此示例说明如何对使用 coder.opaque 声明的变量进行类型转换。函数 castopaque 调用 C 运行时函数 strncmp 以对字符串 s1s2 中的最多 n 个字符进行比较。n 是较短字符串中的字符数。为了对 strncmp 输入 nsizet 生成正确的 C 类型,函数将 n 转换为 C 类型 size_t,并将结果赋值给 nsizet。该函数使用 coder.opaque 声明 nsizet。在使用 strncmp 的输出 retval 之前,函数将 retval 转换为 MATLAB 类型 int32,并将结果存储在 y 中。

编写此 MATLAB 函数:

function y = castopaque(s1,s2)

%  <0 - the first character that does not match has a lower value in s1 than in s2
%   0 - the contents of both strings are equal
%  >0 - the first character that does not match has a greater value in s1 than in s2
%
%#codegen

coder.cinclude('<string.h>');
n = min(numel(s1), numel(s2));

% Convert the number of characters to compare to a size_t

nsizet = cast(n,'like',coder.opaque('size_t','0'));

% The return value is an int
retval = coder.opaque('int');
retval = coder.ceval('strncmp', cstr(s1), cstr(s2), nsizet);

% Convert the opaque return value to a MATLAB value
y = cast(retval, 'int32');

%--------------
function sc = cstr(s)
% NULL terminate a MATLAB character vector for C
sc = [s, char(0)];

生成 MEX 函数。

codegen castopaque -args {blanks(3), blanks(3)} -report

使用输入 'abc''abc' 调用 MEX 函数。

castopaque_mex('abc','abc')
ans =

           0

由于两个字符串相等,因此输出为 0

使用输入 'abc''abd' 调用 MEX 函数。

castopaque_mex('abc','abd')
ans =

          -1

由于第二个字符串中的第三个字符 d 大于第一个字符串中的第三个字符 c,因此输出为 -1

使用输入 'abd''abc' 调用 MEX 函数。

castopaque_mex('abd','abc')
ans =

           1

由于第一个字符串中的第三个字符 d 大于第二个字符串中的第三个字符 c,因此输出为 1

在 MATLAB 工作区中,您可以看到 y 的类型为 int32

y 声明为初始值等于 0 的 4 个字节的整数。

y = coder.opaque('int','0', 'Size', 4);

输入参数

全部折叠

生成的代码中变量的类型。type 必须为编译时常量。类型必须是:

  • 内置的 C 数据类型或头文件中定义的类型

  • 支持通过赋值进行复制的 C 类型

  • C 声明中的合法前缀

示例: 'FILE *'

生成的代码中变量的初始值。value 必须为编译时常量。指定一个不依赖于 MATLAB 变量或函数的 C 表达式。

如果您在 value 中未提供初始值,请在使用之前先初始化变量的值。要初始化使用 coder.opaque 声明的变量,请执行以下操作:

  • 基于具有使用 coder.opaque 声明的相同类型的另一个变量进行赋值,或基于使用 coder.opaque 声明的变量进行赋值。

  • 基于外部 C 函数赋值。

  • 使用 coder.wref 将变量的地址传递给外部函数。

指定具有 type 指定的类型的 value。否则,生成的代码可能产生意外的结果。

示例: 'NULL'

生成的代码中的变量的字节数,指定为整数。如果不指定大小,则变量的大小为 8 个字节。

数据类型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

包含 type 的定义的头文件名称。HeaderFile 必须为编译时常量。

对于系统头文件,使用尖括号。

示例: '<stdio.h>' 生成 #include <stdio.h>

对于应用程序头文件,使用双引号。

示例: '"foo.h"' 生成 #include "foo.h"

如果您省略尖括号或双引号,代码生成器会生成双引号。

示例: 'foo.h' 生成 #include "foo.h"

在编译配置参数中指定包含路径。

示例: cfg.CustomInclude = 'c:\myincludes'

提示

  • 指定具有 type 指定的类型的 value。否则,生成的代码可能产生意外的结果。例如,以下 coder.opaque 声明可能产生意外的结果。

    y = coder.opaque('int', '0.2')

  • coder.opaque 声明变量的类型。它不实例化变量。稍后,您可以通过在 MATLAB 代码中使用变量来对其进行实例化。在下面的示例中,来自 coder.cevalfp1 的赋值对 fp1 进行实例化。

    % Declare fp1 of type FILE *
    fp1 = coder.opaque('FILE *');
    %Create the variable fp1
    fp1 = coder.ceval('fopen', ['testfile.txt', char(0)], ['r', char(0)]);

  • 在 MATLAB 环境中,coder.opaque 返回在 value 中指定的值。如果未提供 value,它将返回空字符向量。

  • 您可以对使用 coder.opaque 声明的变量或基于使用 coder.opaque 声明的变量赋值进行比较。变量必须具有相同的类型。以下示例说明如何对这些变量进行比较。比较使用 coder.opaque 声明的变量

  • 要避免在生成的代码中多次包含相同的头文件,请将头文件括入条件预处理器语句 #ifndef#endif 中。例如:

    #ifndef MyHeader_h
    #define MyHeader_h
    <body of header file>
    #endif
  • 您可以使用 MATLAB cast 函数对使用 coder.opaque 声明的变量进行类型转换。请仅针对数值类型将 castcoder.opaque 结合使用。

    要将 coder.opaque 声明的变量转换为 MATLAB 类型,您可以使用 B = cast(A,type) 语法。例如:

    x = coder.opaque('size_t','0');
    x1 = cast(x, 'int32');

    也可以使用 B = cast(A,'like',p) 语法。例如:

    x = coder.opaque('size_t','0');
    x1 = cast(x, 'like', int32(0));

    要将 MATLAB 变量转换为 coder.opaque 声明的变量的类型,您必须使用 B = cast(A,'like',p) 语法。例如:

    x = int32(12);
    x1 = coder.opaque('size_t', '0');
    x2 = cast(x, 'like', x1));

    castcoder.opaque 结合使用来为以下项生成正确的数据类型:

    • 使用 coder.ceval 调用的 C/C++ 函数的输入。

    • 您对使用 coder.ceval 调用的 C/C++ 函数的输出赋予的变量。

    如果没有这种类型转换,在代码生成过程中可能出现编译器警告。

扩展功能

C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。

GPU 代码生成
使用 GPU Coder™ 为 NVIDIA® GPU 生成 CUDA® 代码。

版本历史记录

在 R2011a 中推出