从c ++(jni)调用java函数根本不起作用

时间:2013-03-25 18:58:26

标签: java android c++ android-ndk java-native-interface

我在网上发现了很多帖子,但是他们似乎没有帮助我把它弄好......

我的问题是我想从ndk c ++部分调用android java函数..

当我上课时:

jclass icls = jenv->GetObjectClass(obj);

我收到此错误: E / AndroidRuntime(27397):java.lang.NoSuchMethodError:类Ljava / lang / Class中没有name ='setValues'cignra ='()V'的方法; => jmid == 0

当我用“FindClass”调用它时,我得到此错误: A / libc(26692):致命信号11(SIGSEGV)位于0x00000004(代码= 1),线程26743(Thread-8302)

findclass和方法似乎有用(!= 0)所以 obj 会出现问题吗?

任何? Thx提前..

JAVA - 主要类别:

package com.new.test;
class Test{
   public Test(Context context, AttributeSet attrs) {
        super(context, attrs);
        run();
   }

   run(){
         int x = 10;
         new DoStuff(x);
   }
   public void setValues(){     
       Log.e("","SET VALUES");
   }
}

JAVA 2 JNI:

public class DoStuff{   
    public DoStuff(int x){
        nativeDoStuff(x);
    }

    private static native long nativeDoStuff(int x);

    static{
        System.loadLibrary("do_stuff");
    }
}

C ++:cpp

JNIEXPORT void JNICALL Java_com_new_test_DoStuff_nativeDoStuff (JNIEnv * jenv, jobject obj, jint x){

    jclass icls = jenv->FindClass("com/new/test/Test");
    //jclass icls = jenv->GetObjectClass(obj);
    jmethodID jmid = jenv->GetMethodID(icls, "setValues","()V");
    jenv->CallVoidMethod(obj,jmid);

}

C ++:h

JNIEXPORT void JNICALL Java_com_new_test_DoStuff_nativeDoStuff (JNIEnv *, jobject, jint);

3 个答案:

答案 0 :(得分:2)

如果我正确地阅读此内容,在这种情况下,“obj”将指向DoStuff对象,而不是Test对象。所以你试图在一个不包含这个方法的对象上调用你的setValues方法。您应该使您的本机方法成为Test的成员,或者将Test的实例传递给该函数。

答案 1 :(得分:2)

方法Test.setValues()是一个实例方法 - 它需要一个有效的Test对象来执行。同时,方法nativeDoStuff没有。它是一个静态方法,它所有的(作为第二个参数)是类DoStuff的类对象。您错误地将该类指针作为指向this的{​​{1}}指针传递 - 这是致命的错误。

将所有内容移动到一个类(CallVoidMethod()Test,无关紧要)并在Java端将DoStuff声明为非静态。或者将nativeDoStuff()本身设为静态,并使用doStuff()作为最后一行。

答案 2 :(得分:0)

尝试更改

中的空格
JNIEXPORT void JNICALL Java_com ...

jlong​​