Main Content

Pass Structure Arguments by Reference or by Value in Generated Code

This example shows how to control whether structure arguments to generated entry-point functions are passed by reference or by value.

Passing by reference uses a pointer to access the structure arguments. If the function writes to an element of the input structure, it overwrites the input value. Passing by value makes a copy of the input or output structure argument. To reduce memory usage and execution time, use pass by reference.

If a structure argument is both an input and output, the generated entry-point function passes the argument by reference. Generated MEX functions pass structure arguments by reference. For MEX function output, you cannot specify that you want to pass structure arguments by value.

Specify Pass by Reference or by Value Using the MATLAB® Coder App

To open the Generate dialog box, on the Generate Code page, click the Generate arrow.

Set the Build type to one of the following:

  • Source Code

  • Static Library

  • Dynamic Library

  • Executable

Click More Settings.

On the All Settings tab, set the Pass structures by reference to entry-point functions option to:

  • Yes, for pass by reference (default)

  • No, for pass by value

Specify Pass by Reference or by Value Using the Command-Line Interface

Create a code configuration object for a static library, a dynamic library, or an executable program. For example, create a code configuration object for a static library.

cfg = coder.config('lib'); 

Set the PassStructByReference property to:

  • true, for pass by reference (default)

  • false, for pass by value

For example:

cfg.PassStructByReference = true;

Pass Input Structure Argument by Reference

Write the MATLAB function my_struct_in that has an input structure argument.

type my_struct_in.m
function y = my_struct_in(s)
%#codegen

y = s.f;

Define a structure variable mystruct in the MATLAB® workspace.

mystruct = struct('f', 1:4);

Create a code generation configuration object for a C static library.

cfg = coder.config('lib');

Specify that you want to pass structure arguments by reference.

cfg.PassStructByReference = true;

Generate code. Specify that the input argument has the type of the variable mystruct.

codegen -config cfg -args {mystruct} my_struct_in
Code generation successful.

View the generated C code.

type codegen/lib/my_struct_in/my_struct_in.c
/*
 * Prerelease License - for engineering feedback and testing purposes
 * only. Not for sale.
 * File: my_struct_in.c
 *
 * MATLAB Coder version            : 24.2
 * C/C++ source code generated on  : 20-Jul-2024 12:25:11
 */

/* Include Files */
#include "my_struct_in.h"
#include "my_struct_in_types.h"

/* Function Definitions */
/*
 * Arguments    : const struct0_T *s
 *                double y[4]
 * Return Type  : void
 */
void my_struct_in(const struct0_T *s, double y[4])
{
  y[0] = s->f[0];
  y[1] = s->f[1];
  y[2] = s->f[2];
  y[3] = s->f[3];
}

/*
 * File trailer for my_struct_in.c
 *
 * [EOF]
 */

The generated function signature for my_struct_in is

void my_struct_in(const struct0_T *s, double y[4])

my_struct_in passes the input structure s by reference.

Pass Input Structure Argument by Value

Specify that you want to pass structure arguments by value.

cfg.PassStructByReference = false;

Generate code. Specify that the input argument has the type of the variable mystruct.

codegen -config cfg -args {mystruct} my_struct_in
Code generation successful.

View the generated C code.

type codegen/lib/my_struct_in/my_struct_in.c
/*
 * Prerelease License - for engineering feedback and testing purposes
 * only. Not for sale.
 * File: my_struct_in.c
 *
 * MATLAB Coder version            : 24.2
 * C/C++ source code generated on  : 20-Jul-2024 12:25:13
 */

/* Include Files */
#include "my_struct_in.h"
#include "my_struct_in_types.h"

/* Function Definitions */
/*
 * Arguments    : const struct0_T s
 *                double y[4]
 * Return Type  : void
 */
void my_struct_in(const struct0_T s, double y[4])
{
  y[0] = s.f[0];
  y[1] = s.f[1];
  y[2] = s.f[2];
  y[3] = s.f[3];
}

/*
 * File trailer for my_struct_in.c
 *
 * [EOF]
 */

The generated function signature for my_struct_in is

void my_struct_in(const struct0_T s, double y[4]

my_struct_in passes the input structure s by value.

Pass Output Structure Argument by Reference

Write the MATLAB function my_struct_out that has an output structure argument.

type my_struct_out.m
function s = my_struct_out(x)
%#codegen

s.f = x;

Define a variable a in the MATLAB® workspace.

a = 1:4;

Create a code generation configuration object for a C static library.

cfg = coder.config('lib');

Specify that you want to pass structure arguments by reference.

cfg.PassStructByReference = true;

Generate code. Specify that the input argument has the type of the variable a.

codegen -config cfg -args {a} my_struct_out
Code generation successful.

View the generated C code.

type codegen/lib/my_struct_out/my_struct_out.c
/*
 * Prerelease License - for engineering feedback and testing purposes
 * only. Not for sale.
 * File: my_struct_out.c
 *
 * MATLAB Coder version            : 24.2
 * C/C++ source code generated on  : 20-Jul-2024 12:25:15
 */

/* Include Files */
#include "my_struct_out.h"
#include "my_struct_out_types.h"

/* Function Definitions */
/*
 * Arguments    : const double x[4]
 *                struct0_T *s
 * Return Type  : void
 */
void my_struct_out(const double x[4], struct0_T *s)
{
  s->f[0] = x[0];
  s->f[1] = x[1];
  s->f[2] = x[2];
  s->f[3] = x[3];
}

/*
 * File trailer for my_struct_out.c
 *
 * [EOF]
 */

The generated function signature for my_struct_out is

void my_struct_out(const double x[4], struct0_T *s)

my_struct_out passes the output structure s by reference.

Pass Output Structure Argument by Value

Specify that you want to pass structure arguments by value.

cfg.PassStructByReference = false;

Generate code. Specify that the input argument has the type of the variable a.

codegen -config cfg -args {a} my_struct_out
Code generation successful.

View the generated C code.

type codegen/lib/my_struct_out/my_struct_out.c
/*
 * Prerelease License - for engineering feedback and testing purposes
 * only. Not for sale.
 * File: my_struct_out.c
 *
 * MATLAB Coder version            : 24.2
 * C/C++ source code generated on  : 20-Jul-2024 12:25:18
 */

/* Include Files */
#include "my_struct_out.h"
#include "my_struct_out_types.h"

/* Function Definitions */
/*
 * Arguments    : const double x[4]
 * Return Type  : struct0_T
 */
struct0_T my_struct_out(const double x[4])
{
  struct0_T s;
  s.f[0] = x[0];
  s.f[1] = x[1];
  s.f[2] = x[2];
  s.f[3] = x[3];
  return s;
}

/*
 * File trailer for my_struct_out.c
 *
 * [EOF]
 */

The generated function signature for my_struct_out is

struct0_T my_struct_out(const double x[4])

my_struct_out returns an output structure.

Pass Input and Output Structure Argument by Reference

When an argument is both an input and an output, the generated C function passes the argument by reference even when PassStructByReference is false.

Write the MATLAB function my_struct_inout that has a structure argument that is both an input argument and an output argument.

type my_struct_inout.m
function [y,s] = my_struct_inout(x,s)
%#codegen

y = x + sum(s.f);

Define the variable a and structure variable mystruct in the MATLAB® workspace.

a = 1:4;
mystruct = struct('f',a);

Create a code generation configuration object for a C static library.

cfg = coder.config('lib');

Specify that you want to pass structure arguments by value.

cfg.PassStructByReference = false;

Generate code. Specify that the first input has the type of a and the second input has the type of mystruct.

codegen -config cfg -args {a, mystruct} my_struct_inout
Code generation successful.

View the generated C code.

type codegen/lib/my_struct_inout/my_struct_inout.c
/*
 * Prerelease License - for engineering feedback and testing purposes
 * only. Not for sale.
 * File: my_struct_inout.c
 *
 * MATLAB Coder version            : 24.2
 * C/C++ source code generated on  : 20-Jul-2024 12:25:21
 */

/* Include Files */
#include "my_struct_inout.h"
#include "my_struct_inout_types.h"
#include <emmintrin.h>

/* Function Definitions */
/*
 * Arguments    : const double x[4]
 *                const struct0_T *s
 *                double y[4]
 * Return Type  : void
 */
void my_struct_inout(const double x[4], const struct0_T *s, double y[4])
{
  __m128d r;
  r = _mm_set1_pd(((s->f[0] + s->f[1]) + s->f[2]) + s->f[3]);
  _mm_storeu_pd(&y[0], _mm_add_pd(_mm_loadu_pd(&x[0]), r));
  _mm_storeu_pd(&y[2], _mm_add_pd(_mm_loadu_pd(&x[2]), r));
}

/*
 * File trailer for my_struct_inout.c
 *
 * [EOF]
 */

The generated function signature for my_struct_inout is

void my_struct_inout(const double x[4], const struct0_T *s, double y[4])

my_struct_inout passes the structure s by reference even though PassStructByReference is false.

Related Topics