动态C / C ++为Android 2.2 lib目录下:错误符号未找到 [英] Dynamic C/C++ lib for Android 2.2: error Symbol not found

查看:156
本文介绍了动态C / C ++为Android 2.2 lib目录下:错误符号未找到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个项目。其中之一是Android应用程序与本地code,刚刚加载动态库andr​​oid_lib.so。

另一个项目是,库(android_lib.so)。这个库的code是简单的只是学习的事情是怎么回事。它只有一个功能。这里是:

  INT计算(INT X,int y)对
{
  回报(X * X + Y * Y);
}

的Makefile 我用的跨平台,Android 2.2的工具链compilator (/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi4.4.3/$p$pbuilt/linux-x86/bin/arm-linux-androideabi-gcc):

<$p$p><$c$c>NDK_DIR=/usr/local/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/$p$pbuilt/linux-x86/bin
ANDROID_GCC = $(NDK_DIR)/ ARM-Linux的androideabi-GCC
NDK_ROOT =的/ usr /本地/ Android的NDK-R8CPPFLAGS = $(NDK_ROOT)/平台/ Android的-8 /弓臂/ usr / include目录
CFLAGS = -nostdlib
LDFLAGS = -Wl,-rpath链接= $(NDK_ROOT)/平台/ Android的-8 /弓臂/ usr / lib目录/ -L $(NDK_ROOT)/平台/ Android的-8 /弓臂/ usr / lib目录/
LIBS = -lcandroid_lib.so:calculate.o
    $(ANDROID_GCC)$(CFLAGS)-o -shared android_lib.so calculate.ocalculate.o:calculate.c
    $(ANDROID_GCC)$(CPPFLAGS)$(CFLAGS)-c -fPIC calculate.c
清洁:
    RM -f * *的.o。所以

于是我输入make并获得 android_lib.so
在Android项目的一部分原生(它是混合的Java / C ++的Eclipse项目),我调用dlopen的()

  dl_handle =的dlopen(LIB,RTLD_LAZY);
  如果(!dl_handle){
      误差=(字符*)dlerror获得();
      如果(错误!= NULL){
          __android_log_print(ANDROID_LOG_INFO,本土code,错误);
          返回-1;
      }
      其他{
          sprintf的(sError%s没有找到,LIB);
          __android_log_print(ANDROID_LOG_INFO,本土code,sError);
          返回-2;
      }
  }

它成功地加载android_lib.so。但是,如果我试图调用函数计算()我得到错误。

  FUNC =(INT(*)(INT,INT))的dlsym(dl_handle,计算);
  误差=(字符*)dlerror获得();
  如果(错误!= NULL){
      __android_log_print(ANDROID_LOG_INFO,本土code,错误);
      返回-3;
  }

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

  7月1日至1日:00:44.624:I /本地code(8696):找不到符号:

请帮我解决这个问题。

更新

  $ CD /usr/local/android-ndk-r8/tool​​chains/arm-linux-androideabi-4.4.3/$p$pbuilt/linux-x86/bin
$ sudo的./arm-linux-androideabi-objdump -T /home/chet/workspace/dinLib/android_lib.so/home/chet/workspace/dinLib/android_lib.so:文件格式ELF32-littlearm动态符号表:
00000234升ð的.text 00000000的.text
00000274克D * ABS * 00000000 __exidx_end
000012e0克D- * ABS * 00000000 _bss_end__
00000234克DF 00000040 .text区段计算
000012e0克D- * ABS * 00000000 __bss_start__
00000274克D * ABS * 00000000 __exidx_start
000012e0克D- * ABS * 00000000 __bss_end__
000012e0克D- * ABS * 00000000 __bss_start
000012e0克D- * ABS * 00000000 __END__
000012e0克D- * ABS * 00000000 _edata
000012e0克D- * ABS * 00000000 _end
000012e0克D- .GOT 00000000 __data_start


解决方案

一些重要的规则:


  1. 您应该使用 NDK的构建,而不是直接 ARM-Linux的androideabi-GCC

  2. 库类型下一选项
  3. Android.mk LOCAL_LDFLAGS + =轮候册, - 出口动态

  4. 如果 dlerror获得()返回错误并不意味着则dlsym()失败。检查则dlsym()真的返回 NULL 。因为它可能会返回一个有效的地址,但 dlerror获得()可能会返回错误找不到符号在同一时间%)),我有这个愚蠢的错误!见code。

  5. 您不需要调用的System.loadLibrary(your_lib.so)。只有的dlopen(your_lib.so)从本地code与 RTLD_NOW RTLD_LAZY 不管!

  6. 确保 your_lib.so 位于 /数据/数据​​/ APP_NAME /库

      FUNC =(INT(*)(INT,INT))的dlsym(dl_handle,计算);
    误差=(字符*)dlerror获得();
    如果(!错误= NULL){//将其替换为IF((FUNC == NULL)及及(误差= NULL)!)
      __android_log_print(ANDROID_LOG_INFO,本土code,错误);
      返回-3;
    }


这是所有:)

I have two projects. One of them is Android app with native code, which just loads dynamically library android_lib.so.

Another project is that library (android_lib.so). Code of this library is simple just for learning how things are going. It has only one function. Here is it:

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

In Makefile I use cross-platform compilator from Android 2.2 toolchains (/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 

So I type make and get android_lib.so. In native part of android project (it is mixed Java/C++ Eclipse project) I call 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;
      }
  }

It succesfully loads android_lib.so. But if I am trying to call function calculate() I get error.

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

Function returns -3 and in LogCat of Eclipse I can see

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

Please help me to solve this issue.

Update:

$ 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

解决方案

Some important rules:

  1. you should use ndk-build instead directly arm-linux-androideabi-gcc
  2. in Android.mk of library type next options: LOCAL_LDFLAGS += -Wl,--export-dynamic
  3. if dlerror() returns error it doesn't mean that dlsym() failed. Check if dlsym() really returns NULL. Because it may return a valid address but dlerror() may return error "Symbol not found" at the same time %)) I had this stupid mistake!!! See code.
  4. You do not need call System.LoadLibrary(your_lib.so). Only dlopen("your_lib.so") from native code with RTLD_NOW or RTLD_LAZY no matter!
  5. Be sure that your_lib.so is situated in /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; 
    }
    

That's all :)

这篇关于动态C / C ++为Android 2.2 lib目录下:错误符号未找到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆