2011-09-27 15 views
12

Próbuję skompilować ten program, jak podano w Beej Guide to Network Programming na stronie 19.netdb.h nie łączące odpowiednio

#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; 
}  

Wśród innych błędów, widzę

../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’ 

Wygląda na to, że gcc nie łączy się z netdb.h. Eclipse, IDE, którego używam do budowania tego, nie ma problemu ze znalezieniem pliku. Oto komenda kompilatora:

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

Dodanie -lnetdb nie rozwiązuje problemu. Również ...

~> 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 

Myślę, że te pliki zostały wstępnie zainstalowane na moim hoście OpenSUSE. Dlaczego gcc nie wykrywa netdb.h? Czy wyciągam błędne wnioski?

Odpowiedz

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’ 

Wydaje się, że gcc nie jest łączenie z netdb.h ....

Nie są linkami błędy i nie trzeba się netdb obiekt udostępniony plik (nie ma takiej bestii: netdb.h po prostu definiuje struktury danych i makra do użycia w twoim kodzie).

Są błędy kompilatora: gcc skarży ponieważ używasz nazwy że nie rozpoznają (AI_PASSIVE) oraz typy danych, dla których struktura jest nieznana (struct addrinfo).

Kod wyświetlany przez użytkownika wydaje się być poprawny, a addrinfo jest zdefiniowany w /usr/include/netdb.h. Co się stanie, jeśli go skompilować takiego:

gcc -c main.c 

Czy nadal uzyskać ten sam problem? Jeśli tak, to spójrz na wyjściu z:

gcc -E main.c 

To generuje przetworzonych wersję kodu, ze wszystkimi #include sprawozdania zastąpionych przez ich rzeczywistej treści.Trzeba mieć stanie grep przez to i zobacz, czy kompilator jest rzeczywiście coraz /usr/include/netdb.h jeśli jeśli jest znalezienie czegoś innego:

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

Który na moich plonów System:

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

Po dodaniu -ansi do linii poleceń, zmienia się sposób, w jaki zachowuje się w sposób, który złamie jądro Linuxa i wiele plików nagłówkowych systemu. Definicja w netdb.haddrinfo jest chroniony tak:

#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 

Po uruchomieniu gcc z flagą -ansi ten undefines __USE_POSIX makro, ponieważ rzeczy chronione przez to nie może być ściśle ANSI zgodny. Widać różnicę jeśli porównać to:

gcc -E /usr/include/netdb.h 

z tym:

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

Tylko byłego zawiera strukturę addrinfo.

+0

Otrzymuję te same trzy pliki nagłówkowe jako dane wyjściowe. Widzę te błędy kompilacji: http://pastebin.com/jVVMqftA – Pieter

+1

Więc ... to działa? Oznacza to, że nie widzisz żadnych błędów związanych z 'netdb.h', a otrzymujesz ostrzeżenie o' memset() '? To brzmi jak postęp. Ostrzeżenie 'memset()' oznacza, że ​​musisz '#include ' (pochodzi ze strony man 'memset (3)'). – larsks

+0

Nie widzę żadnych ostrzeżeń ani błędów, jeśli dołączę również ciąg 'string.h'. Jednak chcę, aby mój kod był zgodny z ANSI C, więc nadal dostaję te błędy ... http://pastebin.com/B21NyGQ9 – Pieter

0

Łączenie nie powoduje dołączenia pliku nagłówkowego do programu, wstępne przetwarzanie obsługuje pliki nagłówkowe.

Łączenie dołącza biblioteki obiektów współdzielonych (patrz/usr/lib) do skompilowanych obiektów. Czasami nie wystarczy dodać "-lnetdb", ponieważ biblioteka może nie znajdować się w ścieżce linkera. W takim przypadku należy użyć -L (ścieżka), aby dodać pozycję ścieżki, aby dyrektywa "-lnetdb" mogła znaleźć poprawny plik netdb.so.

+0

Wygląda na to, że nie mam wspólnego obiektu o nazwie '* netdb *' w tym folderze ... http://pastebin.com/9GPmFehC Jak mogę uzyskać pliki SO, których mi brakuje ? – Pieter

2

dodać na początku pliku

#define _XOPEN_SOURCE 600 
0

Korzystanie #include <netinet/in.h> .... wraz z tym ..... i kompilacji (ubuntu) ....

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

(tutaj lpthread jest wątkiem przetwarzania linków) ... który rozwiązuje twój problem. :-D

Powiązane problemy