获取枚举类型的字符串 - MATLAB Coder

7

我有一个枚举类型,就像这样:

classdef(Enumeration) bla_type < int32
    enumeration
        bla_one(1)
        bla_2(2)
    end
end

我可以通过以下方式获取'元素的字符串表示':
char(bla_type.bla_one)

=>

bla_one

很遗憾,Matlab Coder 对此不太支持。有没有其他替代方案?

你是否一定需要从int32继承?否则,你可以添加一个带有名称的属性(这可能很丑陋,但可能有效)。 - gzm0
2个回答

2
在Coder中没有一种优雅的内置方法来实现这个功能;枚举类型在C中变成了标准的枚举,而MATLAB中的enumeration函数在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

当在MATLAB中调用buildsomeenum2name函数时,它将创建一个字符串数组,其中包含枚举类型的所有成员名称,并创建另一个向量列表,其中包含相同顺序的数值。
这里有个很酷的部分。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

1

尝试[~,s]=enumeration('bla_type')。您将获得一个字符串的单元数组,其中包含s中元素的名称。所以bla_one将在s {1}中。不知道MATLAB编码器是否支持此功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接