Как передать массивы из Java в C ++ с помощью Swig? - PullRequest
9 голосов
/ 12 ноября 2010

У меня есть метод в C ++, который принимает массив значений типа double в качестве аргумента.Я вызываю этот метод из Java и должен передать массив значений типа double.Подпрограмма C ++ читает и изменяет значения массива, и мне нужны эти обновленные значения в Java.Как мне это сделать?

Например, возьмите подпрограмму C ++:

void myMethod( double *values, int size ) {
    for ( int i=0; i < size; i++ ) {
        values[i] = 2*values[i];
    }
}

И код Java:

double[] values = { 1.3, 1.1 };
myMethod(values,values.length);
System.out.println(values[0]); // prints 2.6

Я думаю, что вызов myMethod не можетбыть сделанным как звонок выше ... или это возможно?И что нужно в Swig, чтобы сделать эту работу.Если я не могу сделать вызов, подобный приведенному выше, как я могу получить свои значения в коде C ++?

Ответы [ 4 ]

8 голосов
/ 14 ноября 2010

Использовать carrays.i!

См. Документация Swig на каркасах

%include carrays.i
%array_functions( double, double_array )

Эти две строки создают следующий код в моем модуле:

 public static SWIGTYPE_p_double new_double_array(int nelements) {
    long cPtr = SimulatorModuleJNI.new_double_array(nelements);
    return (cPtr == 0) ? null : new SWIGTYPE_p_double(cPtr, false);
  }

  public static void delete_double_array(SWIGTYPE_p_double ary) {
    SimulatorModuleJNI.delete_double_array(SWIGTYPE_p_double.getCPtr(ary));
  }

  public static double double_array_getitem(SWIGTYPE_p_double ary, int index) {
    return SimulatorModuleJNI.double_array_getitem(SWIGTYPE_p_double.getCPtr(ary), index);
  }

  public static void double_array_setitem(SWIGTYPE_p_double ary, int index, double value) {
    SimulatorModuleJNI.double_array_setitem(SWIGTYPE_p_double.getCPtr(ary), index, value);
  }

Что позволяет мне использовать массивы C в Java ... это решает мои потребности и является лучшим решением для моей проблемы.Спасибо всем за ваши ответы!

1 голос
/ 12 ноября 2010

Карты типов SWIG должны позволять это. Документация SWIG 2.0 показывает этот пример на Python .

В Java вы будете использовать код JNI внутри вашей карты типов SWIG. JNI предоставляет методы Get / ReleaseArrayElements. Я предполагаю, что вы можете получить собственный массив в typemap(in), а затем выпустить его в typemap(argout).

Другой подход - скопировать ваш массив в std :: vector, используя существующую карту типов SWIG в std_vector.i.

0 голосов
/ 12 ноября 2010

Если это всего лишь один метод, перепишите его.Если у вас есть (намного) большая база кода C ++, которую вам нужно портировать, используйте JNI (или более простой JNA ).Это добавляет немного накладных расходов кода, но это выполнимо.

0 голосов
/ 12 ноября 2010

Предполагая, что вы не можете делать то, что предлагает org.life.java ...

Вы можете проверить IPC , а также файлы.

Другая вещь, которую вы можете сделать, - это создать процесс, передав ему путь к exe-файлу, содержащему код C ++ и массив в качестве аргумента. [Runtime.exec (java.lang.String, java.lang.String [])] [2] должно быть в состоянии сделать это.

[2]: http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Runtime.html#exec(java.lang.String, java.lang.String [])

...