exponenta event banner

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

Формат

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

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

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

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

Использование MNUmericArray

Пример Magic Square (интеграция пакета 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 объект в скаляре MATLAB double для перехода к функции MATLAB.

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

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

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

  • Ява 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

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

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

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

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

Правила преобразования применяются не только при вызове собственных методов, но и при вызове конструкторов и заводских методов, принадлежащих 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 class method constructor, предоставление определенного типа данных приводит к преобразованию 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, то есть 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-й вектор равен 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 массив с треугольной структурой. Длина i4-я строка равна i. Такие массивы обычно называют зубчатыми массивами. Зазубренные массивы легко поддерживаются в Java, поскольку Java-матрица - это просто массив массивов.

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

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

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

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

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

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

Использование отражения 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.

Использование запроса MWAray для определения типа и размерности

В следующем примере используется 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Методы массива. Эти методы возвращают массив элементов 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);
}