MATLAB Answers

Using custom C structures with MATLAB coder

2 views (last 30 days)
I need help initialising and using custom C structs in MATLAB. My goal is to write MATLAB code utilising external C structures and functions. The resulting MATLAB code with these C structures will be automatically converted into C by MATLAB Coder. I'm following this example (Please see the section entitled "Integrate External Code that Uses Custom Data Types"), but unfortunately the Coder gives me the following error:
Non-constant expression or empty matrix. This expression must be constant because its value
determines the size or class of some expression.
I believe my problem lies in the incorrect usage of coder.cstructname, struct and coder.opaque. To (auto)generate the C code with MATLAB Coder I use the following command:
codegen calc_length_c -args {0.1, 0.2, 0.3, 1.5, 1.7, 1.9} -report vector.c
MATLAB code, file calc_length_c.m:
function [l] = calc_length_c(p0x, p0y, p0z, p1x, p1y, p1z) %#coder
%CALC_LENGTH Calculates vector length
% Calculates vector length. Vector is given by two points in Cartesian 3D space.
% include statements
coder.cinclude('vector.h');
% declare custom C datatypes
coder.cstructname(p0, 'point', 'extern', 'HeaderFile', 'vector.h');
coder.cstructname(p1, 'point', 'extern', 'HeaderFile', 'vector.h');
coder.cstructname(v, 'vector', 'extern', 'HeaderFile', 'vector.h');
% initialise points
p0 = struct('x', 0.0, 'y', 0.0, 'z', 0.0);
p1 = struct('x', 0.0, 'y', 0.0, 'z', 0.0);
v = struct('p0', p0, 'p1', p1);
% initialise points
p0 = coder.ceval('create_point', p0x, p0y, p0z);
p1 = coder.ceval('create_point', p1x, p1y, p1z);
% initialise vector
v = coder.opaque('create_vector', p0, p1); % <- error occurs here!
% calculate vector length
l = 0.0;
l = coder.opaque('calc_length', v);
end
C code, file vector.c:
#include <math.h>
#include "vector.h"
// Creates point in 3D Cartesian space
struct point create_point(double x, double y, double z) {
struct point p;
p.x = x;
p.y = y;
p.z = z;
return p;
}
// Creates vector in 3D Cartesian space, defines origin and end points
struct vector create_vector(struct point p0, struct point p1) {
struct vector v;
v.p0 = p0;
v.p1 = p1;
return v;
}
// Calculates length of vector in 3D Cartesian space
double calc_length(struct vector v) {
return sqrt( pow(v.p1.x-v.p0.x, 2.0) +
pow(v.p1.y-v.p0.y, 2.0) +
pow(v.p1.z-v.p0.z, 2.0) );
}
C code, file vector.h:
// Definition of point in 3D Cartesian space
struct point {
double x;
double y;
double z;
};
// Definition of vector in 3D Cartesian space
struct vector {
struct point p0;
struct point p1;
};
// Routine signatures
struct point create_point(double x, double y, double z);
struct vector create_vector(struct point p0, struct point p1);
double calc_length(struct vector u);

Accepted Answer

Darshan Ramakant Bhat
Darshan Ramakant Bhat on 26 Feb 2021
You dont have to use code.cstructname() for your usecase.
I have modified your code and try to make it work. I have attached the modified code here. Please run doit.m file to generate code.
Hope this will help you.
  2 Comments
Darshan Ramakant Bhat
Darshan Ramakant Bhat on 27 Feb 2021
Putting all the custome source and header file inside a seperate folder is just a best practice. We need to add those folder using customInclude.
I renamed the files to avoid confusion with <vector> which contains definition for std::vector. But it should work without renaming as well :)

Sign in to comment.

More Answers (0)

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by