2013-03-25 82 views
2

工作我已經發現了很多帖子在網上,但他們不似乎幫助我得到它的權利..調用從C++(JNI)的Java功能不包括在所有

我的問題是,我想調用距離NDK C++一部分的Android的Java功能..

當我拿到類:

jclass icls = jenv->GetObjectClass(obj); 

我得到這個錯誤: E/AndroidRuntime(27397):java.lang.NoSuchMethodError :在類Ljava/lang/Class中沒有name ='setValues'簽名='()V'的方法; => jmid == 0

當我這樣稱呼它下面「findClass的」我得到這個錯誤:A/libc的(26692):在0x00000004致命信號11(SIGSEGV)(代碼= 1) ,螺紋26743(螺紋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); 

回答

2

方法Test.setValues()是一個實例方法 - 它需要一個有效的Test對象來執行。同時,方法nativeDoStuff沒有一個。這是一個靜態方法,它所有的(作爲第二個參數)是類DoStuff的類對象。您錯誤地將該指針作爲this指針傳遞給CallVoidMethod() - 這是致命的錯誤。

將所有內容都移動到一個類中(TestDoStuff,無關緊要),並將其宣佈爲nativeDoStuff()在Java端非靜態。或者使doStuff()本身爲靜態,並使用jenv->CallStaticVoidMethod()作爲最後一行。

+0

THX很多!從來沒有想過這件事,因爲它以前工作過(當然,因爲我哈哈d沒有使用obj)。 我將所有內容都移動到了Test並從nativeDoStuff()中移除了靜態。這是否有任何缺點?我用它使靜態,因爲它是這樣的opencv。 – ddd 2013-03-26 09:38:36

+0

靜態方法的調用開銷略少(不要傳遞'this')。但是在某些時候,您可能需要'this'來回調Java。你的來電。 – 2013-03-26 14:50:49

2

如果我正確地閱讀它,在這種情況下,「obj」將指向DoStuff對象,而不是Test對象。所以你試圖在不包含這個方法的對象上調用你的setValues方法。您應該讓您的本地方法成爲Test的成員,或者將Test的實例傳遞給函數。

+0

確定ic ..但我也試圖把「setValues」函數放在「DoStuff」類中,它沒有解決..應該不是那麼正確嗎?或者你可以給我一個例子如何通過實例? – ddd 2013-03-25 19:19:24

+0

我已經把setValues放在DoStuff中並且得到這個錯誤: *「E/dalvikvm(31575):JNI ERROR(應用程序bug):訪問過時的全局引用0x341c3722(索引3528在139表中) E/dalvikvm (代碼= 1),線程31636(線程-8398)「致命信號11(SIGSEGV)」* – ddd 2013-03-25 19:23:15

+0

我添加(並將所有obj更改爲javaObj):jobject javaObj = jenv-> NewGlobalRef(obj );但我似乎並沒有伎倆 致命信號11(SIGSEGV)在0xdeadd00d(代碼= 1),線程31636(線程-8398)「* – ddd 2013-03-25 19:35:13

0

嘗試在改變無效:

JNIEXPORT void JNICALL Java_com ... 

jlong​​

+0

thx,但我沒有返回任何東西(我會說)..塞瓦的答案似乎現在工作。 – ddd 2013-03-26 09:40:36