2011-05-20 71 views
1

我有一個Android和我正在使用的JNI庫的特殊問題。 JNI庫名爲libBase.so,並且已正確包含在APK中。我能夠做System.loadLibrary(「基地」)和圖書館得到加載,可以毫無問題地使用。Android和UnsatisfiedLinkError

考慮下面的代碼片段:

/* NativeObject.java */ 
public class NativeObject 
{ 
    /* ... */ 
    static 
    { 
     System.loadLibrary("Base"); 
    } 
} 

/* ObjectUtil.java */ 
public class ObjectUtil 
{ 
    public static native NativeObject readNative(String path); 
    public static native void writeNative(String path, NativeObject obj); 
} 

當我試圖在我的程序的開始做ObjectUtil.readNative(),我得到的logcat以下問題:

05-19 18:57:38.508: WARN/dalvikvm(365): No implementation found for native Lcom/navimatics/base/ObjectUtil;.readNative (Ljava/lang/String;)Lcom/navimatics/base/NativeObject; 
05-19 18:59:15.409: ERROR/AndroidRuntime(365): java.lang.UnsatisfiedLinkError: readNative 

我理解是因爲ObjectUtil類引用了NativeObject,因此加載ObjectUtil類應強制加載NativeObject類,從而執行執行System.LoadLibrary()調用的NativeObject靜態初始化程序。現在還不清楚爲什麼我會得到上述的logcat消息。

但是如果我修改ObjectUtil.java內容如下並無異常,程序的工作原理:

/* ObjectUtil.java */ 
public class ObjectUtil 
{ 
    public static native NativeObject readNative(String path); 
    public static native void writeNative(String path, NativeObject obj); 
    static 
    { 
     System.loadLibrary("Base"); 
    } 
} 

如果我這樣做它也適用:

/* ObjectUtil.java */ 
public class ObjectUtil extends NativeObject 
{ 
    public static native NativeObject readNative(String path); 
    public static native void writeNative(String path, NativeObject obj); 
} 

任何幫助將不勝感激。

UPDATE: 本機端的代碼,我問的是:

static jobject JNICALL readNative(JNIEnv *env, jclass jcls, jstring jpath) 
{ 
    // ... 
} 
static void JNICALL writeNative(JNIEnv *env, jclass jcls, jstring jpath, jobject jobj) 
{ 
    // ... 
} 

static JNINativeMethod methods[] = 
{ 
    { "readNative", "(Ljava/lang/String;)Lcom/navimatics/base/NativeObject;", readNative }, 
    { "writeNative", "(Ljava/lang/String;Lcom/navimatics/base/NativeObject;)V", writeNative }, 
}; 

的方法註冊使用JNIEnv.RegisterNatives()。

+1

你還沒有提供本地聲明的代碼,並且答案在於 – ognian 2011-05-20 20:15:34

+0

根據請求添加的代碼。 – 2011-05-23 22:01:01

回答

1

在初始化JNINativeMethod數組時,你有兩個額外的括號,這段代碼不應該編譯。

檢查RegisterNatives()的返回碼,它在成功時應爲零。

另外,如果您正在編譯C++代碼,則應聲明本機方法extern "C"以避免使它們變形。

+0

奧尼安,你是對的括號。但是原始代碼中不存在額外的括號。原始代碼包含許多手動擴展的宏,因此您看到了這些問題。現在修復。 – 2011-05-25 00:54:23

+0

但我不同意關於外部「C」的觀察。回想一下RegisterNatives()註冊函數指針。這些靜態函數的名稱不相關。 – 2011-05-25 00:58:30

+0

你對「extern」C「'說得對。你是否檢查過RegisterNatives的返回值,它們是否被成功註冊? – ognian 2011-05-25 04:35:59