Передайте аргументы на и с 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);

Мост Java преобразует MWNumericArray объект для скалярного double MATLAB для перехода к функции MATLAB.

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

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

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

  • A 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 1 на 1 double массив.

Передача объекта Java Double

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

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

Этот второй аргумент преобразуется в MATLAB 1 на 1 double массив, как требуется функцией 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 объект для скалярного double MATLAB для перехода к функции 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 1 на 1 double массив.

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

Array A is of type double

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

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

Для примера в следующем фрагменте кода код задает, что A должно быть построено как 16-битный целочисленный массив MATLAB 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 векторы такие, что длина ith вектор равен 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();
   }
}

The getrandvectors метод возвращает двумерное double массив с треугольной структурой. Длина iвторая строка равна i. Такие массивы обычно называются зубчатыми массивами. Jagged arrays легко поддерживаются в Java, потому что Java- матрица - это всего лишь массив массивов.

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

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

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

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

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

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

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

Эта выборка кода вызывает 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. The toArray метод работает так же, как getData в предыдущих примерах, за исключением того, что возвращенный массив имеет ту же размерность, что и базовый массив MATLAB.

Используйте запрос MWArray для определения типа и размерности

В следующем примере используется MWArray classID метод для определения типа базового массива 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 для определения типа и размерности

Следующий пример демонстрирует, как можно принудительно или принудительно преобразовать данные в заданный числовой тип путем вызова любого из TypeМетоды Array. Эти методы возвращают массив элементов 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);
}