Matlab 2009b & .NET - PullRequest
       12

Matlab 2009b & .NET

1 голос
/ 22 января 2010

У меня всякие проблемы с перечислениями [FlagsAttribute] в Matlab. Похоже, нет способа передать комбинацию значений в качестве параметра в .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>, установленный в 'Public'.

Это, разумеется, для всех перечислений [FlagsAttribute].

Я что-то здесь упускаю? Написание оболочки enum для Clab для Matlab не является большой проблемой, но это сильно замедлит процесс. Любой обходной путь будет глубоко, глубоко признателен.

Ответы [ 2 ]

0 голосов
/ 14 октября 2010

(это не ответ, просто дополнительная информация)

На момент написания этой статьи последняя версия MATLAB (2010b) не предоставляла интерфейс .NET, позволяющий работать с перечислениями флагов.

Одна из фундаментальных частей .NET, которую MATLAB не поддерживает, - приведение. Это означает строку кода, подобную этой:

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".

0 голосов
/ 22 января 2010

ОТВЕТ НА НЕПРАВИЛЬНЫЙ ВОПРОС:

Если я правильно понимаю проблему, это так:

Чтобы передать перечисления в MATLAB, вам нужно преобразовать его в тип переменной, понятный MATLAB- в этом случае строка.Таким образом, ваше перечисление

BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

преобразуется в

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

Когда код возвращается в .NET из MATLAB, вы хотите преобразовать строку обратно в перечисление.

Вы были очень близки, и пример на странице справки для Enum.Parse дает вам синтаксис.

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

(Кроме того, присвоение переменной enum толькособираюсь закончиться слезами.)


ВТОРАЯ ПОПЫТКА НА ОТВЕТ

Я согласен, что это поведение MATLAB кажется нарушенным.Одним из решений было бы написать свои собственные обёртки для Enum.Parse и Enum.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 объединить их снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...