То, что я пытаюсь сделать, упрощено ниже.
- Java -> Вызов функции C ++ A
- Функция C ++ A вызывает функцию C ++ B
- C ++ функция B вызывает Java метод C
Мне нужно хранить JVM (2) и глобальный jobject (3).
Но в части 3,
JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception java.lang.NoSuchMethodError: no non-static method "Lpackage/name/here/d/b;.setInput([F)V"
Я всегда получал эту ошибку.
Код
Структура
- Оболочка. java
- native -lib. cpp
- Wrapper. cpp
** <-> означает связь
Другое Java Классы <-> Wrapper. java
Wrapper. java <-> native-lib. cpp
native-lib. cpp <-> Wrapper. cpp
Wrapper. cpp <-> Другие классы C ++
Wrapper. java
private static long wrapperAddr = 0; // initializes later
private tfModel model;
private native void nativeSetModel(long native_ptr, tfModel model);
public Wrapper(...){
...
model = tfModel.create(tfModel.Model.MNIST, tfModel.Device.CPU, 1);
nativeSetModel(wrapperAddr, model);
}
native-lib. cpp
extern "C" JNIEXPORT void JNICALL
Java_package_name_here_jni_Wrapper_nativeSetModel(JNIEnv *env,
jobject instance,
jlong native_ptr,
jobject model){
auto wrapper = reinterpret_cast<Wrapper *>(native_ptr);
wrapper->setModel(env, model);
}
Упаковщик. cpp
void setModel(JNIEnv *env, jobject _model){
env->GetJavaVM(&translater::jvm);
jobject gmodel = env->NewGlobalRef(_model);
translater::model = gmodel;
}
функция A
...
translater::setInputTS(input1, 100); // error starts here
...
translater.h / translater. cpp ( функция B )
class translater{
public:
inline static JavaVM *jvm = nullptr;
inline static jobject model = nullptr;
// from: https://stackoverflow.com/a/30026231/8176989
static bool GetJniEnv(JavaVM *vm, JNIEnv **env);
static void predictTS(std::vector<float> &output);
static void translater::setInputTS(float* input, int len) {
JNIEnv *env;
bool did_attach = GetJniEnv(jvm, &env);
if(did_attach){
jclass clazz = env->GetObjectClass(model);
jmethodID jid_input = env->GetMethodID(clazz, "setInput", "([F)V"); // Here is where error happens
}
...
};
tfModel. java
public abstract class tfModel{
...
public void setInput(float[] array){
if(inputIndex < inputImageNum)
setInput_Image(inputIndex, array);
else
setInput_Tensor(inputIndex - inputImageNum, array);
++inputIndex;
}
}
Как n Я правильно звоню jmethodID jid_input = env->GetMethodID(clazz, "setInput", "([F)V");
?