Using custom C structures with MATLAB coder

3 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
Maksims Abalenkovs
Maksims Abalenkovs on 26 Feb 2021
It works! Thank you very much. Can you please explain the reason for renaming the original C files from `vector.*` to `myvector.*` and placing them into a separate directory `mycfiles`?
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!