Я думал, что когда я устанавливаю 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>
, но мне кажется, что у меня не установлена эта библиотека. Где мне его установить?
@cristiFati Я не понимаю вопроса, я не такой уж умный. как я уже сказал, я установил gcc и mingw. отредактировал переменную пути, как показано в руководствах, использовал редактор vscode и скомпилировал в терминале с помощью команды gcc <filename>.
Дело не в том, умный или нет, а в наличии опыта работы с инструментами (а тут я вижу очень мало). В любом случае, я подробно ответил.
[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.
В мою переменную Path уже включен mingw64/bin. включение библиотеки в команду сработало, но у меня есть пара вопросов. Во-первых: почему вы используете опцию -o при компиляции? gcc main.c всегда работал у меня раньше, а не тогда, когда я также пытался включить библиотеку в командную строку. Во-вторых: кажется, я понимаю, о чем идет речь в комментарии #pragma(...), но теперь не понимаю, почему он не работает. Я имею в виду, что в вашем ответе это тоже не работает. Я просмотрел ссылку, которую вы упомянули, но так и не понял.
-o: имя выходного файла (классический вариант GCC). Я думал, что это было очевидно в выводе. Что касается #pragma, я объяснил, что он не работает для GCC.
ах, ок, теперь я все понял, спасибо
Вам не нужно включать «ws2_32.lib», только заголовки, означающие файлы, заканчивающиеся на «.h». Чтобы это работало, вам необходимо связать свой компилятор с «ws2_32.lib», потому что «winsock2.h» нуждается в этом для работы. Попробуй это:
gcc name_of_your_program.c -l ws2_32
«-l» указывает компилятору создать ссылку на то, что вы вводите дальше. Вам также не нужно писать "ws2_32.lib", подойдет "ws2_32".
Как вы создаете свой код?