如何在 Simulink 中使用 .Net 枚举?
How is it possible to use .Net enums in Simulink?
我正在评估 Simulink 环境中现有 .Net 程序集的 .Net 枚举的重用情况。这应该可以防止在 .Net 环境中更改枚举,但不能在 Simulink 模型中更改。换句话说:当枚举已经在 .Net 中定义并且可以重复使用时,应该不需要在 matlab 中定义枚举。
我的 Simulink 模型如下:
我有一个 "branch" 演示了一个带有双值的 switch 案例,下面是另一个用 matlab 内置的枚举来实现的案例。
classdef (Sealed) mDayOfWeek < Simulink.IntEnumType
enumeration
mSunday(0)
mMonday(1)
mTuesday(2)
mWednesday(3)
mThursday(4)
mFriday(5)
mSaturday(6)
end
end
当我打开我的 Simulink 模型时,我已经注册到 运行 我的 go.m(通过模型属性 -> 回调 -> PreLoadFcn)。它使用默认值预填充变量 Eingabe 和 mEingabe,如下所示:
if exist('Eingabe', 'var') == 0
Eingabe = 0;
end
if exist('mEingabe', 'var') == 0
mEingabe = mDayOfWeek.mSunday;
end
现在我想添加第三个分支,它应该使用 mscorlib.dll 中的枚举 System.DayOfWeek。初始化不是问题:
if exist('sEingabe', 'var') == 0
sEingabe = System.DayOfWeek.Sunday;
end
但是,我什至没有成功配置一个常量块,其常量值来自 System.DayOfWeek:
有什么我遗漏的吗?有可能吗?我需要写一些转换来完成它吗?
MathWorks 支持人员告诉我,不支持在 Simulink 中使用 .NET 对象实例作为信号。我被鼓励使用 "int32" 函数通过将常量块的值设置为
将 .NET 枚举值转换为相应的整数值
int32(System.DayOfWeek.Thursday)
并按如下方式配置 SwitchCase 块:
{int32(System.DayOfWeek.Thursday), int32(System.DayOfWeek.Friday)}
但是有人告诉我,这不能与 Matlab/Simulink 的任何代码生成功能结合使用。如果需要(如我的情况),可以自动让 Matlab 在 .NET 反射的帮助下生成适当的 Matlab 枚举,以保持枚举同步。看起来像这样(未测试):
function genEnum(classname)
% Use .NET refection to get Type information
t = System.Type.GetType('System.DayOfWeek');
% Create a new M-file with the name of the Enum
f = fopen([char(t.Name) '.m'],'w');
% Write the classdef header with the name of the class
fprintf(f,'classdef %s < Simulink.IntEnumType\n',char(t.Name));
% Open enumeration
fprintf(f,'\tenumeration\n');
% Get all Enum Values
v = t.GetEnumValues;
for i=1:v.Length
% Add each value
fprintf(f,'\t\t%s(%d)\n',char(v(i)),int32(v(i)));
end
% Close the class and enum definitions
fprintf(f,'\tend\nend\n');
% Close the file
fclose(f);
最后我决定改用这种 T4 模板,在我看来它非常简单:
classdef (Sealed) mDayOfWeek < Simulink.IntEnumType
enumeration
<#
var arr = System.Enum.GetValues(typeof(System.DayOfWeek));
foreach(var it in arr)
{
string name = it.ToString();
string value = ((int)it).ToString();
#>
<#= name #>(<#= value #>)
<#
}
#>
end
end
我正在评估 Simulink 环境中现有 .Net 程序集的 .Net 枚举的重用情况。这应该可以防止在 .Net 环境中更改枚举,但不能在 Simulink 模型中更改。换句话说:当枚举已经在 .Net 中定义并且可以重复使用时,应该不需要在 matlab 中定义枚举。
我的 Simulink 模型如下:
我有一个 "branch" 演示了一个带有双值的 switch 案例,下面是另一个用 matlab 内置的枚举来实现的案例。
classdef (Sealed) mDayOfWeek < Simulink.IntEnumType
enumeration
mSunday(0)
mMonday(1)
mTuesday(2)
mWednesday(3)
mThursday(4)
mFriday(5)
mSaturday(6)
end
end
当我打开我的 Simulink 模型时,我已经注册到 运行 我的 go.m(通过模型属性 -> 回调 -> PreLoadFcn)。它使用默认值预填充变量 Eingabe 和 mEingabe,如下所示:
if exist('Eingabe', 'var') == 0
Eingabe = 0;
end
if exist('mEingabe', 'var') == 0
mEingabe = mDayOfWeek.mSunday;
end
现在我想添加第三个分支,它应该使用 mscorlib.dll 中的枚举 System.DayOfWeek。初始化不是问题:
if exist('sEingabe', 'var') == 0
sEingabe = System.DayOfWeek.Sunday;
end
但是,我什至没有成功配置一个常量块,其常量值来自 System.DayOfWeek:
有什么我遗漏的吗?有可能吗?我需要写一些转换来完成它吗?
MathWorks 支持人员告诉我,不支持在 Simulink 中使用 .NET 对象实例作为信号。我被鼓励使用 "int32" 函数通过将常量块的值设置为
将 .NET 枚举值转换为相应的整数值int32(System.DayOfWeek.Thursday)
并按如下方式配置 SwitchCase 块:
{int32(System.DayOfWeek.Thursday), int32(System.DayOfWeek.Friday)}
但是有人告诉我,这不能与 Matlab/Simulink 的任何代码生成功能结合使用。如果需要(如我的情况),可以自动让 Matlab 在 .NET 反射的帮助下生成适当的 Matlab 枚举,以保持枚举同步。看起来像这样(未测试):
function genEnum(classname)
% Use .NET refection to get Type information
t = System.Type.GetType('System.DayOfWeek');
% Create a new M-file with the name of the Enum
f = fopen([char(t.Name) '.m'],'w');
% Write the classdef header with the name of the class
fprintf(f,'classdef %s < Simulink.IntEnumType\n',char(t.Name));
% Open enumeration
fprintf(f,'\tenumeration\n');
% Get all Enum Values
v = t.GetEnumValues;
for i=1:v.Length
% Add each value
fprintf(f,'\t\t%s(%d)\n',char(v(i)),int32(v(i)));
end
% Close the class and enum definitions
fprintf(f,'\tend\nend\n');
% Close the file
fclose(f);
最后我决定改用这种 T4 模板,在我看来它非常简单:
classdef (Sealed) mDayOfWeek < Simulink.IntEnumType
enumeration
<#
var arr = System.Enum.GetValues(typeof(System.DayOfWeek));
foreach(var it in arr)
{
string name = it.ToString();
string value = ((int)it).ToString();
#>
<#= name #>(<#= value #>)
<#
}
#>
end
end