netdb.h не правильно связывается

Я пытаюсь скомпилировать эту программу, как указано в руководстве Beej по программированию на стр. 19.

#include  #include  #include  #include  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 не -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 ? Или я делаю неправильный вывод?

 ../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 просто определяет структуры данных и macros для использования в вашем коде).

Это compiler errors: 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 себя так, чтобы разорвать kernel ​​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 макрос __USE_POSIX , потому что защищенные этим объекты могут быть несовместимы с ANSI. Вы можете увидеть разницу, если вы сравните это:

 gcc -E /usr/include/netdb.h 

С этим:

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

Только первая содержит структуру addrinfo .

добавить в начало файла

 #define _XOPEN_SOURCE 600 

Связывание не прикрепляет файл заголовка к программе, предварительная обработка обрабатывает файлы заголовков.

Связывание прикрепляет общие библиотеки объектов (смотрите в / usr / lib) к скомпилированным объектам. Иногда не достаточно просто добавить «-lnetdb», поскольку библиотека, возможно, не находится в пути компоновщика. В этом случае вам нужно использовать -L (путь), чтобы добавить запись пути, чтобы директива «-lnetdb» могла найти правильный файл netdb.so.

Используйте #include …. вместе с тем ….. и в компиляции (ubuntu) ….

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

(здесь lpthread – stream обработки linki) … который решает вашу проблему. 😀