在调用Android的Java方法从C ++ [英] Calling a java method from c++ in Android

查看:203
本文介绍了在调用Android的Java方法从C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  

对这个问题的解决方案是在问题的底部!


你好。我想从C得到一个简单的Java方法调用++而Java调用本地方法。所以,这里是java的code:

 公共类MainActivity延伸活动{
    私有静态字符串LIB_NAME =名;

    静态{
        的System.loadLibrary(LIB_NAME);
    }

    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        TextView的电视=(TextView中)findViewById(R.id.textview);
        tv.setText(this.getJniString());
    }

    公共无效messageMe(字符串文本){
        的System.out.println(文本);
    }

    公共本地字符串getJniString();
}
 

我试图调用 messageMe 从本地code方法的过程中的 getJniString 方法调用从Java到本机。

native.cpp:

 的#include< string.h中>
#包括< stdio.h中>
#包括< jni.h>

的jstring Java_the_package_MainActivity_getJniString(JNIEnv的* ENV,jobject OBJ,jint深度){

//的JavaVM *虚拟机;
// JNIEnv的* ENV;
// JavaVMInitArgs vm_args;
// vm_args.version = JNI_VERSION_1_2;
// vm_args.nOptions = 0;
// vm_args.ignoreUnrecognized = 1;
//
// //构造一个虚拟机
// jint解析度= JNI_CreateJavaVM(安培;虚拟机,(无效**)及包膜,&安培; vm_args);

    //创建一个字符串
    的jstring jstr = ENV-> NewStringUTF(此字符串来自JNI);
    //首先要获取包含您需要调用方法的类
    JCLASS clazz所= ENV->的findClass(下称/包/ MainActivity);
    //获取要调用的方法
    jmethodID messageMe = ENV->的GetMethodID(clazz中,messageMe,(Ljava /朗/字符串;)V);
    //调用对象的方法
    jobject结果= ENV-> CallObjectMethod(jstr,messageMe);
    //获取C风格的字符串
    为const char *海峡= ENV-> GetStringUTFChars((的jstring)结果,NULL);
    的printf(%S \ N,STR);
        // 清理
    ENV-> ReleaseStringUTFChars(jstr,STR);

// //关闭虚拟机。
// VM-> DestroyJavaVM();

    返回ENV-> NewStringUTF(你好来自JNI!);
}
 

在与下一个消息干净编译应用程序停止:

  ERROR / AndroidRuntime(742):致命异常:主要
        java.lang.NoSuchMethodError:messageMe
        在* .android.t3d.MainActivity.getJniString(本机方法)
        在* .android.t3d.MainActivity.onCreate(MainActivity.java:22)
 

显然,这意味着,方法名是错误的,但它看起来不错我。任何想法是值得欢迎的。

P.S:我不是一个C / C ++的家伙,还)


  

解决方案:

所以,我很搞砸了与C到C ++的转换(基本变量ENV的东西),但我得到了它的工作与下一code为C:

 的#include< string.h中>
#包括< stdio.h中>
#包括< jni.h>

的jstring Java_the_package_MainActivity_getJniString(JNIEnv的* ENV,jobject OBJ){

    的jstring jstr =(* ENV) - > NewStringUTF(ENV,这个来自JNI);
    JCLASS clazz所=(* ENV) - >的findClass(ENV,COM / inceptix /安卓/ T3D / MainActivity);
    jmethodID messageMe =(* ENV) - >的GetMethodID(ENV,clazz中,messageMe,(Ljava /朗/字符串;)Ljava /朗/字符串;);
    jobject结果=(* ENV) - > CallObjectMethod(ENV,OBJ,messageMe,jstr);

    为const char *海峡=(* ENV) - > GetStringUTFChars(ENV(的jstring)结果,NULL); //应该被释放,但什么赫克,这是一个教程:)
    的printf(%S \ N,STR);

    返回(* ENV) - > NewStringUTF(ENV,STR);
}
 

和下一个code的Java方法:

 公共类MainActivity延伸活动{
    私有静态字符串LIB_NAME =thelib;

    静态{
        的System.loadLibrary(LIB_NAME);
    }

    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        TextView的电视=(TextView中)findViewById(R.id.textview);
        tv.setText(this.getJniString());
    }

    //请让我活着,即使我用这个黑暗的编程技术
    公共字符串messageMe(字符串文本){
        的System.out.println(文本);
        返回文本;
    }

    公共本地字符串getJniString();
}
 

解决方案

这是一个对象的方法,所以我认为你需要的对象传递给 CallObjectMethod

  jobject导致= ENV-> CallObjectMethod(OBJ,messageMe,jstr);
 

你在做什么是相当于 jstr.messageMe()

修改 - 我才意识到,因为你是一个无效的方法,你应该叫:

ENV-> CallVoidMethod(OBJ,messageMe,jstr);

如果你想返回一个结果,你需要改变你的JNI的签名(即()V 表示无效返回类型),并在Java code中的返回类型。

THE SOLUTION TO THIS PROBLEM IS IN THE BOTTOM OF THE QUESTION!


Hi. I'm trying to get a simple java method call from c++ while java calls native method. So, here's the java code:

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();
}

I'm trying to call a messageMe method from native code in the process of getJniString method call from java to native.

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!");
}

After clean compilation app stops with next message:

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)

Apparently it means that method name is wrong, but it looks ok to me. Any ideas are welcome.

P.S.: I'm not a c/c++ guy, yet)


SOLUTION

So, I quite messed it up with c to c++ conversion (basically env variable stuff), but I got it working with next code for 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);
}

And next code for java methods:

    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();
}

解决方案

It's an object method, so I think you need to pass the object to CallObjectMethod:

jobject result = env->CallObjectMethod(obj, messageMe, jstr);

What you were doing was the equivalent of jstr.messageMe().

Edit - I just realized, since your is a void method, you should call:

env->CallVoidMethod(obj, messageMe, jstr);

If you want to return a result, you need to change your JNI signature (the ()V means a method of void return type) and also the return type in your Java code.

这篇关于在调用Android的Java方法从C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆