Mój kod rozpoczyna się w Javie, wywołuje C++, które następnie wywołuje Java powrotem do rzeczy jak znalezienie, uzyskiwanie i ustawienia wartości pól.
W przypadku gdy ktoś szuka C++ podejście znajdzie tej strony, będę orać na z tym:
Co mam teraz robić jest owijanie moje ciał metody JNI się z C++ try/bloku catch,
JNIEXPORT void JNICALL Java_com_pany_jni_JNIClass_something(JNIEnv* env, jobject self)
{
try
{
... do JNI stuff
// return something; if not void.
}
catch (PendingException e) // (Should be &e perhaps?)
{
/* any necessary clean-up */
}
}
gdzie PendingException deklaruje trywialnie:
class PendingException {};
i jestem powołując się następującą metodę po wywołaniu jakiegokolwiek JNI z C++, więc jeśli stan wyjątek Java wskazują s błąd, będę natychmiast ratować i niech normalne obsługa wyjątków Java dodać (metoda podstawowa) linię do śledzenia stosu, dając C++ możliwość oczyścić podczas odwijania:
PendingException PENDING_JNI_EXCEPTION;
void throwIfPendingException(JNIEnv* env)
{
if (env->ExceptionCheck()) {
throw PENDING_JNI_EXCEPTION;
}
}
Moje stosu Java ślad wygląda to dla nieudanej env-> GetFieldId() połączenia:
java.lang.NoSuchFieldError: no field with name='opaque' signature='J' in class Lcom/pany/jni/JniClass;
at com.pany.jni.JniClass.construct(Native Method)
at com.pany.jni.JniClass.doThing(JniClass.java:169)
at com.pany.jni.JniClass.access$1(JniClass.java:151)
at com.pany.jni.JniClass$2.onClick(JniClass.java:129)
at android.view.View.performClick(View.java:4084)
i dość podobny, jeśli zadzwonię do metody Java, który rzuca:
java.lang.RuntimeException: YouSuck
at com.pany.jni.JniClass.fail(JniClass.java:35)
at com.pany.jni.JniClass.getVersion(Native Method)
at com.pany.jni.JniClass.doThing(JniClass.java:172)
nie mogę mówić do owijania wyjątek Javy w innym wyjątku Java z C++, co moim zdaniem jest częścią twojego pytania - nie znalazłem potrzeby, aby to zrobić - ale gdybym to zrobił, zrobiłbym to za pomocą wrappera na poziomie Java dookoła natywne metody, lub po prostu poszerz moje metody rzucania wyjątków, aby wziąć jst i zastąpić połączenie env-> ThrowNew() czymś brzydkim: to niefortunne, że Sun nie dostarczył wersji ThrowNew, która zabrała jst.
void impendNewJniException(JNIEnv* env, const char *classNameNotSignature, const char *message)
{
jclass jClass = env->FindClass(classNameNotSignature);
throwIfPendingException(env);
env->ThrowNew(jClass, message);
}
void throwNewJniException(JNIEnv* env, const char* classNameNotSignature, const char* message)
{
impendNewJniException(env, classNameNotSignature, message);
throwIfPendingException(env);
}
nie uważam referencje buforowanie (wyjątek) Konstruktor klasy ponieważ wyjątki nie mają być zwykły mechanizm przepływu sterowania, więc to nie powinno mieć znaczenia, czy są wolne. Wyobrażam sobie, że look-up nie jest tak strasznie powolny, ponieważ Java prawdopodobnie robi własne buforowanie tego typu rzeczy.
Przez „uchwyty przykuty wyjątki:” Czy to znaczy, że Twój kod będzie zauważyć złapać wyjątek Java poziomu po powrocie z Java do C++, zawinąć go w jakimś innym wyjątku, i rzucać, że nowy wyjątek z powrotem z C++ do Java? –