2013-02-10 37 views
7

我有一个这样的枚举:GET串 - MATLAB编码器

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

我能得到这样的 '元素的字符串表示':

char(bla_type.bla_one) 

=>

bla_one 

不幸的是,matlab编码器不喜欢这个。有没有其他的选择?

+0

你绝对需要它从INT32继承?否则,你可以添加一个名称的属性(这是丑陋的,是的,但可能工作)。 – gzm0 2013-03-29 21:52:14

回答

0

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

2

编码器没有优雅的内置方式来做到这一点;枚举类型成为C中的标准枚举,并且MATLAB中的enumeration函数在编码器中不可用。最简单但不愉快的方法是使用带有手动填充的字符串名称的switch语句创建一个函数。这不好,因为现在你必须在两个地方保留名字。

但是,一种很好的工作方式是使用Coder的更强大功能之一:coder.const。

解决方法是创建一个枚举成员及其值的表。这个函数本身不能被编译,而是在编译过程中被调用来在生成的C代码中构建一个查找表。我们可以在编码器兼容的函数中使用这个查找表来获取数据。

假设我们有一个枚举类型这样的(在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编码器可以在构建时评估函数并将它们转换为常量。这些常量在生成的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在编译时和创建查找表。我们必须指示编码器不要试图编译buildsomeenum2name,所以使用coder.extrinsic命令告诉它忽略该函数。然后someenum2name可以查找字符串的索引并将其拉出(使用deblank是因为数组中的字符串具有尾随0,需要拔出)。功能someenum2name可以在MATLAB和编码器编译代码中调用。

此方法使所有内容保持同步,因此如果您向枚举中添加新成员或重新排列它们,编码器。const函数将确保在输出代码中重建值,以便someenum2name起作用。

在命令行中,这看起来像:

>> someenum2name(someenum.No_thing) 
ans = 
No_thing