Reputation: 33
I have error while trying invoke java method from native code.
[arm64-v8a] Compile++ : hell <= hell.cpp
/home/zns/AndroidStudioProjects/Test/app/src/main/jni/hell.cpp: In function 'int main()':
/home/zns/AndroidStudioProjects/Test/app/src/main/jni/hell.cpp:8:42: error: 'JNI_CreateJavaVM' was not declared in this scope
JNI_CreateJavaVM(&jvm, &env, &vm_args);
^
make: *** [/home/zns/AndroidStudioProjects/Test/app/src/main/obj/local/arm64-v8a/objs/hell/hell.o] Error 1
hell.cpp
#include <string.h>
#include <jni.h>
int main(){
JavaVM *jvm; /* denotes a Java VM */
JNIEnv *env; /* pointer to native method interface */
JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
vm_args.version = JNI_VERSION_1_6;
JNI_CreateJavaVM(&jvm, &env, &vm_args);
jclass cls = env->FindClass("MainActivity");
jmethodID mid = env->GetStaticMethodID(cls, "test", "()V");
env->CallStaticVoidMethod(cls, mid, 100);
jvm->DestroyJavaVM();
}
extern "C" {
jstring
Java_com_oxide_app_MainActivity_stringFromJNI
(JNIEnv *env, jobject obj)
{
main();
return env->NewStringUTF("Hello from C++ over JNI!");
}
}
MainActivity.java
public class MainActivity extends ActionBarActivity {
static{
System.loadLibrary("hell");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = new TextView(this);
tv.setText(stringFromJNI());
setContentView(tv);
}
public native String stringFromJNI();
public void test(){
Log.d("NATIVE", "WHOA");
}
}
OS: linux;
jdk:/opt/icedtea-bin-6.1.12.7/;
P.S. I have seen two similar questions, but they did not help to solve the problem Calling a JAVA method from C++ with JNI, no parameters Using JNI to execute a java jar from a C++ program, using g++ or eclipse
Upvotes: 3
Views: 1902
Reputation: 2145
From the NDK's jni.h
#if 0 /* In practice, these are not exported by the NDK so don't declare them */
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
#endif
As the only supported way to use the NDK is from a Java application so the Java JM is already loaded.
I think you should remove your main
function and look into replacing it with JNI_OnLoad
and remove the calls to control the VM's lifetime.
Upvotes: 1