【问题标题】:Unsatisfiedlinkerror in android (eclipse)android(eclipse)中的Unsatisfiedlinkerror
【发布时间】:2011-06-14 21:22:18
【问题描述】:

我正在尝试在 Android 中运行一个简单的 jni 代码,但我得到的只是 Unsatisfiedlinkerror 。

这是我的 Java 代码:

package com.lipcap;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
/** Called when the activity is first created. */

TextView a;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    a=new TextView(this);

    String b; 
    MainActivity ob=new MainActivity();
    b=ob.sniff();

    a.setText(b);

    setContentView(a);
}
public native String sniff();

    static{
        System.loadLibrary("native");
    }


} 

这是我的 C++ 代码(在 $PROJECT_PATH/jni/ 中):

#include<iostream>
#include<string.h>
#include<jni.h>
JNIEXPORT jstring JNICALL Java_com_lipcap_MainActivity_sniff
(JNIEnv *env, jobject obj){
       return env->NewStringUTF("This is Native");
}

我已经使用 javac 编译了 java 代码,并使用 javah 制作了标头。

然后我运行 ndk-build。 然后我从eclipse运行代码。(在android中安装了apk)。

我收到此错误:

E/AndroidRuntime(  769): FATAL EXCEPTION: main
E/AndroidRuntime(  769): java.lang.UnsatisfiedLinkError: sniff
E/AndroidRuntime(  769):    at com.lipcap.MainActivity.sniff(Native Method)
E/AndroidRuntime(  769):    at com.lipcap.MainActivity.onCreate(MainActivity.java:36)
E/AndroidRuntime(  769):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime(  769):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
E/AndroidRuntime(  769):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
E/AndroidRuntime(  769):    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
E/AndroidRuntime(  769):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
E/AndroidRuntime(  769):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(  769):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(  769):    at android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime(  769):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  769):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(  769):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
E/AndroidRuntime(  769):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
E/AndroidRuntime(  769):    at dalvik.system.NativeStart.main(Native Method)

我没有设置 LD_LIBRARY_PATH。

但是,如果不设置 LD_LIBRARY_PATH 示例代码,例如 NDK 提供的 HelloJNI,运行绝对可以。

请告诉我我在哪里失踪。

【问题讨论】:

  • MainActivity ob=new MainActivity(); 为什么?您已经进入 MainActivity 的一个实例。必须使用this.sniff()
  • 是的,this.sniff 可以使用。无论如何,就 Unsatisfiedlinkerror 而言,这不会产生任何差异。
  • 将代码从 C++ 更改为 C 一切正常.. :)

标签: android eclipse java-native-interface android-ndk


【解决方案1】:

您提到的 Richard-head:“将代码从 C++ 更改为 C 一切正常”...

我被完全相同的问题折磨了好几天,我确实确保我输入的所有内容(命名、Android.mk 等)都没有问题。每当在C中,我都很好。只要我换成cpp,UnsatisfiedLinkError.

我终于从这个链接中得到了提示: http://markmail.org/message/fhbnprmp2m7ju6lc

这完全是因为 C++ 名称错误!同样的函数,如果你在.cpp文件中没有extern "C"包围它,名字就会被破坏,所以JNI找不到函数名所以UnsatisfiedLinkError会弹出。

在你的函数周围放置和移除extern "C" { },运行nm obj/local/armeabi/libnative.so,你会清楚地看到相同的函数没有和有名称修改。

我希望这也能帮助其他有同样问题的人。

【讨论】:

    【解决方案2】:

    这确实不是很正确......

    试试:

    package com.lipcap;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
        /** Called when the activity is first created. */
    
        TextView a;
    
        public native String sniff();
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            a=new TextView(this);
    
            String b = sniff(); 
    
            a.setText(b);
    
            setContentView(a);
        }
    
        static{
            System.loadLibrary("native");
        }
    
    }
    

    最后...这是在您的 Android.mk 中吗?

    LOCAL_MODULE    := native
    

    【讨论】:

    • 检查编辑... Android.mk 中的模块名称应与您正在加载的库名称匹配。
    • 此外,Java 中的声明顺序并不重要。
    • 是的.. 这是我的 Android.mk LOCAL_MODULE := native
    【解决方案3】:

    我会给出另一个建议。我之前也遇到过同样的错误,但我通过“Android Native Development Kit Cookbook”解决了这个问题。请注意这些陈述;

    native 函数必须遵循包名、类名和方法名的特定模式。包和类名必须与调用本地方法的 Java 类的包和类名一致, 而方法名必须与该 Java 类中声明的方法名相同。 这有助于 Dalvik VM 在运行时定位原生函数。不遵守规则将导致运行时出现 UnsatisfiedLinkError。

    以上举例

    您需要更改您的函数名称,例如(如果您专注于 NDK,请不要在包名称中使用 com.bla)

    #include<iostream>
    #include<string.h>
    #include<jni.h>
    
    JNIEXPORT jstring JNICALL Java_lipcap_example_MainActivity_sniff
    (JNIEnv *env, jobject obj){
           return env->NewStringUTF("This is Native");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-04
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      相关资源
      最近更新 更多