netdb.h没有正确链接

时间:2011-09-27 15:41:05

标签: c networking linker

我正在尝试编译此程序,如第19页 Beej的网络编程指南中所述。

#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>

int main() {
    int status;
    struct addrinfo hints;
    struct addrinfo *servinfo;          /* Will point to the results */
    memset(&hints, 0, sizeof hints);    /* Make sure the struct is empty */
    hints.ai_family = AF_UNSPEC;        /* Don't care IPv4 or IPv6 */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    if ((status = getaddrinfo(NULL, "3490", &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
        exit(1);
    }

    /* Servinfo now points to a linked list of 1 or more struct addrinfos
        ... do everything until you don't need servinfo anymore .... */

    freeaddrinfo(servinfo); /* Free the linked-list */

    return 0;
}    

在其他错误中,我看到了

../main.c:8:18: error: storage size of ‘hints’ isn’t known
../main.c:13:19: error: ‘AI_PASSIVE’ undeclared (first use in this function)
../main.c:16:3: warning: implicit declaration of function ‘gai_strerror’

gcc似乎没有与netdb.h相关联。 Eclipse,我用来构建它的IDE,可以轻松找到该文件。这是编译器命令:

gcc -O0 -g3 -pedantic -Wall -c -fmessage-length=0 -ansi -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.c"

添加-lnetdb无法解决问题。也...

~> find /usr/include/ -name netdb.h
/usr/include/bits/netdb.h
/usr/include/gssrpc/netdb.h
/usr/include/netdb.h
/usr/include/rpc/netdb.h

我认为我的openSUSE主机上预装了这些文件。为什么gcc没有检测到netdb.h?或者我得出了错误的结论?

4 个答案:

答案 0 :(得分:17)

../main.c:8:18: error: storage size of ‘hints’ isn’t known
../main.c:13:19: error: ‘AI_PASSIVE’ undeclared (first use in this function)
../main.c:16:3: warning: implicit declaration of function ‘gai_strerror’
     

gcc似乎没有与netdb.h ....链接。

这些不是链接错误,您不需要netdb共享对象 文件(没有这样的野兽; netdb.h只是定义数据结构 和代码中使用的宏。)

这些是编译错误:gcc抱怨因为你正在使用名字 它无法识别(AI_PASSIVE)和数据类型 结构未知(struct addrinfo)。

您提供的代码似乎是正确的,addrinfo/usr/include/netdb.h中定义。如果编译它会发生什么 像这样:

gcc -c main.c

你还有同样的行为吗?如果是这样,请查看输出 的:

gcc -E main.c

这将生成一个预处理版本的代码,包含所有代码 #include语句被其实际内容所取代。你应该 能够通过这个grep看看编译器是否真正得到了 /usr/include/netdb.h如果它找到别的东西:

$ gcc -E foo.c | grep netdb.h | awk '{print $3}' | sort -u

我系统上的产量:

"/usr/include/bits/netdb.h"
"/usr/include/netdb.h"
"/usr/include/rpc/netdb.h"

-ansi添加到命令行时,您正在改变方式 gcc的行为会破坏Linux内核和许多系统 头文件。 addrinfo中的netdb.h定义受到保护 像这样:

#ifdef  __USE_POSIX
/* Structure to contain information about address of a service provider.  */
struct addrinfo
{
  int ai_flags;                 /* Input flags.  */
  int ai_family;                /* Protocol family for socket.  */
  int ai_socktype;              /* Socket type.  */
  int ai_protocol;              /* Protocol for socket.  */
  socklen_t ai_addrlen;         /* Length of socket address.  */
  struct sockaddr *ai_addr;     /* Socket address for socket.  */
  char *ai_canonname;           /* Canonical name for service location.  */
  struct addrinfo *ai_next;     /* Pointer to next in list.  */
};

// ...other stuff...
#endif

当您使用gcc标志运行-ansi时,这将取消定义 __USE_POSIX宏,因为受此保护的内容可能不是 严格遵守ANSI标准。如果比较,你可以看到差异 这样:

gcc -E /usr/include/netdb.h

有了这个:

gcc -E -ansi /usr/include/netdb.h

只有前者包含addrinfo结构。

答案 1 :(得分:2)

添加到文件顶部

#define _XOPEN_SOURCE 600

答案 2 :(得分:0)

链接不会将头文件附加到程序,预处理处理头文件。

链接将共享对象库(在/ usr / lib中查找)附加到编译对象。有时仅仅添加“-lnetdb”是不够的,因为库可能不在链接器路径中。在这种情况下,您需要使用-L(路径)来添加路径条目,以便指令“-lnetdb”可以找到正确的netdb.so文件。

答案 3 :(得分:0)

使用#include <netinet/in.h> ....以及.....和编译(ubuntu)....

gcc server/client -o server/client.c -lpthread

(这里lpthread是一个linki处理线程)...它解决了你的问题。 :-D

相关问题