【问题标题】:unsatisfied link error in android native callandroid本机调用中的不满意链接错误
【发布时间】:2014-09-26 06:51:50
【问题描述】:

我正在尝试从 android 活动类中调用本机函数,这会导致不满意的链接错误。这是活动。

package com.example.rockboos;
import android.os.Bundle;

import android.app.Activity;
import android.widget.Button;
import android.widget.Toast;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {


    public native void hello();
    private void boostMe() 
    {
        hello();
    }

    private VolumeController volumeController;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.volumeController = new VolumeController(this);
        Button btn = (Button)findViewById(R.id.btn0);
        btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                    //volumeController.boost();
                boostMe();




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

    }

}

native.h

#include <jni.h>

JNIEXPORT void JNICALL Java_com_example_rockboost_MainActivity_hello(JNIEnv *, jobject);

native.c:

#include "mp3gain/mp3gain.h"

#include "native.h"

JNIEXPORT void JNICALL Java_com_example_rockboost_MainActivity_hello(JNIEnv *jniEnv, jobject thiz)
{
    //changeGain("/sdcard0/test.mp3", 10, 10);
    int x = 0;
    x++;
}

目录

08-03 17:58:54.040: D/dalvikvm(4007): 试图加载 lib /data/app-lib/com.example.rockboost-1/libhellomodule.so 0xb1c88e70

08-03 17:58:54.050: D/dalvikvm(4007): 添加共享库 /data/app-lib/com.example.rockboost-1/libhellomodule.so 0xb1c88e70

08-03 17:58:54.050: D/dalvikvm(4007): 在 /data/app-lib/com.example.rockboost-1/libhellomodule.so 0xb1c88e70 中找不到 JNI_OnLoad,跳过初始化

08-03 17:58:55.700:D/gralloc_goldfish(4007):没有检测到 GPU 仿真的仿真器。 08-03 17:59:15.040: W/dalvikvm(4007): 找不到本地 Lcom/example/rockboost/MainActivity 的实现;.hello:()V

08-03 17:59:15.050: D/AndroidRuntime(4007): 关闭 VM 08-03 17:59:15.050: W/dalvikvm(4007): threadid=1: 线程以未捕获的异常退出 (group=0xb1a4ed70)

08-03 17:59:15.130:E/AndroidRuntime(4007):致命异常:主要

08-03 17:59:15.130:E/AndroidRuntime(4007):进程:com.example.rockboost,PID:4007

08-03 17:59:15.130:E/AndroidRuntime(4007):java.lang.UnsatisfiedLinkError:找不到本机方法:com.example.rockboost.MainActivity.hello:()V

08-03 17:59:15.130: E/AndroidRuntime(4007): 在 com.example.rockboost.MainActivity.hello(本机方法) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 com.example.rockboost.MainActivity.boostMe(MainActivity.java:17) 08-03 17:59:15.130: E/AndroidRuntime(4007): at com.example.rockboost.MainActivity.access$0(MainActivity.java:15) 08-03 17:59:15.130: E/AndroidRuntime(4007): at com.example.rockboost.MainActivity$1.onClick(MainActivity.java:35) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 android.view.View.performClick(View.java:4450) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 android.view.View$PerformClick.run(View.java:18600) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 android.os.Handler.handleCallback(Handler.java:733) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 android.os.Handler.dispatchMessage(Handler.java:95) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 android.os.Looper.loop(Looper.java:136) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 android.app.ActivityThread.main(ActivityThread.java:5026) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 java.lang.reflect.Method.invokeNative(Native Method) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 java.lang.reflect.Method.invoke(Method.java:515) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777) 08-03 17:59:15.130: E/AndroidRuntime(4007): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602) 08-03 17:59:15.130: E/AndroidRuntime(4007): at dalvik.system.NativeStart.main(Native Method) 08-03 18:04:16.680: I/Process(4007): 发送信号。 PID:4007 SIG:9 08-03 18:24:16.030: D/dalvikvm(5266): 试图加载 lib /data/app-lib/com.example.rockboost-2/libhellomodule.so 0xb1c89f18 08-03 18:24:16.410: D/dalvikvm(5266): 添加共享库 /data/app-lib/com.example.rockboost-2/libhellomodule.so 0xb1c89f18 08-03 18:24:16.410: D/dalvikvm(5266): 在 /data/app-lib/com.example.rockboost-2/libhellomodule.so 0xb1c89f18 中找不到 JNI_OnLoad,跳过初始化 08-03 18:24:17.330:D/gralloc_goldfish(5266):没有检测到 GPU 仿真的仿真器。

08-03 17:58:54.040: D/dalvikvm(4007): 试图加载 lib /data/app-lib/com.example.rockboost-1/libhellomodule.so 0xb1c88e70 08-03 17:58:54.050: D/dalvikvm(4007): 添加共享库 /data/app-lib/com.example.rockboost-1/libhellomodule.so 0xb1c88e70 08-03 17:58:54.050: D/dalvikvm(4007): 在 /data/app-lib/com.example.rockboost-1/libhellomodule.so 0xb1c88e70 中找不到 JNI_OnLoad,跳过初始化 08-03 17:59:15.040: W/dalvikvm(4007): 找不到本地 Lcom/example/rockboost/MainActivity 的实现;.hello:()V

库编译。我可以在日志中看到可以加载共享库。 但是本机调用不起作用并导致不满意的链接错误

据我所知,命名约定似乎很好。我可以启动应用程序,该错误仅在调用本机函数时发生。我还确保该库是为正确的 cpu/架构构建的,

更新

我运行了 objdump -t 来检查符号表:

$ objdump.exe -t libhellomodule.so

libhellomodule.so:     file format elf32-little

SYMBOL TABLE:
no symbols

所以函数不在库中,但我不知道为什么。 这是我的 Android.mk 文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDLIBS := -llog

LOCAL_MODULE    := hellomodule
LOCAL_SRC_FILES := mp3gain mp3gain/mpglibDBL  

LOCAL_C_INCLUDE :=  mp3gain mp3gain/mpglibDBL native.h


APP_ABI := armeabi

include $(BUILD_SHARED_LIBRARY)

这可能有问题,但我不确定在哪里。

更新 2

修复了我的 Android.mk 并使用了另一个库

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mp3lame
LOCAL_SRC_FILES := bitstream.c fft.c id3tag.c mpglib_interface.c presets.c quantize.c reservoir.c tables.c util.c VbrTag.c encoder.c gain_analysis.c lame.c newmdct.c psymodel.c quantize_pvt.c set_get.c takehiro.c vbrquantize.c version.c native.c   


include $(BUILD_SHARED_LIBRARY)

编译正常,但结果相同,程序在库中找不到函数。尽管 nm 表明该符号在那里:

$ nm -D ../libs/armeabi/libmp3lame.so | grep hello
0001c4e9 T Java_com_example_rockboost_MainActivity_hello

【问题讨论】:

  • 如果没有您的最新更改,安装的库是否有可能是“陈旧”的库?您可以清理项目并重新部署。您还可以使用 ndk 的 objdump 来确保该函数确实在 .so 中(可能是您可以使用 zip 文件工具从 apk 中提取的那个)。
  • 以 ZIP 格式打开您的 APK 并从中提取 libmp3lame.so。为该文件重新运行 nm

标签: android android-ndk jdi


【解决方案1】:

LOCAL_SRC_FILES 应该是 C 文件的列表。在你的情况下,它似乎是

LOCAL_SRC_FILES = native.c

当你运行ndk-build 时,你会看到它已编译。

您的 Android.mk 中还有其他错误。

APP_ABI 在那里无关紧要;将它放在 Application.mk 或命令行中。

LOCAL_C_INCLUDE 拼写错误;它显示为 LOCAL_C_INCLUDES。这列出了在哪里查找头文件的目录。在您的情况下,它可能是从您的项目到 mp3gain 目录的路径。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 2014-03-26
    • 1970-01-01
    • 2012-04-22
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多