Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/205.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用动态库交叉编译C代码时出错_Android_C_Arm_Cross Compiling_Codesourcery - Fatal编程技术网

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

Android 使用动态库交叉编译C代码时出错,android,c,arm,cross-compiling,codesourcery,Android,C,Arm,Cross Compiling,Codesourcery,我有两个文件: lib.c #包括 void hi(){ printf(“嗨,我是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; SharedObje

我有两个文件:

lib.c

#包括
void hi(){
printf(“嗨,我是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);
}
#包括
#包括
/*基于Jeff Scudder的代码*/
int main(){
作废*共享对象文件;
无效(*hi)();
//加载共享库;
SharedObjectFile=dlopen(“./lib.so”,RTLD_-LAZY);
//获取共享库中函数的地址。
ciao=dlsym(共享对象文件,“hi”);
//使用动态加载的函数。
(*hi)();
dlclose(SharedObjectFile);
}
我尝试使用以下命令构建可执行文件:

导出LD_库_路径=
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)上导出我的程序:

导出LD_库_路径=
pwd

armnonelinuxgnueabigcc-c-fpic lib.c

armnonelinuxgnueabigcc-shared-lc-o lib.so lib.o

armnonelinuxgnueabigccmain.c-ldl-omain

adb推送主/系统/应用程序

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

/主:未找到

即使我的文件就在那里

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

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

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

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

未找到的消息指的不是共享对象,而是动态链接器。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的
--动态链接器
开关一起使用,但可能存在其他差异。例如,Android使用一个称为仿生的精简libc实现,它可能缺少程序所依赖的功能,或者具有不同的行为


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

您不使用NDK的具体原因是什么?C代码在android设备上执行后,是否无法在其文件夹中找到?我知道程序应该在同一个文件夹/usr/lib或/usr/local/lib中检查。所以库文件,但我的设备上没有后两个。如何添加错误检查和
dlerror
调用
main
?@Michael:我不能使用NDK,我应该使用命令行通过一个交叉编译器调用来实现这类代码的执行。由于
“/lib.so”
包含一个斜杠,
dlopen
应该尝试该文件名,所有关于
LD\u LIBRARY\u PATH
和/usr/lib的内容都不应该应用。谢谢Igor!这就是我想要的解释。我的问题是链接器,因为如果我在main上使用readelf-l,它会显示“/lib/ld linux…”,所以它是一个错误的链接器。我发现更多的线程处理这个问题,现在我知道这是一个链接的问题。我只需要正确地使用arm none linux gnueabi ld,我希望它能实现。
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]