正如您所说,MATLAB 代码中不允许结构的动态字段名供 Coder 使用。我以前也遇到过和你很像的情况,我是这样处理的。
首先,我们可以列出一些在 Coder 中允许使用的好工具。我们可以有类(值或句柄),这非常方便。此外,如果我们使用coder.varsize 来专门指定它,我们就可以拥有可变大小的数据。如果我们愿意,我们也可以在 switch 语句中使用字符串值。但是,我们不能将 coder.varsize 用于类中的属性,但如果您愿意,您可以使用 varsized 持久变量。
在您的情况下,我要做的是创建一个句柄类来存储和检索值。以下示例非常基本,但可以使用并且可以扩展。如果在方法中使用了持久变量,您甚至可以为数据创建一个可变大小的分配存储,但在我的示例中,它是一个属性,并且它可以存储的值的数量受到限制。
classdef keyval < handle %# codegen
%KEYVAL A key and value class designed for Coder
% Stores an arbitrary number of keys and values.
properties (SetAccess = private)
numvals = 0
end
properties (Access = private)
intdata
end
properties (Constant)
maxvals = 100;
maxkeylength = 30;
end
methods
function obj = keyval
%KEYVAL Constructor for keyval class
obj.intdata = repmat(struct('key', char(zeros(1, obj.maxkeylength)), 'val', 0), 1, obj.maxvals);
end
function result = put(obj, key, value)
%PUT Adds a key and value pair into storage
% Result is 0 if successful, 1 on error
result = 0;
if obj.numvals >= obj.maxvals
result = 1;
return;
end
obj.numvals = obj.numvals + 1;
tempstr = char(zeros(1,obj.maxkeylength));
tempstr(1,1:min(end,numel(key))) = key(1:min(end, obj.maxkeylength));
obj.intdata(obj.numvals).key = tempstr;
obj.intdata(obj.numvals).value = value;
end
function keystring = getkeyatindex(obj, index)
%GETKEYATINDEX Get a key name at an index
keystring = deblank(obj.intdata(index).key);
end
function value = getvalueforkey(obj, keyname)
%GETVALUEFORKEY Gets a value associated with a key.
% Returns NaN if not found
value = NaN;
for i=1:obj.numvals
if strcmpi(keyname, deblank(obj.intdata(i).key))
value = obj.intdata(i).value;
end
end
end
end
end
这个类实现了一个简单的键/值添加以及查找。有几点需要注意。首先,在分配时非常小心,以确保我们不会超出整个存储空间。其次,它使用deblank 清除字符串存储中所需的尾随零。在这种情况下,不允许结构中的字符串具有不同的长度,因此当我们将关键字符串放入其中时,它需要与尾随空值完全相同的长度。 Deblank 为调用函数清理了这个。
常量属性分配我们在存储阵列中允许的空间总量。显然,这些可以增加,但不能在运行时增加。
在 MATLAB 命令提示符下,使用此类如下所示:
>> obj = keyval
obj =
keyval with properties:
numvals: 0
>> obj.put('SomeKeyName', 1.23456)
ans =
0
>> obj
obj =
keyval with properties:
numvals: 1
>> obj.put('AnotherKeyName', 34567)
ans =
0
>> obj
obj =
keyval with properties:
numvals: 2
>> obj.getvalueforkey('SomeKeyName')
ans =
1.2346
>> obj.getkeyatindex(2)
ans =
AnotherKeyName
>> obj.getvalueforkey(obj.getkeyatindex(2))
ans =
34567
如果需要一个完全可变的存储区域,可以使用带有 coder.varsize 的持久变量,但这会将此类的使用限制为单个实例。持久变量很好,但你只能得到其中一个。正如所写,您可以在程序的许多不同位置使用此类用于不同的存储。如果使用持久变量,则只能使用一次。
如果您知道一些键名并在以后使用它们来确定功能,请记住您可以在 MATLAB 中打开字符串,这在 Coder 中有效。