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

51 views (last 30 days)
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
  1 Comment
Joris Brouwer
Joris Brouwer on 27 Mar 2023
I just ran into the same boundary conditions. I have a JSON input in Matlab which works perfectly with dynamic fields. Now converting to C-code I need predefined fieldnames. Since my problem is not so big (and I knew very well this was a limitation before I started but I still had a go since each version coder is improved) I'll go for the hardcoded fieldnames. Just a tit bit more coding to do.
My preferred solutions would be jsondecode (and jsonencode) to be made an extended capability C/C++ code generation. But I understand that may be though one not getting the highest priority by the development team.

Sign in to comment.

Accepted Answer

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
Ryan Livingston
Ryan Livingston on 29 Sep 2020
The concept that Denis describes above also holds here. When MATLAB Coder analyzes your code, it needs to be able to determine the full set of fields present in your struct during code generation. In the generated code, do you envision that your users would need to provide input to specify these pairs? Or could the user provide the input prior to code generation?
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.

More Answers (0)

Categories

Find more on MATLAB Coder in Help Center and File Exchange

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!