2009-03-21 4 views
0
#include "stdafx.h" 
#include <windows.h> 
#include <winsock.h> 
#include <stdio.h> 

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR IpCmdLine,int nCmdShow) 
{ 
    WSADATA ws; 
    char buf[100]; 

    WSAStartup(0x0101,&ws); 

    sprintf(buf,"%d.%d",HIBYTE(ws.wVersion),LOBYTE(ws.wVersion)); 
    MessageBox(0,buf,"info",0); 
    WSACleanup(); 
    return 0; 
} 

Dieses Programm dient zum Abrufen von Informationen zur verfügbaren Wsock-Version im Computer. Ich kann nicht verstehen, warum "stdafx.h" im Programm enthalten ist. Was ist die Bedeutung von APIENTRY? Können wir statt dessen _stdcall verwenden? Ich kann es auch nicht in VC++ kompilieren. Was ist das Problem mit dem Code?Problem mit der Socket-Programmierung in c C++

Nachstehend sind die Fehler bei der Programmausführung aufgeführt. Es gibt keine Fehler beim Kompilieren.

--------------------Configuration: sa - Win32 Debug-------------------- 
Linking... 
sa.obj : error LNK2001: unresolved external symbol [email protected] 
sa.obj : error LNK2001: unresolved external symbol [email protected] 
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main 
Debug/sa.exe : fatal error LNK1120: 3 unresolved externals 
Error executing link.exe. 

sa.exe - 4 error(s), 0 warning(s) 
+0

Welche Art von Fehlern erhalten Sie? – bayda

+0

Bitte erläutern Sie das Problem, auf das Sie gestoßen sind! – Aaron

Antwort

8
  1. stdafx verwendet precompiled headers in VC++ zu implementieren. Sie können Ihre Bibliotheks-Header wie windows.h und winsock.h usw. dort einfügen und sie werden nur einmal bei jeder Änderung von stdafx.h kompiliert.

  2. APIENTRY ist normalerweise nur eine Definition für __stdcall, aber manchmal ist es leer definiert (wenn __stdcall beispielsweise nicht unterstützt wird). Es macht Ihren Code portabler.

  3. Ohne die tatsächlichen Fehler, die Sie bekommen, werde ich nicht in der Lage sein, viel zu helfen. Aber meine erste Vermutung ist, dass Sie in Ihrem Build Unicode aktiviert haben und es beschwert sich, dass MessageBoxW kein Char [100] als Argument verwendet. Verwenden Sie in diesem Fall entweder breite Zeichen oder deaktivieren Sie Unicode oder verwenden Sie MessageBoxA, um explizit die ASCII-Version zu verwenden.

Edit:

nun mit den Fehlern, es ist einfach. Fügen Sie unter Projekteigenschaften -> Linker -> Eingabe -> Zusätzliche Abhängigkeiten ws2_32.lib hinzu. So können Sie die Winsock-Funktionen verknüpft in.

Die fehlende _main gibt an, dass Sie die App als eine Konsolen-App und nicht eine Windows-App erstellen. Gehe zurück zum Projekt Eigenschaften -> Linker -> System und setze SubSystem auf Windows (/ Subsystem: Windows) anstelle von Console. Oder benennen Sie WinMain einfach in int main() um (stellen Sie sicher, dass Sie die APIENTRY löschen).

Auch wenn Sie MSVC verwenden ++ Sie könnte genauso gut die sicherere sprintf_s verwenden:

sprintf_s(buf,100,"%d.%d",HIBYTE(ws.wVersion),LOBYTE(ws.wVersion)); 
+0

Beat mich dazu. Das wollte ich sagen. :) –

+0

immer noch bekomme ich diesen Fehler -------------------- Konfiguration: sa - Win32 Debug ------------- ------- Verknüpfung ... LINK: Schwerwiegender Fehler LNK1104: Datei kann nicht geöffnet werden "odbccp32.libwin32.lib" Fehler beim Ausführen von link.exe. sa.exe - 1 Fehler, 0 Warnung (en) – paragjain

+0

Irgendwo in Ihren Optionen haben Sie ein Semikolon zwischen odbccp32.lib und win32.lib gelöscht – Eclipse

0

stdafx hat mit vorkompilierte Header in Visual Studio zu tun. Es hat nichts speziell mit dem Socket zu tun.

APIENTRY hat mit der Aufrufkonvention von WinMain zu tun, wieder sollte es nichts mit dem Socket zu tun haben.

Post-Fehler.

0

nächste
offene Projekteigenschaften versuchen, wählen Sie Linker Eigenschaften, SubItem wählt Eingang Ws2_32.lib in zusätzlichem dependecies Elemente hinzufügen vergessen Sie nicht die gleichen Konfigurationen für alle Projekt zu tun.
auch scheint es, Sie verwenden müssen int main() statt WinMain (...)

stdafx.h ändern - usualy bedeutet vorkompilierte Header VC++ Projekte
APIENTRY - Aufrufkonvention. in deinem Fall ist es __stdcall, aber manchmal könnte es auch etwas anderes bedeuten.

4

Wie für die Fehler: Sie müssen mit der Bibliothek ws2_32.lib verknüpfen. Sie können dies auf zwei Arten tun:

  1. hinzufügen es in Projekteigenschaften -> Linker -> Input -> „zusätzliche Bibliotheken“ (vergessen Sie nicht diese beiden Debug zu tun und Release-Konfigurationen).
  2. In der Kopfzeile hinzufügen, um diese Compiler-Direktive:

    #pragma comment (lib, "ws2_32.lib")

ich die zweite Methode bevorzugen, da die Änderungen, die Sie in der Quelle sichtbar zu machen sind anstatt tief in den Projektoptionen versteckt zu sein.

Wie für APIENTRY und ähnliche definiert - es ist nur eine Bequemlichkeit wie die Rückgabe von NULL anstelle von 0, um darauf hinzuweisen, dass Sie nichts anstelle einer Zahl Null zurückgeben. Erleichtert das Lesen und Verstehen von Code.

0

Soweit die Linker-Fehler betroffen sind, sollten Sie mit wsock32.lib verknüpfen.

0

Wenn der Linker beklagt, dass er _main nicht finden kann, bedeutet es, dass es versucht, Ihr Programm als eine Konsolenanwendung zu verknüpfen, was bedeutet, dass Sie main() und nicht WinMain() definieren sollten. Wenn Sie WinMain() verwenden, sollten Sie Ihre Anwendung wahrscheinlich als eine Windows-Anwendung erstellen.