Реализуйте безопасный с точки зрения типов интерфейс и объединяйтесь в приложение.NET

В этом примере показано, как реализовать безопасный с точки зрения типов интерфейс и интегрировать его в приложение.NET.

Безопасные с точки зрения типов интерфейсы позволяют вам работать непосредственно со знакомыми собственными типами данных вместо того, чтобы использовать MWArray API. Добавление безопасного с точки зрения типов интерфейса к блоку.NET создает дополнительный набор методов, которые принимают и возвращают нативные типы.NET.

Запишите и протестируйте свой код MATLAB

Создайте свой MATLAB® программа и затем тестирует код прежде, чем реализовать безопасный с точки зрения типов интерфейс. Функции в вашей программе MATLAB должны совпадать с объявлениями в вашем нативном интерфейсе.NET.

В данном примере сохраните следующий код как multiply.m. Функция возвращает умножение входных параметров x и y.

function z = multiply(x,y)
z = x * y;

Протестируйте функцию в командной строке MATLAB.

multiply([1 4 7; 2 5 8; 3 6 9],[1 4 7; 2 5 8; 3 6 9])
 ans =

    30    66   102
    36    81   126
    42    96   150

Реализуйте безопасный с точки зрения типов интерфейс

После того, как вы пишете и тестируете свой код MATLAB, разрабатываете.NET безопасный с точки зрения типов интерфейс или в C# или в Visual Basic®. Этот пример использование, обеспеченное исходный код C# для интерфейса.

  1. Открытая Microsoft® Visual Studio® и создайте новый проект Class Library (.NET Framework) под названием IMultiply.

  2. В окне Solution Explorer переименуйте Class1.cs файл к IMultiply.cs. В этом файле вы пишете исходный код для безопасного с точки зрения типов интерфейса, это получает доступ к компоненту.

    В этом примере, IMultiply интерфейс написан в C# и задает три перегрузки multiply:

    using System;
    
    public interface IMultiply
    {
        // Scalar multiplication
        System.Double multiply(System.Double x, System.Double y);
    
        // Multiply vector by a scalar, return a vector
        System.Double[] multiply(System.Double[] x, System.Double y);
    
        // Matrix multiplication
        System.Double[,] multiply(System.Double[,] x, System.Double[,] y);
    }

    Каждый метод в интерфейсе должен точно совпадать с развернутой функцией MATLAB.

    Все методы имеют два входных параметров и один выход (чтобы совпадать с multiply MATLAB функция), хотя тип данных параметров варьируется.

  3. Перейдите к Build и затем Configuration Manager, и измените платформу от Any CPU до x64.

  4. Разработайте проект с Microsoft Visual Studio.

    Файл IMultiply.dll сгенерирован в папке сборки.

Этот пример принимает, что ваш блок содержит только IMultiply. Реалистично, более вероятно, что безопасный с точки зрения типов интерфейс уже будет частью скомпилированного блока. Блок может быть скомпилирован даже, прежде чем функция MATLAB записана.

Создайте блок.NET Используя приложение Library Compiler

Сгенерируйте безопасный с точки зрения типов интерфейс с блоком.NET с помощью приложения Library Compiler. В качестве альтернативы, если вы хотите создать блок.NET из окна команды MATLAB с помощью программируемого подхода, смотрите, Создают блок.NET Используя compiler.build.dotNETAssembly.

  1. Создайте проект Library Compiler и выберите .NET Assembly из списка Type.

  2. Задайте следующие значения:

    Поле Значение
    Library NameMultiply
    Class NameArithmetic
    File to Compilemultiply.m

  3. Расширьте раздел Additional Runtime Settings.

  4. В разделе Type-Safe API сделайте следующее:

    1. Выберите Enable Type-Safe API.

    2. В поле Interface assembly задайте местоположение безопасного с точки зрения типов интерфейсного блока IMultiply.dll то, что вы создали.

    3. Выберите IMultiply интерфейс от .NET interface выпадающее поле.

    4. Оставьте незаполненное поле Namespace.

    5. Задайте Arithmetic класс в поле Wrapped Class.

  5. Нажмите кнопку Package, чтобы разработать проект.

Создайте блок.NET Используя compiler.build.dotNETAssembly

Как альтернатива приложению Library Compiler, можно сгенерировать безопасный с точки зрения типов интерфейс с помощью программируемого подхода с помощью следующих шагов. Если вы уже создали блок с помощью Library Compiler, смотрите, Интегрируют блок.NET В Приложение.NET.

  1. Создайте блок.NET с помощью compiler.build.dotNETAssembly функция. Используйте аргументы name-value, чтобы задать имя сборки и имя класса.

    compiler.build.dotNETAssembly('multiply.m', ...
        'AssemblyName','Multiply', ...
        'ClassName','Arithmetic');
    
  2. Перейдите к сгенерированному MultiplydotNETAssembly папка.

  3. Сгенерируйте безопасный с точки зрения типов интерфейс при помощи ntswrap команда из MATLAB:

    ntswrap('-c','Multiply.Arithmetic', ...
            '-a','IMultiply.dll', ...
            '-i','IMultiply');

    Не все аргументы совместимы друг с другом. Смотрите ntswrap для деталей обо всех опциях команды.

    Совет

    Если IMultiply.dll блок не находится в текущей папке, задайте полный путь.

    Эта команда генерирует блок ArithmeticIMultiply.dll это содержит безопасный с точки зрения типов API для класса MATLAB Compiler SDK™ Arithmetic в пространстве имен MultiplyNative.

Интегрируйте блок.NET в приложение.NET

После создания вашего блока.NET можно интегрировать его в любое приложение.NET. Можно использовать этот код приложения.NET в качестве примера в качестве руководства, чтобы записать собственное приложение.NET.

Скомпилируйте программу.NET с помощью Microsoft Visual Studio путем выполнения следующих шагов:

  1. Открытый Microsoft Visual Studio и создает Console App (.NET Framework) C# по имени MultiplyApp.

  2. Скопируйте следующий исходный код в сгенерированный Program.cs в вашем проекте:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace MultiplyApp
    {
        class Program
        {
            delegate String VectorToString<T>(IEnumerable<T> v);
            delegate IEnumerable<String> MatrixToString<T>(T[,] m);
    
            static void Main(string[] args)
            {
                Console.WriteLine("\nStarting application...\n");
                
                //Create an instance of the Type-safe API
                IMultiply m = new ArithmeticIMultiply();
                
                // Scalar multiplication
                double x = 17, y = 3.14159;
                double z = m.multiply(x, y);
                System.Console.WriteLine("{0} * {1} = {2}\n", x, y, z);
    
                // Vector times scalar
                double[] v = new double[] { 2.5, 81, 64 };
                double s = 11;
                double[] d = m.multiply(v, s);
    
                VectorToString<double> vec2str = (vec =>
                  vec.Select(n => n.ToString()).Aggregate((str, next) => str + " " + next));
    
                System.Console.WriteLine("[ {0} ] * {1} = [ {2} ]\n",
                    vec2str(v), s, vec2str(d));
    
                // Matrix multiplication
                double[,] magic = new double[,]{  // 3x3 magic square
                         { 8, 1, 6 },
                         { 3, 5, 7 },
                         { 4, 9, 2 } };
                double[,] squareSquared = m.multiply(magic, magic);
    
                MatrixToString<double> mat2str = mat =>
                    mat.EnumerateRows<double>().Select(r => vec2str(r));
    
                PrintParallel(mat2str(magic), " * ".Select(c => c.ToString()),
                              mat2str(magic), " = ".Select(c => c.ToString()),
                              mat2str(squareSquared));
    
                Console.WriteLine("\nClosing application...");
            }
    
            public static void PrintParallel<T>(params IEnumerable<T>[] sources)
            {
                int max = sources.Select(s => s.Count()).Max();
                for (int i = 0; i < max; i++)
                {
                    foreach (var src in sources)
                        System.Console.Write("{0} ", src.ElementAt(i));
                    System.Console.WriteLine();
                }
            }
        }
        public static class ArrayExtensions
        {
            public static IEnumerable<IEnumerable<T>> EnumerateRows<T>(this Array a)
            {
                return Enumerable.Range(0, a.GetLength(1)).Select(row =>
                    a.ToIEnumerable<T>().Skip(row * a.GetLength(0)).Take(a.GetLength(0)));
            }
    
            public static IEnumerable<T> ToIEnumerable<T>(this Array a)
            {
                foreach (var item in a)
                    yield return (T)item;
            }
    
        }
    }
    
  3. Добавьте ссылки в проекте к следующим файлам.

    Эта ссылка:Задает:
    IMultiply.dllСобственный компонент.NET вводит интерфейсный блок IMultiply
    ArithmeticIMultiply.dllСгенерированный безопасный с точки зрения типов API
    MultiplyNative.dllСгенерированный блок.NET

    Примечание

    В отличие от других сценариев развертывания.NET, вы не должны ссылаться на MWArray.dll в исходном коде программы сервера. MWArray типы данных скрыты позади безопасного с точки зрения типов API в ArithmeticIMultiply.

  4. Перейдите к Build и затем Configuration Manager, и измените платформу от Any CPU до x64.

  5. Скомпилируйте и запустите программу с Microsoft Visual Studio.

    Программа отображает следующий вывод:

    Starting application...
    
    17 * 3.14159 = 53.40703
    
    [ 2.5 81 64 ] * 11 = [ 27.5 891 704 ]
    
    8 1 6   8 1 6   91 67 67
    3 5 7 * 3 5 7 = 67 91 67
    4 9 2   4 9 2   67 67 91
    
    Closing application...

Советы

  • В функции MATLAB объявление выводит, появляются перед входными параметрами. Например, в multiply функция, выход z появляется перед входными параметрами x и y. Это упорядоченное расположение не требуется для функций интерфейса.NET. Входные параметры могут появиться, прежде или после того, как выходные параметры или эти два могут быть смешаны вместе.

  • MATLAB Compiler SDK совпадает с функциями интерфейса.NET к общедоступным функциям MATLAB количеством аргумента и именем функции. В multiply пример, и функция интерфейса.NET и функция MATLAB нужно назвать multiply, и обе функции должны иметь равное количество заданных аргументов.

  • Номер и относительный порядок аргументов ввода и вывода очень важны.

    • В оценке порядка параметра только порядок подобных параметров (вводы или выводы) рассматривается, независимо от того, где они появляются в списке параметров.

    • Функция в интерфейсе может иметь меньше входных параметров, чем его соответствующая функция MATLAB, но не больше.

  • Отображение аргумента происходит согласно порядку аргументов, а не имени аргумента.

  • Функциональное возвращаемое значение, если задано, рассчитывает как первый выход.

  • Необходимо использовать out параметры для нескольких выходных параметров.

    • Альтернативно, ref параметр может использоваться для out, как ref и out синонимичны.

  • MATLAB не поддерживает перегрузку функций. Таким образом все предоставленные пользователями перегрузки функции с именем сопоставят с функцией, сгенерированной MATLAB Compiler SDK.

Смотрите Типы.NET к Типам MATLAB для полных инструкций в преобразовании данных об управлении с безопасными с точки зрения типов интерфейсами.

Смотрите также

|

Похожие темы