gpt4 book ai didi

android - 适用于 Android 2.2 的动态 C/C++ 库 : error Symbol not found

转载 作者:行者123 更新时间:2023-11-29 22:05:49 25 4
gpt4 key购买 nike

我有两个项目。其中之一是带有 native 代码的 Android 应用程序,它只加载动态库 android_lib.so。

另一个项目是那个库(android_lib.so)。这个库的代码很简单,只是为了了解事情的进展。它只有一个功能。这是它:

int calculate (int x, int y)
{
return (x*x+y*y);
}

Makefile 中,我使用来自 Android 2.2 工具链的跨平台编译器 (/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc):

NDK_DIR=/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
ANDROID_GCC=$(NDK_DIR)/arm-linux-androideabi-gcc
NDK_ROOT=/usr/local/android-ndk-r8

CPPFLAGS = $(NDK_ROOT)/platforms/android-8/arch-arm/usr/include
CFLAGS =-nostdlib
LDFLAGS = -Wl,-rpath-link=$(NDK_ROOT)/platforms/android-8/arch-arm/usr/lib/ -L$(NDK_ROOT)/platforms/android-8/arch-arm/usr/lib/
LIBS=-lc

android_lib.so: calculate.o
$(ANDROID_GCC) $(CFLAGS) -shared -o android_lib.so calculate.o

calculate.o: calculate.c
$(ANDROID_GCC) $(CPPFLAGS) $(CFLAGS) -c -fPIC calculate.c
clean:
rm -f *.o *.so

所以我输入 make 并获取 android_lib.so。在 android 项目的 native 部分(它是混合的 Java/C++ Eclipse 项目)我调用 dlopen()

dl_handle = dlopen( lib, RTLD_LAZY );
if (!dl_handle) {
error = (char *) dlerror();
if (error != NULL) {
__android_log_print(ANDROID_LOG_INFO,"nativeCode",error);
return -1;
}
else {
sprintf(sError,"%s is not found",lib);
__android_log_print(ANDROID_LOG_INFO,"nativeCode",sError);
return -2;
}
}

它成功加载了 android_lib.so。但是,如果我尝试调用函数 calculate(),则会出现错误。

func = (int (*)(int, int)) dlsym( dl_handle, "calculate" );
error = (char *) dlerror();
if (error != NULL) {
__android_log_print(ANDROID_LOG_INFO,"nativeCode",error);
return -3;
}

函数返回 -3 并且在 Eclipse 的 LogCat 中我可以看到

01-01 07:00:44.624: I/nativeCode(8696): Symbol not found:

请帮我解决这个问题。

更新:

$ cd /usr/local/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin 
$ sudo ./arm-linux-androideabi-objdump -T /home/chet/workspace/dinLib/android_lib.so

/home/chet/workspace/dinLib/android_lib.so: file format elf32-littlearm

DYNAMIC SYMBOL TABLE:
00000234 l d .text 00000000 .text
00000274 g D *ABS* 00000000 __exidx_end
000012e0 g D *ABS* 00000000 _bss_end__
00000234 g DF .text 00000040 calculate
000012e0 g D *ABS* 00000000 __bss_start__
00000274 g D *ABS* 00000000 __exidx_start
000012e0 g D *ABS* 00000000 __bss_end__
000012e0 g D *ABS* 00000000 __bss_start
000012e0 g D *ABS* 00000000 __end__
000012e0 g D *ABS* 00000000 _edata
000012e0 g D *ABS* 00000000 _end
000012e0 g D .got 00000000 __data_start

最佳答案

一些重要的规则:

  1. 你应该直接使用 ndk-build arm-linux-androideabi-gcc
  2. 在库类型的 Android.mk 中下一个选项:LOCAL_LDFLAGS += -Wl,--export-dynamic
  3. 如果 dlerror() 返回错误,这并不意味着 dlsym() 失败。检查 dlsym() 是否真的返回 NULL。因为它可能会返回一个有效地址,但 dlerror() 可能会同时返回错误“找不到符号”%))我犯了这个愚蠢的错误!!!见代码。
  4. 您不需要调用 System.LoadLibrary(your_lib.so)。无论是 RTLD_NOW 还是 RTLD_LAZY,都只能从 native 代码中使用 dlopen("your_lib.so")!
  5. 确保 your_lib.so 位于 /data/data/app_name/libs

    func = (int (*)(int, int)) dlsym( dl_handle, "calculate" );
    error = (char *) dlerror();
    if (error != NULL) { //replace it with if ((func == NULL)&& (error != NULL))
    __android_log_print(ANDROID_LOG_INFO,"nativeCode",error);
    return -3;
    }

就是这样:)

关于android - 适用于 Android 2.2 的动态 C/C++ 库 : error Symbol not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10785740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com