Передайте аргументы и из Java

Формат

Когда вы вызываете метод на сгенерированный класс, входные параметры, полученные методом, должны быть в формате внутреннего массива MATLAB®. Можно или преобразовать их сами в рамках программы вызова или передать аргументы как типы данных Java®, которые затем автоматически преобразованы механизмом вызова.

Чтобы преобразовать их самостоятельно, используйте экземпляры классов MWArray; в этом случае вы используете manual conversion. Хранение ваших данных с помощью классов и типов данных, заданных на языке Java, означает, что вы полагаетесь на automatic conversion. Скорее всего, вы будете использовать комбинацию ручного и автоматического преобразования.

Ручное преобразование типов данных

Чтобы вручную преобразовать в один из стандартных типов данных MATLAB, используйте классы преобразования данных MWArray, обеспеченные компилятором. Для ссылки класса и информации об использовании, смотрите пакет com.mathworks.toolbox.javabuilder.

Используя MWNumericArray

Пример Магического квадрата (Интегрируют Пакет Java в Приложение) иллюстрирует ручное преобразование. Следующий фрагмент кода из той программы показывает аргумент java.lang.Double, который преобразован в тип MWNumericArray, который может использоваться функцией MATLAB без дальнейшего преобразования:

n = new MWNumericArray(Double.valueOf(args[0]),
                                      MWClassID.DOUBLE);

         theMagic = new Class1();

         result = theMagic.makesqr(1, n);

Передача MWArray.  Этот пример создает MWNumericArray типа MWClassID.DOUBLE. Вызов myprimes передает количество выходных параметров, 1, и MWNumericArray, x:

x = new MWNumericArray(n, MWClassID.DOUBLE);
cls = new myclass();
y = cls.myprimes(1, x);

Джейва-Бридж преобразовывает объект MWNumericArray в скаляр MATLAB double, чтобы передать функции MATLAB.

Автоматическое преобразование в тип MATLAB

При передаче аргумента только небольшое число раз обычно столь же эффективно передать примитивный тип Java или объект. В этом случае механизм вызова преобразовывает данные для вас в эквивалентный тип MATLAB.

Например, любой из следующих типов Java был бы автоматически преобразован в тип double MATLAB:

  • Java примитивный double

  • Объект класса java.lang.Double

Для справочной информации о преобразовании данных (таблицы, показывающие каждый тип Java наряду с его конвертированным типом MATLAB и каждым типом MATLAB с его конвертированным типом Java), см. Правила для Преобразования Данных Между Java и MATLAB.

Автоматическое преобразование данных

Когда вызов метода makesqr использовал в приложении getmagic, вы могли создать объект типа MWNumericArray. Выполнение так было бы примером ручного преобразования. Вместо этого вы могли полагаться на автоматическое преобразование, как показано в следующем фрагменте кода:

result = M.makesqr(1, arg[0]);

В этом случае Java double передается как arg[0].

Вот другой пример:

result = theFourier.plotfft(3, data, new Double(interval));

В этом операторе Java третий аргумент имеет тип java.lang.Double. Согласно правилам преобразования, java.lang.Double автоматически преобразовывает в MATLAB массив double 1 на 1.

Передача Java дважды возражает

Пример вызывает метод myprimes с двумя аргументами. Первое задает количество аргументов, чтобы возвратиться. Вторым является объект класса java.lang.Double, который передает один ввод данных myprimes.

cls = new myclass();
y = cls.myprimes(1, new Double((double)n));

Этот второй аргумент преобразован в MATLAB массив double 1 на 1, как требуется функцией MATLAB. Это - правило преобразования по умолчанию для java.lang.Double.

Передача MWArray

Этот пример создает MWNumericArray типа MWClassID.DOUBLE. Вызов myprimes передает количество выходных параметров, 1, и MWNumericArray, x.

x = new MWNumericArray(n, MWClassID.DOUBLE);
cls = new myclass();
y = cls.myprimes(1, x);

Компилятор преобразовывает объект MWNumericArray в скаляр MATLAB double, чтобы передать функции MATLAB.

Вызов методы MWArray

Правила преобразования применяются не только когда вызов ваших собственных методов, но также и при вызове конструкторов и методов фабрики, принадлежащих классам MWArray.

Например, следующий фрагмент кода вызывает конструктора для класса MWNumericArray с Java double как входной параметр:

double Adata = 24;
MWNumericArray A = new MWnumericArray(Adata);
System.out.println("Array A is of type " + A.classID());

Компилятор преобразовывает входной параметр в экземпляр MWNumericArray со свойством ClassID MWClassID.DOUBLE. Этот объект MWNumericArray является эквивалентом MATLAB массив double 1 на 1.

Когда вы запускаете этот пример, результат следующие:

Array A is of type double

Изменение значения по умолчанию путем определения типа

Когда вызов конструктора метода класса MWArray, предоставление определенного типа данных заставляют продукт MATLAB Compiler SDK™ преобразовывать в тот тип вместо значения по умолчанию.

Например, в следующем фрагменте кода, код указывает, что A должен быть создан как MATLAB 16-битный целочисленный массив 1 на 1:

double Adata = 24;
MWNumericArray A = new MWnumericArray(Adata, MWClassID.INT16);
System.out.println("Array A is of type " + A.classID());

Когда вы запускаете этот пример, результат следующие:

Array A is of type int16

Задайте дополнительные аргументы

До сих пор примеры не использовали функции MATLAB, которые имеют аргументы varargin или varargout. Рассмотрите следующую функцию MATLAB:

function y = mysum(varargin)

y = sum([varargin{:}]);

Эта функция возвращает сумму входных параметров. Входные параметры обеспечиваются в качестве аргумента varargin, что означает, что вызывающая сторона может задать любое количество входных параметров к функции. Результат возвращен как скалярный double.

Передайте переменные количества входных параметров

Продукт MATLAB Compiler SDK генерирует интерфейс Java к этой функции можно следующим образом:

/* mlx interface - List version*/
public void mysum(List lhs, List rhs)
                          throws MWException
{
   (implementation omitted)
}
/* mlx interface - Array version*/
public void mysum(Object[] lhs, Object[] rhs)
                          throws MWException
{
   (implementation omitted)
}

/* standard interface - no inputs */
public Object[] mysum(int nargout) throws MWException
{
   (implementation omitted)
}

/* standard interface - variable inputs */
public Object[] mysum(int nargout, Object varargin)
                          throws MWException
{
   (implementation omitted)
}

Во всех случаях аргумент varargin передается как тип Object. Это позволяет вам обеспечить любое количество входных параметров в форме массива Объекта, который является Object[], и содержимое этого массива передается скомпилированной функции MATLAB в порядке, в котором они появляются в массиве. Вот пример того, как вы можете использовать метод mysum в программе Java:

public double getsum(double[] vals) throws MWException
{
   myclass cls = null;
   Object[] x = {vals};
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.mysum(1, x);
      return ((MWNumericArray)y[0]).getDouble(1);
   }

   finally
   {
      MWArray.disposeArray(y);
      if (cls != null)
	      cls.dispose();
   }
}

В этом примере массив Object длины 1 создается и инициализируется со ссылкой на предоставленный массив double. Этот аргумент передается методу mysum. Результатом, как известно, является скалярный double, таким образом, код возвращает это значение double с оператором:

return ((MWNumericArray)y[0]).getDouble(1);

Бросьте возвращаемое значение к MWNumericArray и вызовите метод getDouble(int), чтобы возвратить первый элемент в массиве как примитивное значение double.

Передайте Входные параметры Массивов.  Следующий пример выполняет более общее вычисление:

public double getsum(Object[] vals) throws MWException
{
   myclass cls = null;
   Object[] x = null;
   Object[] y = null;

   try
   {
      x = new Object[vals.length];
      for (int i = 0; i < vals.length; i++)
         x[i] = new MWNumericArray(vals[i], MWClassID.DOUBLE);

      cls = new myclass();
      y = cls.mysum(1, x);
      return ((MWNumericArray)y[0]).getDouble(1);
   }
   finally
   {
      MWArray.disposeArray(x);
      MWArray.disposeArray(y);
      if (cls != null)
         cls.dispose();
   }
}

Эта версия getsum берет массив Object, как введено и преобразовывает каждое значение в массив double. Список массивов double затем передается функции mysum, где это вычисляет полную сумму каждого входного массива.

Передайте переменное количество Выходных параметров

Когда существующий, аргументы varargout обработаны таким же образом, что аргументы varargin обработаны. Рассмотрите следующую функцию MATLAB:

function varargout = randvectors

for i=1:nargout
   varargout{i} = rand(1, i);
end

Эта функция возвращается, список случайного double векторизовал таким образом, что длина i th вектор равна i. Продукт MATLAB Compiler™ генерирует интерфейс Java к этой функции можно следующим образом:

/* mlx interface - List version */
 public void randvectors(List lhs, List rhs) throws MWException
{
   (implementation omitted)
}
/* mlx interface - Array version */
public void randvectors(Object[] lhs, 
           Object[] rhs) throws MWException
{
   (implementation omitted)
}
/* Standard interface - no inputs*/
public Object[] randvectors(int nargout) throws MWException
{
   (implementation omitted)
}

Передайте Дополнительные аргументы со Стандартным Интерфейсом.  Вот один способ использовать метод randvectors в программе Java:

public double[][] getrandvectors(int n) throws MWException
{
   myclass cls = null;
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.randvectors(n);
      double[][] ret = new double[y.length][];

      for (int i = 0; i < y.length; i++)
         ret[i] = (double[])((MWArray)y[i]).getData();
      return ret;
   }

   finally
   {
      MWArray.disposeArray(y);
      if (cls != null)
         cls.dispose();
   }
}

Метод getrandvectors возвращает двумерный массив double с треугольной структурой. Длина i th строка равняется i. Такие массивы обычно упоминаются как зубчатые массивы. Зубчатые массивы легко поддержаны на Java, потому что матрица Java является только массивом массивов.

Обработайте возвращаемые значения

Предыдущие примеры использовали то, что вы знали тип и размерность выходного аргумента. В случае, что эта информация неизвестна, или может отличаться (как возможно в программировании MATLAB), код, который вызывает метод, может должен быть запросить тип и размерность выходных аргументов.

Существует несколько способов сделать это. Выполнить одно из следующих действий:

  • Используйте отражательную поддержку на языке Java, чтобы запросить любой объект для его типа.

  • Используйте несколько методов, предоставленных классом MWArray, чтобы запросить информацию о базовом массиве MATLAB.

  • Принуждение к определенному типу с помощью Type to методы Array.

Используйте отражение Java, чтобы определить тип и размерность

Этот пример кода вызывает метод myprimes, и затем определяет тип с помощью отражения. Пример принимает, что выходной параметр возвращен как числовая матрица, но точный числовой тип неизвестен.

public void getprimes(int n) throws MWException
{
   myclass cls = null;
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.myprimes(1, new Double((double)n));
      Object a = ((MWArray)y[0]).toArray();

      if (a instanceof double[][])
      {
         double[][] x = (double[][])a;

         /* (do something with x...) */
      }

      else if (a instanceof float[][])
      {
         float[][] x = (float[][])a;

         /* (do something with x...) */
      }

      else if (a instanceof int[][])
      {
         int[][] x = (int[][])a;

         /* (do something with x...) */
      }

      else if (a instanceof long[][])
      {
         long[][] x = (long[][])a;

         /* (do something with x...) */
      }

      else if (a instanceof short[][])
      {
         short[][] x = (short[][])a;

         /* (do something with x...) */
      }

      else if (a instanceof byte[][])
      {
         byte[][] x = (byte[][])a;

         /* (do something with x...) */
      }

      else
      {
         throw new MWException(
            "Bad type returned from myprimes");
      }
   }

Этот пример использует метод toArray, чтобы возвратить Java примитивный массив, представляющий базовый массив MATLAB. Метод toArray работает точно так же, как getData в предыдущих примерах, за исключением того, что возвращенный массив имеет ту же размерность как базовый массив MATLAB.

Используйте запрос MWArray, чтобы определить тип и размерность

Следующий пример использует метод classID MWArray, чтобы определить тип базового массива MATLAB. Это также проверяет размерность путем вызова numberOfDimensions. Если неожиданная информация возвращена, исключение выдается. Это затем проверяет MWClassID и обрабатывает массив соответственно.

public void getprimes(int n) throws MWException
{
   myclass cls = null;
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.myprimes(1, new Double((double)n));
      MWClassID clsid = ((MWArray)y[0]).classID();

      if (!clsid.isNumeric() ||
         ((MWArray)y[0]).numberOfDimensions() != 2)
      {
         throw new MWException("Bad type 
                          returned from myprimes");
      }

      if (clsid == MWClassID.DOUBLE)
      {
         double[][] x = (double[][])((MWArray)y[0]).toArray();

         /* (do something with x...) */
      }

      else if (clsid == MWClassID.SINGLE)
      {
         float[][] x = (float[][])((MWArray)y[0]).toArray();

         /* (do something with x...) */
      }

      else if (clsid == MWClassID.INT32 || 
              clsid == MWClassID.UINT32)
      {
         int[][] x = (int[][])((MWArray)y[0]).toArray();

         /* (do something with x...) */
      }

      else if (clsid == MWClassID.INT64 || 
              clsid == MWClassID.UINT64)
      {
         long[][] x = (long[][])((MWArray)y[0]).toArray();

         /* (do something with x...) */
      }

      else if (clsid == MWClassID.INT16 || 
              clsid == MWClassID.UINT16)
      {
         short[][] x = (short[][])((MWArray)y[0]).toArray();

         /* (do something with x...) */
      }

      else if (clsid == MWClassID.INT8 || 
              clsid == MWClassID.UINT8)
      {
         byte[][] x = (byte[][])((MWArray)y[0]).toArray();

         /* (do something with x...) */
      }
   }
   finally
   {
      MWArray.disposeArray(y);
      if (cls != null)
         cls.dispose();
   }
}

Используйте toTypeArray Методы, чтобы Определить Тип и Размерность

Следующий пример демонстрирует, как можно принудить или обеспечить данные к заданному числовому типу путем вызова любого из toTypeArray методов. Эти методы возвращают массив элементов Java типа, заданного от имени вызываемого метода. Данные принуждены или обеспечены к типу примитива, заданному в имени метода. Обратите внимание на то, что при использовании этих методов, данные будут усеченными при необходимости, чтобы позволить соответствие заданному типу данных.

Object results = null;
try {
    // call a compiled MATLAB function
    results = myobject.myfunction(2);

    // first output is known to be a numeric matrix
    MWArray resultA = (MWNumericArray) results[0];
   double[][] a = (double[][]) resultA.toDoubleArray();

    // second output is known to be 
    //    a 3-dimensional numeric array
    MWArray resultB = (MWNumericArray) results[1];
   int[][][] b = (int[][][]) resultB.toIntArray();   
}
 finally {
    MWArray.disposeArray(results);
}