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

22 次查看(过去 30 天)
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 个评论
Joris Brouwer
Joris Brouwer 2023-3-27
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.

请先登录,再进行评论。

采纳的回答

Denis Gurchenkov
Denis Gurchenkov 2020-2-21
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 个评论
Ryan Livingston
Ryan Livingston 2020-9-29
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 2020-9-30
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

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 MATLAB Coder 的更多信息

产品


版本

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by