Matlab 2009b& 。净

时间:2010-01-22 02:27:59

标签: .net matlab enums

我在Matlab中使用[FlagsAttribute]枚举时遇到了各种麻烦。 似乎没有办法将值组合作为参数传递给.NET。 例如,BindingFlags.Public | BindingFlags.Instance,一旦你在Matlab中将它们组合在一起,它们就变成了一个内部类型,不能被强制转换回BindingFlags。

这样的事情
import System.*;
import System.Reflection.*;

flags = BindingFlags.Public+BindingFlags.Instance;
enum  = Enum.ToObject(Type.GetType('System.Reflection.BindingFlags'), int32(flags));

enum = Enum.Parse(Type.GetType('System.Reflection.BindingFlags'), 'Public, Instance');

根本无法正常工作:

???在调用“System.Enum.ToObject”期间未分配的一个或多个输出参数 (或“System.Enum.Parse”)。

另一方面

enum = Enum.Parse(Type.GetType('System.Reflection.BindingFlags'), 'Public');

工作正常并返回< 1x1 System.Reflection.BindingFlags>设为'公开'。

不用说,对于所有[FlagsAttribute]枚举。

我在这里遗漏了什么吗? 为Matlab编写一个C#反射枚举包装器并不是什么大问题,但这会大大减慢速度。 任何解决方法都会深深地,深深地感激。

2 个答案:

答案 0 :(得分:0)

回答错误的问题:

如果我正确理解问题,那就是:

要将枚举传递给MATLAB,您需要将其转换为MATLAB理解的变量类型 - 在本例中为字符串。所以你的枚举

BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

转换为

"Public, Instance"  // via flags.ToString()   

当代码从MATLAB返回.NET时,您希望将字符串转换回枚举。

您非常接近,help page for Enum.Parse上的示例为您提供了语法。

BindingFlags flags2 = (BindingFlags)Enum.Parse(typeof(BindingFlags), "Public, Instance");

(另外,命名变量“enum”只会以泪流满面。)


答案的第二次尝试

我同意这个MATLAB行为似乎已被打破。一种解决方案是将自己的包装器写入Enum.ParseEnum.Object,这些包装器不会中断。像这样的东西:

function enum = EnumParse(typename, value)
import System.*;

type = Type.GetType(typename);
values = regexp(value, ', ', 'split');

enum = cell(1, length(values));
for i = 1:length(values)
   enum{i} = Enum.Parse(type, values{i});
end
end


function enum = EnumToObject(typename, value)
import System.*;

type = Type.GetType(typename);
values = int32(GetPowersOf2(value));

enum = cell(1, length(values));
for i = 1:length(values)
   enum{i} = Enum.ToObject(type, values(i));
end
end

function y = GetPowersOf2(x)
index = logical(arrayfun(@str2num, dec2bin(x)));
y = 2.^((length(index) - 1):-1:0);
y = y(index);
end

这些的用法是,例如,

EnumParse('System.Reflection.BindingFlags', 'Public, Instance')
EnumToObject('System.Reflection.BindingFlags', 20)

请注意,我在这里采用了简单的路径,只返回了一个BindingFlags的单元格数组,而不是试图说服MATLAB再次组合它们。

答案 1 :(得分:0)

(这不是答案,只是更多信息)

在撰写本文时,最新版本的MATLAB(2010b)没有提供允许您使用标志枚举的.NET接口。

MATLAB不支持的.NET的基本部分之一是强制转换。 这意味着一行代码如下:

myControl.Anchor = (AnchorStyles)(AnchorStyles.Top | AnchorStyles.Bottom)

无法用MATLAB编写。

.NET方法 System.Enum.Parse 非常适合解决在MATLAB中创建组合标志枚举的问题。但是,当从MATLAB调用时,System.Enum.Parse被破坏。

试试这个:

>> NET.addAssembly('System.Windows.Forms');
>> anchorStylesTypeName = 'System.Windows.Forms.AnchorStyles, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089';
>> anchorType = System.Type.GetType(anchorStylesTypeName);
>> enum = System.Enum.Parse(anchorType, '1')

enum = 

   Top
>> 
>> % That looked good!
>> enum = System.Enum.Parse(anchorType, '2')

enum = 

    Bottom
>>
>> % OK, now we combine them...
>> enum = System.Enum.Parse(anchorType, '3')
??? One or more output arguments not assigned during call to
"_class_dot_paren".

在C#中运行时,相同的功能正常工作:将“3”传递给System.Enum.Parse会返回“Top,Bottom”。