我在网上发现了很多帖子,但是他们似乎没有帮助我把它弄好......
我的问题是我想从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);
答案 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 。