Konstanten in einem Header File

[tE]bachi

BSD Freak
Salü Zusammen

Habe ein Problem mit mehreren Konstanten.
Ich habe sie ich ein Headerfile gesteckt. Beim kompilieren habe ich aber Fehler:
Code:
[...]
TCPViewTreeView.o(.data+0x0): In function `tcp_view_tree_view_get_type':
/usr/home/bachi/TCPView/src/tcpview/TCPViewTreeView.c:92: multiple definition of `TCPViewSocketState'
TCPViewMain.o(.data+0x0):/usr/home/bachi/TCPView/src/tcpview/TCPViewMain.c:6: first defined here
TCPViewTreeView.o(.data+0x30): In function `tcp_view_tree_view_get_type':
[...]

Mein Header File:
Code:
[...]
const guchar *TCPViewSocketState[] = {
    "",
    "CLOSED",
    "LISTEN",
    "SYN_SENT",
    "SYN_RCVD",
    "ESTABLISHED",
    "CLOSE_WAIT",
    "FIN_WAIT_1",
    "CLOSING",
    "LAST_ACK",
    "FIN_WAIT_2",
    "TIME_WAIT"
};
[...]

Habe es auch mit Header:
Code:
[...]
extern const guchar *TCPViewSocketState[];
[...]
und C Source:
Code:
const guchar *TCPViewSocketState[] = {
    "",
    "CLOSED",
    "LISTEN",
    "SYN_SENT",
    "SYN_RCVD",
    "ESTABLISHED",
    "CLOSE_WAIT",
    "FIN_WAIT_1",
    "CLOSING",
    "LAST_ACK",
    "FIN_WAIT_2",
    "TIME_WAIT"
};

Hat aber nicht funktioniert...
Hat jemand eine Lösung dazu?

greets

[tE]bachi
 
Wenn ich das mit 'extern' Versucht, kommt einfach eine andere Fehlermeldung
Code:
/usr/home/bachi/TCPView/src/tcpview/TCPViewTreeView.c:512: undefined reference to `TCPViewSocketState'
 
Warum um alles in der Welt nimmst du keine Enumeration?

Ansonsten funktionieren hier beide Varianten (also entweder im Header, oder im .c)
Code:
const char *foo[] = {
  "A",
  "B",
  "C"
};
 
Zuletzt bearbeitet:
Hallo [tE]bachi

Was steht denn in Zeile 6:
Code:
/usr/home/bachi/TCPView/src/tcpview/TCPViewMain.c:6: first defined here
TCPViewTreeView.o(.data+0x30): In function `tcp_view_tree_view_get_type':
Offensichtlich wurde dieses Array oder die eine Variable gleichen Namens schon mal definiert.

Viele Grüße

Jürgen
 
joh....

ich nehme mal an, du benutzt das header-file in beiden c-files?
und deswegen meckert der?

kein problem.... mach einfach folgendes:

Code:
#ifndef  MYTCPVIEWSOCKETSTATE
#define MYTCPVIEWSOCKETSTATE
const guchar *TCPViewSocketState[] = {....};
#endif

und zwar ueberall.
 
Habe schon ein #ifndef, hat aber nicht funktioniert...

Code:
#ifndef __TCP_VIEW_SOCKET_H__
#define __TCP_VIEW_SOCKET_H__

[...]

enum _TCPViewSocketStateEnum {
    STATE_UNKNOW = 0,
    STATE_CLOSED,
    STATE_LISTEN,
    STATE_SYN_SENT,
    STATE_SYN_RCVD,
    STATE_ESTABLISHED,
    STATE_CLOSE_WAIT,
    STATE_FIN_WAIT_1,
    STATE_CLOSING,
    STATE_LAST_ACK,
    STATE_FIN_WAIT_2,
    STATE_TIME_WAIT
};


static const guchar *TCPViewSocketState[] = {
    "",
    "CLOSED",
    "LISTEN",
    "SYN_SENT",
    "SYN_RCVD",
    "ESTABLISHED",
    "CLOSE_WAIT",
    "FIN_WAIT_1",
    "CLOSING",
    "LAST_ACK",
    "FIN_WAIT_2",
    "TIME_WAIT"
};

[...]

#endif

ich glaube, dass das nicht funktioniert,
Code:
               -------------------
               | TCPViewSocket.h |
               -------------------
                       |
         ---------------------------
         |                         |
--------------------    ------------------------
| TCPViewBackend.h |    | TCPViewBackendFBSD.h |
--------------------    ------------------------
         |                         |
--------------------    ------------------------
| TCPViewBackend.c |    | TCPViewBackendFBSD.c |
--------------------    ------------------------

dass aber schon
Code:
--------------------  -------------------  ------------------------
| TCPViewBackend.h |  | TCPViewSocket.h |  | TCPViewBackendFBSD.h |
--------------------  -------------------  ------------------------
         |                     |                      |
         |    ------------------------------------    |
         |    |                                  |    |
--------------------                       ------------------------
| TCPViewBackend.c |                       | TCPViewBackendFBSD.c |
--------------------                       ------------------------

auf jeden fall funktioniert es jetzt irrgendwie...

schaut mal rein: TCPView 0.9

nur noch das menu (in arbeit), das speicherleck, die xlib async fehler, die segmentation faults und die portierung auf andere plattformen (im moment ist nur FreeBSD unterstützt) sind noch ausstehend.

greets

[tE]bachi
 
Alles funktioniert.

In ein Header-File gehören Konstantendefinitionen nicht hinein. Du kannst die Konstanten aber deklarieren. Sie werden dann als gültig angesehen und beim Linken "zusammengeschweißt".

In ein Header (a.h) kannst Du eine extern-Deklaration machen:
Code:
extern const int a;

In EIN Modul kannst Du dann diese Konstante definieren:
Code:
const int a=1;

Aus allen möglichen Modulen kannst Du nun a.h laden. Erst beim Linken wird dann überprüft, ob die Deklaration eine Definition hat. Dabei brauchst Du noch nicht mal die #ifndef/#define Schutzmechanismen, obwohl sie generell empfehlenswert sind.

Es ist wichtig den Unterschied zwischen Deklaration und Definition zu verstehen.
 
habe ich auch gemeint... ist aber irrgendwie doch falsch gelaufen.
wenn ich das nun linke, gibts einfach einen anderen fehler aus:
Code:
TCPViewTreeView.o(.text+0xa5a): In function `tcp_view_tree_view_refresh_list':
/usr/home/bachi/tcpview/src/tcpview/TCPViewTreeView.c:513: undefined reference to `TCPViewSocketState'
*** Error code 1

ist ja auch egal, funktioniert ja jetzt!
 
Wenn Du ganz verloren bist, dann kannst Du ja mittels nm nachschauen was in welcher Objekt-Datei definiert wurde. Weiteres zu nm gibt es in der entsprechenden Man-Page.
 
Aber es funktioniert eigentlich falsch. Es geht nur, da du const benutzt und beide gleich sind...
Wäre es eine Variable, so würdest du beim Debuggen spucken ;)
Du legt nämlich const in beiden(!) Objekt-Dateien an.

Sauber ist nur die Extern-Deklaration und das linken einer zusätzlichen TcpViewSocket.o, wo die const deklariert ist.
Ist der Extern-definition darf auch nicht "const xx* yy[]" stehen sondern const xx** yy, da die Größe hier ja noch unbekannt ist. Deine [] ist nur eine Kurzformfür [12], der Compiler zählt die 12 Einträge selber :)
Es ist schon ein Kreuz mit dem Programmieren....
 
Zurück
Oben