2011-06-15 96 views
4

我今天用Android SDK創建了我的第一個Java本地調用。
我發現了幾個例子,但是與函數頭不一致。調用java方法

我總是

JNIEXPORT void JNICALL Java_com_test_Calculator_calcFileSha1 
    (JNIEnv *, jclass, jstring); 

使用,但我已經看到

JNIEXPORT void JNICALL Java_com_test_Calculator_calcFileSha1 
    (JNIEnv *, jobject, jstring); 

屬於頭是不同的是獲取類的調用者。
但是最好的方法是什麼?

從C++代碼中我想調用一個java方法。我找到了JNI文檔(Calling Instance Methods)。
但我不知道第一個參數(對象)應該是什麼。

我試圖給出我從本地方法的調用中獲得的類實例,它與AbstractMethodError失敗。

固定源代碼:

public class TestCalc extends Activity { 
    static { 
     System.loadLibrary("Test"); 
    } 

    private void setFilesize(long size) { 

    } 
} 

本地庫:

// header 
#ifdef __cplusplus 
extern "C" { 
#endif 
JNIEXPORT void JNICALL Java_com_test_TestCalc_calcFilesize 
    (JNIEnv *, jobject, jstring); 

    void setFilesize(const INT_64 size); 

#ifdef __cplusplus 
} 
#endif 

#endif 

// code 
JNIEnv * callEnv; 
jobject callObj; 


JNIEXPORT void JNICALL Java_com_test_SHA1Calc_calcFileSha1 
    (JNIEnv * env, jobject jobj, jstring file) 
{ 
    callEnv = env; 
    callObj = jobj; 

    [...] 
} 

    void setFilesize(const INT_64 size) { 
     jmethodID mid; 
     jclass cls; 

     cls=callEnv->FindClass("com/test/TestCalc");  
     mid=callEnv->GetMethodID(cls, "setFilesize", "(J)V"); 
     if (mid == 0) { 
     __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", "Cannot find method setFilesize"); 
     return; 
     } 

     callEnv->ExceptionClear(); 
     callEnv->CallVoidMethod(callObj, mid, size); 
     if(callEnv->ExceptionOccurred()) { 
     callEnv->ExceptionDescribe(); 
     callEnv->ExceptionClear(); 
     } 
    } 

感謝您的任何建議。

回答

0

jobject可以是任何java對象,而jclass應該是代表java.lang.Class的對象。在C API中,jobjectjclass是同樣的事情,而C++ API試圖強制執行類型安全並將它們聲明爲jclass繼承jobject的不同類型。第二個參數應該表示一個類,所以jclass是首選。即使在C中並不重要,如果您決定切換到C++,它可以暗示開發人員甚至節省您的時間。閱讀更多關於JNI類型here