I have an enum like this:
classdef(Enumeration) bla_type < int32
enumeration
bla_one(1)
bla_2(2)
end
end
I can get the 'string representation of an element' like this:
char(bla_type.bla_one)
=>
bla_one
Unfortunately, matlab coder does not like this. Are there any alternatives?
There's no elegant built-in way in Coder to do this; the enumerated type becomes a standard enum in C, and the enumeration
function in MATLAB is unavailable in Coder. The simplest, but unpleasant, way to do it is to create a function with a switch statement with the manually populated string names. It's not nice, since now you have to maintain the names in two places.
However, one way that does work nicely is to use one of the more powerful features of Coder: coder.const.
The solution is to have a function that creates a table of the enumeration members and their values. This function itself cannot be compiled, but rather is called during compilation to build a lookup table in the resulting C code. We can use this lookup table in a Coder compatible function to get the data.
Imagine we have an enumerated type like this (in someenum.m):
classdef someenum < int32 %#codegen
enumeration
First_thing (0)
Second_thing (2)
Another_thing (3)
No_thing (4000)
end
end
We also then have the build-time function called 'buildsomeenum2name.m':
function [namearray, memberidx] = buildsomeenum2name
%BUILDSOMEENUM2NAME Compile-time creation of lookup table for someenum
% THIS FUNCTION IS NOT CODER COMPATIBLE, BUT IS CALLED DURING COMPILE
% TO CREATE A LOOKUP TABLE.
[members, names]=enumeration('someenum');
maxlen = 0;
for i=1:numel(names)
maxlen = max(maxlen, numel(names{i}));
end
namearray = char(zeros(numel(names), maxlen));
for i=1:numel(names)
namearray(i, 1:numel(names{i})) = names{i};
end
memberidx = int32(members); %#ok<NASGU>
end
When buildsomeenum2name
is called in MATLAB, it creates an array of string names of all the members of the enumerated type and another vector list of their numeric values in the same order.
Here's the cool part. MATLAB Coder can evaluate functions at build time and turn them into constants. These constants become literals in the resulting C code, rather than actual code. Since the functions are evaluated at build time, the enumeration information is put into a nice table, therefore if we make a Coder-compatible lookup function, we can use it to convert the member types into a string. We'll call this function 'someenum2name.m':
function name = someenum2name(enum) %#codegen
%SOMEENUM2NAME Get the string name of an enumerated type
% The following line loads namearray and memberidx with constant arrays
coder.extrinsic('buildsomeenum2name');
[namearray, memberidx] = coder.const(@buildsomeenum2name);
% First find the index of the enumerated type in the memberidx vector
index = find(memberidx==int32(enum));
if isempty(index)
name = 'UNKNOWN';
return;
end
name = deblank(namearray(index,:));
end
This function uses the coder.const
command to evaluate buildsomeenum2name
at compile time and create the lookup tables. We have to instruct Coder not to try to compile buildsomeenum2name
, so use the coder.extrinsic
command to tell it to ignore the function. Then someenum2name
can look up the index for the string and pull it out (deblank is used because the strings in the array have trailing 0's that need to be pulled out.) The function someenum2name
can be called both within MATLAB and in Coder compiled code.
This method keeps everything in-sync, so if you ever add a new member to the enum or rearrange them, the coder.const function will make sure that the values are rebuilt in the output code so that someenum2name works.
At the command line, this looks like:
>> someenum2name(someenum.No_thing)
ans =
No_thing
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With