如何在 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