2013-02-10 74 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