Фильтр ArrayList [дубликат]

Это дополнение к ответу Эллиотта Хьюза . Мой ответ содержит пошаговый пример, объясняющий, как перехватывать исключения и как их переводить между словами C ++ и Java, используя слой JNI .

Короткий ответ

См. правильный ответ Эллиотта Хьюза .

Пример повторного использования

Этот ответ и фрагменты находятся в открытом доступе или в CC0, чтобы облегчить повторное использование. Весь исходный код здесь является совместимым с C ++ 03.

Чтобы повторно использовать приведенный выше фрагмент, сделайте следующее:

  • Замените mypackage::Exception своим собственным Исключением на C ++.
  • Если соответствующее исключение Java my.group.mypackage.Exception не определено, замените "my/group/mypackage/Exception" на "java/lang/RuntimeException".

Исключить исключения из Java

См. Также фрагмент на coliru .

void rethrow_cpp_exception_as_java_exception()
{
  try
  {
    throw; // This allows to determine the type of the exception
  }
  catch (const mypackage::Exception& e) {
    jclass jc = env->FindClass("my/group/mypackage/Exception");
    if(jc) env->ThrowNew (jc, e.what());
    /* if null => NoClassDefFoundError already thrown */
  }
  catch (const std::bad_alloc& e) {
    jclass jc = env->FindClass("java/lang/OutOfMemoryError");
    if(jc) env->ThrowNew (jc, e.what());
  }
  catch (const std::ios_base::failure& e) {
    jclass jc = env->FindClass("java/io/IOException");
    if(jc) env->ThrowNew (jc, e.what());                          
  }                                                               
  catch (const std::exception& e) {
    /* unknown exception (may derive from std::exception) */
    jclass jc = env->FindClass("java/lang/Error");
    if(jc) env->ThrowNew (jc, e.what());
  }
  catch (...) {
    /* Oops I missed identifying this exception! */
    jclass jc = env->FindClass("java/lang/Error");
    if(jc) env->ThrowNew (jc, "Unidentified exception => "
      "Improve rethrow_cpp_exception_as_java_exception()" );
  }
}

Я благодарю Mooing Duck за вклад в код C ++.

] Адаптировать исходный код JNI

В следующем файле Java_my_group_mypackage_example.cpp используется вышеупомянутая функция rethrow_cpp_exception_as_java_exception():

JNIEXPORT jlong JNICALL Java_my_group_mypackage_example_function1
        (JNIEnv *env, jobject object, jlong value)
{
  try {
    /* ... my processing ... */
    return jlong(result);
  } catch(...) {
    rethrow_cpp_exception_as_java_exception();
    return 0;
  }
}

JNIEXPORT jstring JNICALL Java_my_group_mypackage_example_function2
        (JNIEnv *env, jobject object, jlong value)
{
  jstring jstr = 0
  try {
    /* ... my processing ... */
    jstr = env->NewStringUTF("my result");
  } catch(...) {
    rethrow_cpp_exception_as_java_exception();
  }
  return  jstr;
}

JNIEXPORT void JNICALL Java_my_group_mypackage_example_function3
        (JNIEnv *env, jobject object, jlong value)
{
  try {
    /* ... my processing ... */
  } catch(...) {
    rethrow_cpp_exception_as_java_exception();
  }
}

Соответствующий код Java

Файл example.java

package my.group.mypackage;

public class Example {
  static {
    System.loadLibrary("my-DLL-name");
  }

  public Example() {
    /* ... */
  }

  private native int    function1(int); //declare DLL functions
  private native String function2(int); //using the keyword
  private native void   function3(int); //'native'

  public void dosomething(int value) {
    int result = function1(value);  
    String str = function2(value);  //call your DLL functions
    function3(value);               //as any other java function
  }
}

Примечание: «my-DLL-name» относится к динамической библиотеке, созданной из приведенного выше кода на C / C ++. Это может быть my-DLL-name.dll в Windows или my-DLL-name.so в GNU / Linux / Unix.

Шаги

  1. Сгенерировать example.class из example.java (используя javac или maven или ваш любимый IDE Eclipse / Netbeans / IntelliJ IDEA /...)
  2. Сгенерировать заголовочный файл C / C ++ Java_my_group_mypackage_example.h из example.class с помощью javah

37
задан Mark 5 February 2012 в 13:21
поделиться