LA SOLUTION À CE PROBLÈME EST DANS LE FOND DE LA QUESTION!
Salut. Je vais essayer d'obtenir un java simple appel de méthode à partir de c++ alors que java appels de méthode native. Donc, voici le code java:
public class MainActivity extends Activity { private static String LIB_NAME = "name"; static { System.loadLibrary(LIB_NAME); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = (TextView) findViewById(R.id.textview); tv.setText(this.getJniString()); } public void messageMe(String text) { System.out.println(text); } public native String getJniString(); }
Je suis en train d'appeler un messageMe méthode de code natif dans le processus de getJniString appel de méthode à partir de java natif.
native.cpp:
#include <string.h> #include <stdio.h> #include <jni.h> jstring Java_the_package_MainActivity_getJniString( JNIEnv* env, jobject obj, jint depth ){ // JavaVM *vm; // JNIEnv *env; // JavaVMInitArgs vm_args; // vm_args.version = JNI_VERSION_1_2; // vm_args.nOptions = 0; // vm_args.ignoreUnrecognized = 1; // // // Construct a VM // jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args); // Construct a String jstring jstr = env->NewStringUTF("This string comes from JNI"); // First get the class that contains the method you need to call jclass clazz = env->FindClass("the/package/MainActivity"); // Get the method that you want to call jmethodID messageMe = env->GetMethodID(clazz, "messageMe", "(Ljava/lang/String;)V"); // Call the method on the object jobject result = env->CallObjectMethod(jstr, messageMe); // Get a C-style string const char* str = env->GetStringUTFChars((jstring) result, NULL); printf("%s\n", str); // Clean up env->ReleaseStringUTFChars(jstr, str); // // Shutdown the VM. // vm->DestroyJavaVM(); return env->NewStringUTF("Hello from JNI!"); }
Après le nettoyage de compilation de l'application s'arrête avec le message suivant:
ERROR/AndroidRuntime(742): FATAL EXCEPTION: main java.lang.NoSuchMethodError: messageMe at *.android.t3d.MainActivity.getJniString(Native Method) at *.android.t3d.MainActivity.onCreate(MainActivity.java:22)
Apparemment, il signifie que le nom de la méthode est mauvaise, mais il semble ok pour moi. Toutes les idées sont les bienvenue.
P. S.: je ne suis pas un c/c++ gars, encore)
SOLUTION
Donc, j'ai tout gâché avec de c à c++ de conversion (en gros env variable genre de trucs), mais je l'ai eu à travailler avec du code c:
#include <string.h> #include <stdio.h> #include <jni.h> jstring Java_the_package_MainActivity_getJniString( JNIEnv* env, jobject obj){ jstring jstr = (*env)->NewStringUTF(env, "This comes from jni."); jclass clazz = (*env)->FindClass(env, "com/inceptix/android/t3d/MainActivity"); jmethodID messageMe = (*env)->GetMethodID(env, clazz, "messageMe", "(Ljava/lang/String;)Ljava/lang/String;"); jobject result = (*env)->CallObjectMethod(env, obj, messageMe, jstr); const char* str = (*env)->GetStringUTFChars(env,(jstring) result, NULL); // should be released but what a heck, it's a tutorial :) printf("%s\n", str); return (*env)->NewStringUTF(env, str); }
Et suivant le code pour les méthodes de java:
public class MainActivity extends Activity { private static String LIB_NAME = "thelib"; static { System.loadLibrary(LIB_NAME); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView tv = (TextView) findViewById(R.id.textview); tv.setText(this.getJniString()); } // please, let me live even though I used this dark programming technique public String messageMe(String text) { System.out.println(text); return text; } public native String getJniString(); }
Réponses
Trop de publicités?C'est une méthode de l'objet, donc je pense que vous avez besoin de passer l'objet à l' CallObjectMethod
:
jobject result = env->CallObjectMethod(obj, messageMe, jstr);
Ce que vous faisiez était l'équivalent d' jstr.messageMe()
.
Edit - je viens de réaliser, depuis votre est une méthode void, vous devriez appeler:
env->CallVoidMethod(obj, messageMe, jstr);
Si vous souhaitez retourner un résultat, vous avez besoin de changer votre JNI signature ( ()V
moyen d'une méthode de void
type de retour) et également le type de retour dans votre code Java.
Vous pouvez apprendre à bien appeler des méthodes java à partir du code natif ici: http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html
Vous pouvez en savoir plus sur global de la JNI de programmation avec ce joli tutoriel: http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/index.html