Android 使用动态库交叉编译C代码时出错
我有两个文件: lib.cAndroid 使用动态库交叉编译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
#包括
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]