我有一个这样的枚举:
classdef(Enumeration) bla_type < int32
enumeration
bla_one(1)
bla_2(2)
end
end
我可以像这样得到“元素的字符串表示”:
char(bla_type.bla_one)
=>
bla_one
不幸的是,matlab 编码器不喜欢这样。有没有其他选择?
我有一个这样的枚举:
classdef(Enumeration) bla_type < int32
enumeration
bla_one(1)
bla_2(2)
end
end
我可以像这样得到“元素的字符串表示”:
char(bla_type.bla_one)
=>
bla_one
不幸的是,matlab 编码器不喜欢这样。有没有其他选择?
Coder 中没有优雅的内置方法可以做到这一点。枚举类型成为 C 中的标准枚举,而enumeration
MATLAB 中的函数在 Coder 中不可用。最简单但令人不快的方法是使用手动填充的字符串名称创建一个带有 switch 语句的函数。这不好,因为现在您必须在两个地方维护名称。
但是,一种效果很好的方法是使用 Coder 更强大的功能之一:coder.const。
解决方案是创建一个包含枚举成员及其值的表的函数。此函数本身无法编译,而是在编译期间调用以在生成的 C 代码中构建查找表。我们可以在 Coder 兼容函数中使用这个查找表来获取数据。
想象一下,我们有一个像这样的枚举类型(在 someenum.m 中):
classdef someenum < int32 %#codegen
enumeration
First_thing (0)
Second_thing (2)
Another_thing (3)
No_thing (4000)
end
end
然后我们还有一个名为“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
在buildsomeenum2name
MATLAB 中调用时,它会创建一个包含枚举类型所有成员的字符串名称的数组,以及另一个按相同顺序包含其数值的向量列表。
这是很酷的部分。MATLAB Coder 可以在构建时评估函数并将它们转换为常量。这些常量在生成的 C 代码中变成文字,而不是实际代码。由于函数是在构建时评估的,枚举信息被放入一个漂亮的表中,因此如果我们制作一个与 Coder 兼容的查找函数,我们可以使用它将成员类型转换为字符串。我们将此函数称为“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
此函数使用该coder.const
命令buildsomeenum2name
在编译时进行评估并创建查找表。我们必须指示 Coder 不要尝试编译buildsomeenum2name
,所以使用coder.extrinsic
命令告诉它忽略该函数。然后someenum2name
可以查找字符串的索引并将其拉出(使用 deblank 是因为数组中的字符串有尾随的 0 需要拉出。)该函数someenum2name
可以在 MATLAB 和 Coder 编译的代码中调用。
此方法使所有内容保持同步,因此如果您向枚举添加新成员或重新排列它们,则 coder.const 函数将确保在输出代码中重新构建这些值,以便 someenum2name 工作。
在命令行中,这看起来像:
>> someenum2name(someenum.No_thing)
ans =
No_thing
试试[~,s]=enumeration('bla_type')
。您会得到一个字符串元胞数组,其中包含s
. 所以bla_one
会在s{1}
。不知道 MATLAB 编码器是否支持这一点。