Is it possible to access struct fields dynamically in generated code?

55 views (last 30 days)
Nikita Balyschew
Nikita Balyschew on 21 Feb 2020
Commented: PatrizioGraziosi on 30 Sep 2020
Hello all,
I would like to know if it is possible to access struct fields dynamically in generated code as stated in the title. For that I provide a minimum example. In my case I need to load a JSON file which is translated to a structure and I don't know the fields in advance.
%% structure.json
{
"a": 0,
"bb": 0.1,
"ccc": [],
"dddd": {},
"eeeee": "abc",
"ffffff": 'abc',
"a1": 0,
"b2": 0.1,
"c3": [],
"d4": {},
"e5": "abc",
"f6": 'abc'
}
%% main.m
structure = struct;
structure.a = 0;
structure.bb = 0.1;
structure.ccc = [];
structure.dddd = {};
structure.eeeee = 'abc';
structure.ffffff = "abc";
prototype(structure);
prototype("structure.json");
%% prototype.m
function prototype(structure)
if isstruct(structure)
field_names = fieldnames(structure);
disp("field names count: " + length(field_names));
for i = 1:length(field_names)
disp("field name " + i + ": " + field_names{i});
end
disp("content of field name a: " + structure.a);
for i = 1:length(field_names)
if ~iscell(structure.(field_names{i})) && ~isnumeric(structure.(field_names{i}))
disp("dynamic access to content of field name " + field_names{i} + ": " + structure.(field_names{i}));
end
end
elseif ischar(structure) || isstring(structure)
json_file = fileread(structure);
json_content = jsondecode(json_file);
end
end
%% compile.m
structure = struct;
structure.a = 0;
structure.bb = 0.1;
structure.ccc = [];
structure.dddd = {};
structure.eeeee = 'abc';
structure.ffffff = "abc";
structure.a1 = 0;
structure.b2 = 0.1;
structure.c3 = [];
structure.d4 = {};
structure.e5 = 'abc';
structure.f6 = "abc";
cfg = coder.config('lib');
codegen -report -config cfg prototype...
-args structure...
-O disable:inline
cfg = coder.config('exe');
codegen -report -config cfg -args structure prototype codegen/lib/prototype/examples/main.c codegen/lib/prototype/examples/main.h
Many thanks in advance,
Nikita

Answers (1)

Denis Gurchenkov
Denis Gurchenkov on 21 Feb 2020
The the specific question you are asking ("is possible to access struct fields dynamically in generated code"), the answer is "no". Where is why:
MATLAB Coder aims to translate MATLAB into statically typed C/C++ code, similar to what a human would write. To that extent, it translates MATLAB structures into C/C++ structs. In C and C++, the list of fields in a struct, each use of a field must be statically resolved.
So, whenever codegen sees "var.(field)", it wants to find out the value of the variable "field" at compile time. If it could not do so, it produces an error. Also, it wants to know, at compile time, what is the full list of fields in a struct.
If you elaborate on your intent (what you want to achieve, why you'd want to generate C/C++ code using MATLAB Coder and parse Json there) someone could suggest an alternative solution.
For instance, if you know the full list of fields ahead of time, and all the fields have same types, you could write something akin to
function out = dynFieldAccess(var, fieldname)
if strcmp(fieldname, 'a')
out = var.a;
else if strcmp(fieldname, 'b')
out = var.b;
else..
and so on.
Or maybe you'd be better off hand-writing the C/C++ code for this part of your application.
  5 Comments
PatrizioGraziosi
PatrizioGraziosi on 30 Sep 2020
Hi Ryan,
thank you!
the idea is to share the application in C, already finished, and the users enter the inputs and run the code.
At present, the inputs are in "free form", the user enters what is needed and the application checks them.
But if I understand, in order to share the application already in C, I should re-shape it to have pre-defined fields, is this correct?
Thanks
Patrizio

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by