Documentation

coder.opaque

Declare variable in generated code

Syntax

  • y = coder.opaque(type)
  • y = coder.opaque(type,value) example
  • y = coder.opaque(type,'HeaderFile',HeaderFile)
  • y = coder.opaque(type,value,'HeaderFile',HeaderFile) example

Description

y = coder.opaque(type) declares a variable y with the specified type and no initial value in the generated code.

  • y can be a variable or a structure field.

  • MATLAB® code cannot set or access y, but external C functions can accept y as an argument.

  • y can be an:

    • Argument to coder.rref, coder.wref, or coder.ref

    • Input or output argument to coder.ceval

    • Input or output argument to a user-written MATLAB function

    • Input to a subset of MATLAB toolbox functions supported for code generation

  • Assignment from y declares another variable with the same type in the generated code. For example:

    y = coder.opaque('int');
    z = y;
    declares a variable z of type int in the generated code.

  • You can assign y from another variable declared using either coder.opaque or assignment from a variable declared using coder.opaque. The variables must have identical types.

  • You can compare y to another variable declared using either coder.opaque or assignment from a variable declared using coder.opaque. The variables must have identical types.

example

y = coder.opaque(type,value) declares a variable y and specifies the initial value of y in the generated code.

y = coder.opaque(type,'HeaderFile',HeaderFile) declares a variable y and specifies the header file that contains the definition of type. The code generation software generates the #include statement for the header file where required in the generated code.

example

y = coder.opaque(type,value,'HeaderFile',HeaderFile) declares a variable y with the specified type, initial value, and header file in the generated code.

Examples

collapse all

Declare Variable Specifying Initial Value

Generate code for a function valtest which returns 1 if the call to myfun is successful. This function uses coder.opaque to declare a variable x1 with type int and initial value 0. The assignment x2 = x1 declares x2 to be a variable with the type and initial value of x1 .

Write a function 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 intial 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

Create a code generation configuration object for a static library.

cfg = coder.config('lib');

Generate a static library for valtest.

codegen -report -config cfg valtest

codegen generates C code in the codegen\lib\valtest folder.

Declare Variable Specifying Initial Value and Header File

Generate code for a MATLAB function filetest which returns its own source code using fopen/fread/fclose. This function uses coder.opaque to declare the variable that stores the file pointer used by fopen/fread/fclose. The call to coder.opaque declares the variable f with type FILE *, initial value NULL, and header file <stdio.h>.

Write a MATLAB function filetest.

function buffer = filetest 
%#codegen

% Declare 'f' as an opaque type 'FILE *' with intial 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 string
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;

Create a code generation configuration object for a static library.

cfg = coder.config('lib');

Generate a static library for filetest.

codegen -report -config cfg filetest

codegen generates C code in the codegen\lib\filetest folder.

Compare Variables Declared Using coder.opaque

Compare variables declared using coder.opaque to test for successfully opening a file.

Use coder.opaque to declare a variable null with type FILE * and initial value NULL.

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

Use assignment to declare another variable ftmp with the same type and value as null.

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

Compare the variables.

if ftmp == null
		%error condition
end

Cast to and from Types of Variables Declared Using coder.opaque

This example shows how to cast to and from types of variables that are declared using coder.opaque. The function castopaque calls the C run-time function strncmp to compare at most n characters of the strings s1 and s2. n is the number of characters in the shorter of the strings. To generate the correct C type for the strncmp input nsizet, the function casts n to the C type size_t and assigns the result to nsizet. The function uses coder.opaque to declare nsizet. Before using the output retval from strncmp, the function casts retval to the MATLAB type int32 and stores the results in y.

Write this MATLAB function:

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 string for C
sc = [s, char(0)];

Generate the MEX function.

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

Call the MEX function with inputs 'abc' and 'abc'.

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

           0

The output is 0 because the strings are equal.

Call the MEX function with inputs 'abc' and 'abd'.

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

          -1

The output is -1 because the third character d in the second string is greater than the third character c in the first string.

Call the MEX function with inputs 'abd' and 'abc'.

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

           1

The output is 1 because the third character d in the first string is greater than the third character c in the second string.

In the MATLAB workspace, you can see that the type of y is int32.

Input Arguments

collapse all

type — Type of variablestring

Type of variable in generated code specified as a string constant. The type must be a:

  • Built-in C data type or a type defined in a header file

  • C type that supports copy by assignment

  • Legal prefix in a C declaration

Example: 'FILE *'

Data Types: char

value — Initial value of variablestring

Initial value of variable in generated code specified as a string constant. Specify a C expression not dependent on MATLAB variables or functions.

If you do not provide the initial value in value, initialize the value of the variable prior to using it. To initialize a variable declared using coder.opaque:

  • Assign a value from another variable with the same type declared using either coder.opaque or assignment from a variable declared using coder.opaque.

  • Assign a value from an external C function.

  • Pass the variable's address to an external function using coder.wref.

Example: 'NULL'

Data Types: char

HeaderFile — Name of header filestring

Name of header file, specified as a string constant, that contains the definition of type.

For a system header file, use angle brackets.

Example: '<stdio.h>' generates #include <stdio.h>

For an application header file, use double quotes.

Example: '"foo.h"' generates #include "foo.h"

If you omit the angle brackets or double quotes, the code generation software generates double quotes.

Example: 'foo.h' generates #include "foo.h"

Specify the include path in the build configuration parameters.

Example: cfg.CustomInclude = 'c:\myincludes'

Data Types: char

More About

collapse all

Tips

  • coder.opaque declares the type of a variable. It does not instantiate the variable. You can instantiate a variable by using it later in the MATLAB code. In the following example, assignment of fp1 from coder.ceval instantiates 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)]);

  • In the MATLAB environment, coder.opaque returns the value specified in value. If value is not provided, it returns the empty string.

  • You can compare variables declared using either coder.opaque or assignment from a variable declared using coder.opaque. The variables must have identical types. The following example demonstrates how to compare these variables. Compare Variables Declared Using coder.opaque

  • To avoid multiple inclusions of the same header file in generated code, enclose the header file in the conditional preprocessor statements #ifndef and #endif. For example:

    #ifndef MyHeader_h
    #define MyHeader_h
    <body of header file>
    #endif
  • You can use the MATLAB cast function to cast a variable to or from a variable that is declared using coder.opaque. Use cast with coder.opaque only for numeric types.

    To cast a variable declared by coder.opaque to a MATLAB type, you can use the B = cast(A,type) syntax. For example:

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

    You can also use the B = cast(A,'like',p) syntax. For example:

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

    To cast a MATLAB variable to the type of a variable declared by coder.opaque, you must use the B = cast(A,'like',p) syntax. For example:

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

    Use cast with coder.opaque to generate the correct data types for:

    • Inputs to C/C++ functions that you call using coder.ceval.

    • Variables that you assign to outputs from C/C++ functions that you call using coder.ceval.

    Without this casting, it is possible to receive compiler warnings during code generation.

Was this topic helpful?