Declare variable in generated code
y = coder.opaque(
declares
a variable type
)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;
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.
y = coder.opaque(___,'Size',
specifies
the size, in bytes, of Size
)y
. You can specify the size
with any of the previous syntaxes.
y = coder.opaque(___,'HeaderFile',
specifies
the header file that contains the type definition. The code generator
produces the HeaderFile
)#include
statement for the header
file where the statement is required in the generated code. You can
specify the header file with any of the previous syntaxes.
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 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
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 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
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
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 character vector 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
.
Declare y
to be a 4-byte integer with initial
value 0.
y = coder.opaque('int','0', 'Size', 4);
Specify a value
that has the
type that type
specifies. Otherwise, the generated
code can produce unexpected results. For example, the following coder.opaque
declaration
can produce unexpected results.
y = coder.opaque('int', '0.2')
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 an empty character vector.
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.