Проблемы связывания Ws2_32.lib с помощью gcc

Я думал, что когда я устанавливаю gcc и mingw, эти важные библиотеки Windows уже импортируются вместе с ними. Судя по всему, нет. Как теперь передать компоновщику gcc необходимые библиотеки, чтобы он мог связать сборку этого кода?

#include <Winsock2.h>
//#include <Ws2_32.lib> why can't I type it like this?
#pragma comment(lib, "Ws2_32.lib")

void main(){
    WSADATA Winsockdata;
    WSAStartup(MAKEWORD(2,2), &Winsockdata);
    socket(AF_UNIX, SOCK_STREAM,0);
}

Я получаю следующую ошибку:

C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\pc2\AppData\Local\Temp\ccd7HYF8.o:main.c:(.text+0x24): undefined reference to `__imp_WSAStartup'

C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\pc2\AppData\Local\Temp\ccd7HYF8.o:main.c:(.text+0x3d): undefined reference to `__imp_socket'

collect2.exe: error: ld returned 1 exit status

Кажется, я видел несколько похожих вопросов, в которых говорилось, что вы можете использовать -L <pathoflibrary>, но мне кажется, что у меня не установлена ​​эта библиотека. Где мне его установить?

🤔 А знаете ли вы, что...
C компилируется в нативный код, что делает его быстрым и эффективным на большинстве аппаратных платформ.


1
56
2

Ответы:

Решено

[MS.Learn]: комментарий pragma - lib кажется специфичным для MS (VStudio) (поэтому GCC (и, возможно, другие компиляторы) игнорирует его). Точнее, компилятор добавляет комментарий в сгенерированный файл (.o, .obj), но только компоновщик MSVC интерпретирует комментарии такого типа и воздействует на них (указывая упомянутые библиотеки). Для GCC вам придется сделать это классическим способом: -l аргумент командной строки ( [GNU.GCC]: Опции для связывания).
Проверьте [SO]: эквивалент #pragma comment(lib, "xxx.lib") в Linux?подробнее.

код00.с:

#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")


int main()
{
    WSADATA wsData;
    int res = WSAStartup(MAKEWORD(2, 2), &wsData);
    printf("WSAStartup returned: %d\n", res);
    WSACleanup();
    printf("\nDone.\n\n");
    return 0;
}

Выход:

[cfati@CFATI-5510-0:e:\Work\Dev\StackExchange\StackOverflow\q078607979]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]> set _PATH=%PATH%

[prompt]> set PATH=%_PATH%;f:\Install\Qt\Qt\Tools\mingw730_64\bin

[prompt]> dir /b
main00.c

[prompt]> :: Specify the library via #pragma
[prompt]> gcc main00.c -o main00.exe
C:\Users\cfati\AppData\Local\Temp\ccT5QUCz.o:main00.c:(.text+0x24): undefined reference to `__imp_WSAStartup'
C:\Users\cfati\AppData\Local\Temp\ccT5QUCz.o:main00.c:(.text+0x47): undefined reference to `__imp_WSACleanup'
collect2.exe: error: ld returned 1 exit status

[prompt]> :: Specify the library at command line
[prompt]> gcc main00.c -o main00.exe -lWs2_32

[prompt]> dir /b
main00.c
main00.exe

[prompt]> main00.exe
WSAStartup returned: 0

Done.

Итак, вы можете смело удалить эту строку (ну, если только вы не хотите также скомпилировать ее с помощью VStudio, а не передавать библиотеку в командной строке).

P.S.: Эта библиотека (и другие, связанные с WinAPI) должна присутствовать в установке набора инструментов/эмулятора Nix (MinGW, MSYS2, Cygwin,...).

В VSCode (который вы упомянули в комментарии) вы должны добавить аргументы библиотеки в Tasks.json (список аргументов компилятора). Проверьте [ТАК]: Добавление внешней библиотеки C в код Visual Studio.


Вам не нужно включать «ws2_32.lib», только заголовки, означающие файлы, заканчивающиеся на «.h». Чтобы это работало, вам необходимо связать свой компилятор с «ws2_32.lib», потому что «winsock2.h» нуждается в этом для работы. Попробуй это:

gcc name_of_your_program.c -l ws2_32

«-l» указывает компилятору создать ссылку на то, что вы вводите дальше. Вам также не нужно писать "ws2_32.lib", подойдет "ws2_32".