2011-05-20 48 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