我正在尝试在Android中运行一个简单的jni代码,但是我得到的是不满意的链接错误。
这是我的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");
}
}
这是My 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等示例代码运行绝对正常。
请告诉我我失踪的地方。
答案 0 :(得分:12)
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
,您将清楚地看到相同的功能,没有和名称损坏。
我希望这也可以帮助其他人解决同样的问题。
答案 1 :(得分:0)
这实际上并没有被称为非常正确......
尝试:
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
答案 2 :(得分:0)
我会给出另一个建议。我之前遇到了同样的错误,但我通过“Android Native Development Kit Cookbook”解决了这个问题。请注意这些陈述;
本机函数必须遵循包名,类名和方法名的特定模式。包和类名必须与调用本机方法的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");
}