2009-03-21 1 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; 
} 

Эта программа предназначена для получения информации о доступной версии wsock на компьютере. Я не могу понять, почему «stdafx.h» включен в программу. В чем смысл APIENTRY? Разве мы не можем использовать _stdcall? Я также не могу скомпилировать его в VC++. В чем проблема с кодом?проблема с программированием сокетов в c C++

Ниже приведены ошибки при выполнении программы при компиляции ошибок нет.

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

какие ошибки вы получаете? – bayda

+0

Просьба уточнить проблему, с которой вы столкнулись! – Aaron

ответ

8
  1. stdafx используется для реализации precompiled headers в VC++. Вы можете поместить свои заголовки в библиотеку, такие как windows.h и winsock.h, и т. Д. Там, и они будут скомпилированы только один раз при изменении stdafx.h.

  2. APIENTRY обычно является просто определением для __stdcall, но иногда он определяется пустым (если, например, __stdcall не поддерживается). Это сделать ваш код более портативным.

  3. Без реальных ошибок, которые вы получаете, я не смогу много помочь. Но прежде всего я предполагаю, что у вас есть unicode в вашей сборке, и он жалуется, что MessageBoxW не принимает char [100] в качестве аргумента. В этом случае либо используйте широкие символы везде, либо отключите юникод, либо используйте MessageBoxA, чтобы явно использовать версию ASCII.

Edit:

Теперь с ошибками, это легко. В разделе Свойства проекта -> Линкер -> Ввод -> Дополнительные зависимости, добавьте ws2_32.lib. Таким образом, вы можете подключить функции Winsock.

Отсутствует _main указывает, что вы создаете приложение как консольное приложение, а не приложение для Windows. Вернитесь к проекту Properties -> Linker -> System и установите SubSystem в Windows (/ Подсистема: Windows) вместо консоли. Или просто переименуйте WinMain в int main() (убедитесь, что вы отбросили APIENTRY).

Кроме того, если вы используете MSVC++ вы можете также использовать более безопасные sprintf_s:

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

Побей меня. Вот что я собирался сказать. :) –

+0

все еще я получаю эту ошибку -------------------- Конфигурация: sa - Win32 Debug ------------- ------- Ссылка ... LINK: фатальная ошибка LNK1104: невозможно открыть файл «odbccp32.libwin32.lib» Ошибка при выполнении link.exe. sa.exe - 1 error (s), 0 warning (s) – paragjain

+0

Где-то в ваших вариантах вы удалили точку с запятой между odbccp32.lib и win32.lib – Eclipse

0

stdafx имеет отношение к скомпилированных заголовков в Visual Studio. Он не имеет ничего общего с сокетом.

APIENTRY имеет отношение к вызывающему соглашению WinMain, опять же он не должен иметь ничего общего с сокетом.

Сообщение об ошибках.

0

попробовать следующие
свойства открытого проекта, выберите свойства компоновщика, выберите Input подпозиция добавить Ws2_32.lib в дополнительном пункте dependecies не забудьте сделать то же самое для всех конфигураций проекта.
также кажется, что вам нужно изменить использование Int основной() вместо WinMain (...)

stdafx.h - значит прекомпилированный обычно работают на жидком VC++ заголовка проецирует
APIENTRY - соглашение о вызове. в вашем случае это __stdcall, но иногда может означать sometihng другой.

4

Что касается ошибок: вам необходимо установить ссылку на библиотеку ws2_32.lib. Вы можете сделать это двумя способами:

  1. Добавьте его в свойствах проекта -> Linker -> Input -> «дополнительные библиотеки» (не забудьте сделать это как для отладки и выпуска конфигурации).
  2. В вашем заголовке добавить эту директиву компилятора:

    #pragma комментарий (ОМТ, «ws2_32.lib»)

Я предпочитаю второй способ, потому что изменения, внесенные видимы в источнике вместо того, чтобы скрываться глубоко в вариантах проекта.

Что касается APIENTRY и аналогичных определений - это просто удобство, как возврат NULL вместо 0, чтобы указать, что вы ничего не возвращаете вместо нулевого числа. Делает код более легким для чтения и понимания.

0

Что касается ошибок компоновщика, вы должны связаться с wsock32.lib.

0

Если компоновщик жалуется, что он не может найти _main, это означает, что он пытается связать вашу программу как консольное приложение, а это значит, что вы должны определить main(), а не WinMain(). Если у вас есть WinMain(), вероятно, вы должны создать приложение в качестве приложения Windows.