Android и UnsatisfiedLinkError - PullRequest
1 голос
/ 20 мая 2011

У меня есть специфическая проблема с Android и библиотекой JNI, которую я использую.Библиотека JNI называется libBase.so и правильно включена в APK.Я могу сделать System.loadLibrary («База»), и библиотека загружается и может использоваться без каких-либо проблем.

Рассмотрим следующие фрагменты кода:

/* 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 и, следовательно, выполнение статического инициализатора NativeObject, который выполняет вызов System.LoadLibrary ().Непонятно, почему я получу вышеупомянутые сообщения 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");
    }
}

Itтакже работает, если я делаю это:

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

Любая помощь по этому вопросу будет принята с благодарностью.

ОБНОВЛЕНИЕ: Код родной стороны, который меня попросили, это:

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 Ответ

1 голос
/ 24 мая 2011

У вас есть две дополнительные скобки при инициализации массива JNINativeMethod, этот код не должен компилироваться.

Проверьте код возврата RegisterNatives (), в случае успеха он должен быть равен нулю.

Также, если вы компилируете код C ++, вы должны объявить нативные методы extern "C", чтобы избежать их искажения.

...