我有两个项目。其中一个是带有本机代码的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/箱/臂-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项目的原生部分(它是混合的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
答案 0 :(得分:2)
一些重要规则:
ndk-build
arm-linux-androideabi-gcc
Android.mk
中的LOCAL_LDFLAGS += -Wl,--export-dynamic
dlerror()
返回错误,则不表示dlsym()
失败。检查dlsym()
是否确实返回NULL
。因为它可能会返回一个有效的地址,但dlerror()
可能会同时返回错误“未找到符号”%))我有这个愚蠢的错误!见代码。 System.LoadLibrary(your_lib.so)
。只有dlopen("your_lib.so")
来自RTLD_NOW
或RTLD_LAZY
的本机代码! 请确保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;
}
这就是全部:)