使用动态库交叉编译C代码时出错

时间:2013-02-18 14:54:44

标签: android c arm cross-compiling codesourcery

我有两个文件:

lib.c

#include<stdio.h>

void hi() {
  printf("Hi i'm a library function in lib.so\n");
} 

和main.c

#include<stdio.h>
#include<dlfcn.h>
/* based on Jeff Scudder's code */
int main() {
  void *SharedObjectFile;
  void (*hi)();

  // Load the shared libary;
  SharedObjectFile = dlopen("./lib.so", RTLD_LAZY);

  // Obtain the address of a function in the shared library.
  ciao = dlsym(SharedObjectFile, "hi");

  // Use the dynamically loaded function.
  (*hi)();

  dlclose(SharedObjectFile);
}

我尝试使用以下命令构建可执行文件:

  

export LD_LIBRARY_PATH = pwd

     

gcc -c -fpic lib.c

     

gcc -shared -lc -o lib.so lib.o

     

gcc main.c -ldl

它运作良好。 然后我尝试使用以下命令在Android(Nexus One,ARM-v7-0a arch)上导出我的程序:

  

export LD_LIBRARY_PATH = pwd

     

arm-none-linux-gnueabi-gcc -c -fpic lib.c

     

arm-none-linux-gnueabi-gcc -shared -lc -o lib.so lib.o

     

arm-none-linux-gnueabi-gcc main.c -ldl -o main

     

adb push main / system / app

在智能手机上正确的文件夹上执行./main的结果只是:

  

./ main:not found

即使我的文件就在那里!

在交叉编译过程中我遗漏了什么吗?有帮助吗? 我正在使用CodeSourcery的交叉编译器,它适用于没有.so库的静态程序。 感谢

编辑 :正如Igor在下面所述,这是一个链接器问题。此命令修复它:

  

arm-none-linux-gnueabi-gcc -o test main.c -Wl, - dynamic-linker = / system / bin / linker -ldl

在我的情况下我需要其他库,因为在/ system / lib /中没有很多.so文件。

1 个答案:

答案 0 :(得分:6)

“未找到”消息不是指共享对象,而是指动态链接器。 Linux使用/lib/ld-linux.so.2(或/lib64/ld-linux-x86-64.so.2表示x64),而Android则使用/bin/linker。您可以使用readelf -l检查程序使用的动态加载程序,例如:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4
  INTERP         0x000134 0x08048134 0x08048134 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]

您可以指定要与ld的--dynamic-linker开关一起使用的链接器,但可能存在其他差异。例如,Android使用名为bionic的精简libc实现,它可能缺少程序所依赖的功能,或者具有不同的行为。

在为Android编译程序时,您应该使用NDK或其他以Android为目标的工具链。尽管它基于Linux内核,但差异很大,以至于Linux目标工具链还不够。