Fehler beim Linken

Hallo,
ich habe ein Netzwerkprogramm geschrieben, aber beim Linken kommen immer Fehlermeldungen, die ich nicht verstehe. Ich weiß auch nicht wo mein Fehler sein könnte.
Ich hoffe, dass ihr mir helfen könnt.

Hier mein Programm:
Code:
#include<windows.h>
#include<winsock2.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int startWinSock();

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	MSG msg;
	HWND hWnd;
	WNDCLASS wc;
	int fehler;

	const char szAppName[]="chat 1";

	wc.style=CS_HREDRAW|CS_VREDRAW|CS_NOCLOSE;
	wc.lpfnWndProc=WndProc;
	wc.cbClsExtra=0;
	wc.cbWndExtra=0;
	wc.hInstance=hInstance;
	wc.hIcon=NULL;
	wc.hCursor=LoadCursor(NULL, IDI_APPLICATION);
	wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName=NULL;
	wc.lpszClassName=szAppName;

	fehler=RegisterClass(&wc);
	if(fehler==0)
	{
		MessageBox(0, "Fehler bei RegisterClass()!", "Fehler", MB_ICONERROR|MB_OK);
		return 1;
	}

	hWnd=CreateWindow(
		szAppName,
		szAppName,
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL);

	ShowWindow(hWnd, iCmdShow);
	UpdateWindow(hWnd);

	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	SOCKET empfangsSocket;
	SOCKET verbindungsSocket;
	int fehler;
	switch(message)
	{
	case WM_CREATE:
		{
			fehler=startWinSock();
			if(fehler!=0)
			{
				return 1;
			}
			MessageBox(0, "WinSock gestartet!", "", MB_ICONASTERISK|MB_OK);
			empfangsSocket=socket(AF_INET, SOCK_STREAM, 0);
			if(empfangsSocket==INVALID_SOCKET)
			{
				return 1;
			}
			MessageBox(0, "Socket erstellt!", "", MB_ICONASTERISK|MB_OK);
			SOCKADDR_IN adresse;
			memset(&adresse, 0, sizeof(SOCKADDR_IN));
			adresse.sin_family=AF_INET;
			adresse.sin_port=htons(12345);
			adresse.sin_addr.s_addr=ADDR_ANY;
			fehler=bind(empfangsSocket, (SOCKADDR*)&adresse, sizeof(SOCKADDR_IN));
			if(fehler==SOCKET_ERROR)
			{
				return 1;
			}
			MessageBox(0, "Socket an Port 12345 gebunden!", "", MB_ICONASTERISK|MB_OK);
			fehler=listen(empfangsSocket, 10);
			if(fehler==SOCKET_ERROR)
			{
				return 1;
			}
			MessageBox(0, "empfangsSocket ist im listen Modus...", "", MB_ICONASTERISK|MB_OK);
			UpdateWindow(hWnd);
			verbindungsSocket=accept(empfangsSocket, 0, 0);
			if(verbindungsSocket==INVALID_SOCKET)
			{
				return 1;
			}
			MessageBox(0, "Neue Verbindung wurde akzeptiert!", "", MB_ICONASTERISK|MB_OK);
			char nachricht[1002];
			while(fehler!=SOCKET_ERROR)
			{
				fehler=recv(verbindungsSocket, nachricht, 1000, 0);
				if(fehler==0)
					break;
				if(fehler==SOCKET_ERROR)
					break;
				if(nachricht=="close.window.now")
					break;
				nachricht[fehler]='\0';
				MessageBox(0, nachricht, "", MB_ICONASTERISK|MB_OK);
			}
			closesocket(empfangsSocket);
			closesocket(verbindungsSocket);
			WSACleanup();
			return 0;
		}
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}

int startWinSock()
{
	WSADATA wsa;
	return WSAStartup(MAKEWORD(2, 0), &wsa);
}

Hier die Fehlermeldungen:
Code:
C:\C++\netzwerk>g++ -c winappserver.cpp -mwindows

C:\C++\netzwerk>g++ -o winappserver c:\c++\mingw\lib\libws2_32.a winappserver.o
-mwindows
winappserver.o:winappserver.cpp:(.text+0x246): undefined reference to `socket@12
'
winappserver.o:winappserver.cpp:(.text+0x2b5): undefined reference to `htons@4'
winappserver.o:winappserver.cpp:(.text+0x2dd): undefined reference to `bind@12'
winappserver.o:winappserver.cpp:(.text+0x332): undefined reference to `listen@8'

winappserver.o:winappserver.cpp:(.text+0x39d): undefined reference to `accept@12
'
winappserver.o:winappserver.cpp:(.text+0x40e): undefined reference to `recv@16'
winappserver.o:winappserver.cpp:(.text+0x47a): undefined reference to `closesock
et@4'
winappserver.o:winappserver.cpp:(.text+0x488): undefined reference to `closesock
et@4'
winappserver.o:winappserver.cpp:(.text+0x490): undefined reference to `WSACleanu
p@0'
winappserver.o:winappserver.cpp:(.text+0x4ef): undefined reference to `WSAStartu
p@8'
collect2: ld returned 1 exit status
 
Du hast vergessen(oder weist nicht).
Dem Compiler zu sagen das du eine nicht standart liberie nutzt.
Wenn du unter windows endwickelst heist die lib "wsock32.lib " die ist auch im Windows enthalten.

Wenn du visuel studie nutzt
dann kannst du die libery linken über Projekt einstellungen Linker und dann unten bei "objekt Biblotheken" hinzufügen.

Wenn du unter Windows arbeites könnte es auch helfen wenn du die winsock2.h nicht einbindest.

mfg Faller
 
Hallo Faller,
danke erstmal für deine schnelle Antwort.
Ich hab jetzt alles mögliche versucht, was du geschrieben hast (nur libwsock32.a, libwsock32.a und libws2_32.a und beides mit und ohne winsock.h), aber die Fehler tauchen immer wieder auf.
Könntest du mir denn vielleicht erklären, was die Fehler bedeuten? Dann könnte ich auch überlegen, wodran das liegen könnte.

bastionmancher

P.S.
wsock32.lib hab ich nicht im lib-Verzeichniss von meinem Compiler gefunden. Ich hoffe, dass libwsock32.a nur ein anderer Name für die gleiche Sache ist. Oder liegts etwa dadran?
 
Hi.

Offensichtlich verwendest du den MinGW um dein Programm zu kompilieren.

Wenn du die wsock32 Bibliothek einbinden willst, heißt die Datei dann tatsächlich libwsock32.a bzw. libwsock32.dll.

Du mußt nur in den Projekteinstellungen diese Datei mit angeben. Für Dev-Cpp:

Im "Project Options" Dialog, Reiter "Paramater" auf "Add Library or Object" klicken, die libwsock32.a Datei aus dem lib/ Verzeichnis auswählen.

Gruß
 
Hallo,
ich benutze visual studio und als compiler MinGW. Ich starte in Visual Studio aber nie ein neues Projekt, sondern öffne immer nur eine neue datei. Deshalb benutze ich MinGW als Compiler.
Als Betriebssystem nehm ich Windows.
Hoffe, dass ihr mir weiterhelfen könnt, denn bisjetzt haben die Bibliotheken alle noch nichts genützt.
Bei anderen Programmen (keine Windowsprogramme) hat es bisher immer gereicht, wenn ich zusätzlich libws2_32.a eingebunden habe.

Gruß
bastionmancher
 
Hallo,
ich benutze visual studio und als compiler MinGW. Ich starte in Visual Studio aber nie ein neues Projekt, sondern öffne immer nur eine neue datei. Deshalb benutze ich MinGW als Compiler.
D.h. du gibst die Befehle dann immer manuell ein?
Der Befehl zum Linken wäre:
Code:
g++ -o winappserver c:\c++\mingw\lib\libws2_32.a winappserver.o -lwsock32
Die Bibliotheken sollten in der Abhänigkeitsreihenfolge angegeben werden. Die Datei winappserver.o hängt von libwsock32 ab, deshalb sollte die Datei nach der winappserver.o auf der Kommadozeile angeben werden.

Warum kompilierst du eigentlich mit dem C++ Compiler?

Gruß

PS: Ich hab grad nochmal geschaut: ws2_32 ist die WinSock2 Bibliothek, wsock32 die WinSock 1 Bibliothek. Die Bibliotheken haben beide grundsätzlich die gleiche Schnittstelle (WinSock 2 hat mehr Funktionalität), aber der WinSock2 Bibliothek sollte der Vorzug gegeben werden.

D.h. die Zeile zum Kompilieren sieht so aus:
Code:
g++ -o winappserver winappserver.o -lws2_32
Die Reihenfolge ist wichtig!
 
Zuletzt bearbeitet:
Hallo,
deepthroat hat es wieder einmal geschafft mein Problem zu lösen.
Vielen, vielen Dank. War schon am verzweifeln.
Die Zeile zum Kompilieren musste zwar auch noch -mwindows enthalten, aber auf das -lws2_32 wär ich nie gekommen.
Wie kann man denn herausfinden, in welcher Reihenfolge die Bibliotheken und Objekte eingebunden werden müssen?
Danke nochmal deepthroat

bastionmancher
 
Wie kann man denn herausfinden, in welcher Reihenfolge die Bibliotheken und Objekte eingebunden werden müssen?
Man muss sich die Abhängigkeiten anschauen. Wenn man Funktionen aus einer Bibliothek in einer Datei xyz.c verwendet, dann hängt natürlich die Datei bzw. die daraus erstellte Objektdatei von der Bibliothek ab.

Es ist natürlich auch möglich, dass eine Bibliothek von einer anderen abhängt. Das muss man dann wissen oder irgendwo nachschlagen.

Die Abhängigkeiten seines eigenen Codes weiß man natürlich selbst am Besten.

Dann gibt es noch das Tool "nm" welches die Symbole von Bibliotheken auflisten kann, so dass man sehen kann ob die Bibliothek das gesuchte Symbol enthält oder nicht.
Code:
nm --defined-only lib/libws2_32.a | grep -i wsacleanup
00000000 I __imp__WSACleanup@0
00000000 T _WSACleanup@0
Gruß
 
Zurück