将函数gethostbyname编译为静态链接错误



我正在尝试使用交叉编译器arm-none-linux-gnueabi的函数gethostbyname()编译程序,但当我在android上运行二进制文件时,它不起作用。

我的代码如下:

  /* gethostbyname-example.c */
  #include <stdio.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <netdb.h>
  extern int h_errno;
  int main(int argc,char **argv) {
     int x, x2;
     struct hostent *hp;
     for ( x=1; x<argc; ++x ) {
        hp = gethostbyname(argv[x]);
        if ( !hp ) {
           fprintf(stderr,
                   "%s: host '%s'n",
                   hstrerror(h_errno),
                   argv[x]);
           continue;
        }
        printf("Host %s : n" ,argv[x]);
        printf(" Officially:t%sn", hp->h_name);
        fputs(" Aliases:t",stdout);
        for ( x2=0; hp->h_aliases[x2]; ++x2 ) {
           if ( x2 ) {
              fputs(", ",stdout);
             }
        fputs(hp->h_aliases[x2],stdout);
        }     
        fputc('n',stdout);
        printf(" Type:tt%sn",
               hp->h_addrtype == AF_INET
               ? "AF_INET" : "AF_INET6");
        if ( hp->h_addrtype == AF_INET ) {
           for ( x2=0; hp->h_addr_list[x2]; ++x2 ) {
              printf(" Address:t%sn",
                     inet_ntoa( *(struct in_addr *)
                      hp->h_addr_list[x2]));
           }
        }
     putchar('n');
     }
     return 0;
  }

我用arm-none-linux-gnueabi-gcc编译,在我的笔记本电脑上使用操作系统ubuntu 12.04和交叉编译器Sourcery Codebench:

$ arm-none-linux-gnueabi-gcc gethostbyname-example.c --static -o gethostbyname-example
/tmp/ccE0xjBG.o: In function `main':
lookup.c:(.text+0x38): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ ls
gethostbyname-example.c gethostbyname-example
$ file gethostbyname-example
gethostbyname-example: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped

然后我在chroot手臂上测试二进制gethostbyname-example,我复制粘贴二进制到chroot文件夹,然后我登录到chroot,我执行,顺便说一句,我从这里制作chroot https://wiki.ubuntu.com/ARM/BuildEABIChroot,如果我在chroot上运行它,我得到的结果如下:

# ./gethostbyname-example www.google.com
Host google.com : 
 Officially:    www.google.com
 Aliases:   
 Type:      AF_INET
 Address:   74.125.135.139
 Address:   74.125.135.100
 Address:   74.125.135.101
 Address:   74.125.135.102
 Address:   74.125.135.113
 Address:   74.125.135.138

然后我也上传二进制gethostbyname-example与adb push到我的android设备,如果我运行二进制gethostbyname-example我得到错误如下:

# ./gethostbyname-example www.google.com
# Unknown server error: host 'www.google.com'
# ping www.google.com
# PING www.google.com (74.125.135.99) 56(84) bytes of data.
# 64 bytes from ni-in-f99.1e100.net (74.125.135.99): icmp_seq=1 ttl=49 time=798 ms
# 64 bytes from ni-in-f99.1e100.net (74.125.135.99): icmp_seq=2 ttl=49 time=1039 ms

在我的android设备中,我有一个文件hosts在/etc/和/system/etc/与谷歌DNS

8.8.8.8 
8.8.4.4

大概是什么原因导致这个失败,

谢谢。

简短说明

glibc中的DNS查找需要/lib/libnss_dns.so。2,在Android上不可用。

另一个不同之处在于Android存储DNS设置/system/etc/resolv.conf,使用仿生C库构建的原生Android应用程序将在那里查找要查询的DNS服务器。使用glibc构建的应用程序将在/etc/resolv.conf中查找,这在Android上不存在。

<标题> 再解释

您已经使用glibc构建了二进制文件,而Android使用bionic C库。

当静态链接到libc时,这应该在很大程度上是好的,因为我不知道android内核中有足够严重的变化来破坏简单的用户端应用程序。你应该使用Android NDK来构建Android原生应用, 然而,当静态链接到glibc时,有一些事情会出错。glibc中的某些功能,例如查找用户信息、主机名和其他通常在/etc/nsswitch.conf中配置的功能,会调用其他共享库来实际完成工作。无论是否静态链接到glibc本身,都会发生这种情况。这些文件通常是在glibc系统上找到的/lib/libnss_*文件。

大多数共享库都是glibc的一部分,并且将被安装在glibc系统上。但它们在安卓系统上是不可用的。当这些共享库可用时,依赖于使用这些helper共享库的函数的应用程序不能正常工作- gethostbyname()就是其中之一,因为对于正常的DNS查询,它需要/lib/libnss_dns.so.2

说明请参阅no reply,解决方案请遵循以下步骤:

  • 从这里下载android NDK: https://developer.android.com/ndk/downloads/index.html(我使用linux 64bit)
  • unzip android-ndk-r13b-linux-x86_64.zip
  • 进入刚解压的目录
  • 启动./build/tools/make_standalone_toolchain.py查看可能的选项例如:/build/tools/make_standalone_toolchain.py——arch arm——api 9
  • 工具将构建arm-linux-androideabi.tar。bz2给你
  • 解压tar xjvf arm-linux-androideabi.tar.bz2
  • 将创建。/arm-linux-androideabi目录
  • 现在你可以用。/arm-linux-androideabi/bin/arm-linux-androideabi-gcc编译你的程序。
  • >
  • >
  • 生成的可执行文件是本机的,解析器将按预期工作

相关内容

  • 没有找到相关文章

最新更新