Господа, у меня серьезный и важный вопрос, над которым я бьюсь головой об клавиатуру уже больше недели. Я даже готов обсудить вознаграждение тому, кто мне поможет. Вопрос такой: надо меня научить правильно ставить галочки в настройках линкера под VS 2015, чтобы у меня библиотека libevent линковалась к проекту на c++ (и, возможно, правильно билдить эту библиотеку).
Предыстория вопроса: я прочитал пару мотивирующих статей насчет библиотеки libevent (напрмер, эту: https://habrahabr.ru/post/217437/ ). Начал я с того, что сделал девелоперскую машину под Ubuntu 16 LTS, куда поставл g++ и собрал библиотеку из исходников по иструкциям с гитхаба. ( https://github.com/libevent/libevent ) Потом я написал простую программу test.cpp, в которой попробовал инициализировать библиотеку:
#include <memory>
#include <cstdint>
#include <iostream>
#include <evhttp.h>
#include <string>
#include <fstream>
using namespace std;
int main(){
cout<< "Hi!" << endl ;
if ( !event_init())
cout << "Failed to init libevent." << endl;
else
cout << "libevent init successfully!" << endl;
return 0;
}
После небольшого замешательства я нормально собрал эту программу командой g++ -std=c++11 -o test.ex test.cpp -levent и запустил её. ./test.ex Всё работает. Это пркрасно. Затем я переписал из примеров немного более сложный пример... Но как только я начал писать сам - мне понадобилась отладка. И родная для меня система в этом смысле - Windows. Ну, вы понимаете... родственников не выбирают...
А под Windows все совсем не так гладко. Во первых, нужно собрать библиотеку из исходников. По инструкции я делаю это при помощи CMake:
"CMake (Windows)
Install CMake: http://www.cmake.org
$ md build && cd build
$ cmake -G "Visual Studio 10" .. # Or whatever generator you want to use
$ start libevent.sln"
Cmake при сборке ругается на отсутствие OpenSSL, и тут уже не помогают никакие танцы с бубнами: чтобы использовать OpenSSL под виндой, надо определить три магические переменные окружения
OPENSSL_ROOT_DIR
OPENSSL_INCLUDE_DIR
OPENSSL_CRYPTO_LIBRARY
а как эти переменные определять - не написано нигде. К счастью, если закрыта дверь - можно проверить окно... libevent позволяет собрать себя без поддержки OpenSSL, дописыванием ключика -DEVENT__DISABLE_OPENSSL=on, то есть командой cmake -DEVENT__DISABLE_OPENSSL=on -G "Visual Studio 14 2015" Меня, правда, немного смущают некоторые предупреждения, которые написала мне эта команда, её вывод видно здесь: Но *.sln файл создаётся, и после запуска компиляции я получил набор *.lib - файлов в директории Debug: event.lib, event_core.lib, event_extra.lib. А вот потом начались проблемы. Никакие пляски с бубном не позволяют мне прилинковать эти библиотеки к C++ проекту. Для полноты картины: в моей системе путь к этим *.lib файлам - это C:\Programs\includes\libevent\lib\Debug я засобывал их сюда: и сюда: и сюда: и даже сюда:
При последней попытке создалась иллюзия того, что что то получилось. то есть проект нормально собрался. Но при запуске я мгновенно получил ошибку:
Потом я сделал еще две жалкие попытки разобраться: слинковать (потому что сборка obj-файла проходит без ошибок, заметьте) под виндой из командной строки (результат - тот же, не видит библиотеки) и попробовать сравнить содержимой obj - файлов, воспользовавшись под линуксом утилитой nm, а под виндой - dumpbin с опцией /symbols Но разница слишком велика, я просто вижу в виндовом оьбъектном файле, что символ _event_init - UNDEFined. В общем, я не достиг успеха. Помогите, пожалуйста, например - подсказав, как определить магические переменные для OpenSSL (может, библиотека толькоприкинулась, что она нормально собрана?), или попробовав у себя собрать этот проект с этой библиотекой - возможно, у вас получится.
Заранее спасибо за советы.
Господа, большое спасибо за советы, они мне помогли, и особенно мне помогла подсказка на cyberforum.ru. Итак, я, как человек разумный и уже попробовавший запустить все это под linux и без усилий запустивший - утверждал, что ни о какой специальной инициализации winsock не может быть и речи, ведь библиотека же, в ней внутре всё должно быть сделано! И именно это своё мнение я писал в ответ на совет что то сделать с winsocket руками.
Оказалось, что я ошибался.
подсказка звучала так: "Глядите пример libevent/sample/hello-world.c — нужно вызывать." Точно... Да, стал сравнивать, и в отдадчике нашел, в каком месте в одном случае инициализация происходит, а в другом — не происходит. Оказалось, что под виндовс ДЕЙСТВИТЕЛЬНО надо в самом начале функции main написать
#ifdef _WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif
Как говорится, никогда не было, и вот опять!
Нет, это никогда не надоедает!
Спасибо всем, кто мне помогал.
( моё личное мнение - о таких вещах надо на каждом заборе писать. чтобы выходишь с работы, видишь забор - а там про винсок под винддовс написано. )
Господа, у меня появились новые успехи: как выяснилось, у меня при сборке libevent создаются таки DLL-ки. Просто я их не сразу заметил. Сейчас я их копирую в тот же фолдер, где лежит EXEшник. Сейчас у меня следующая стадия: программа
#include <memory>
#include <cstdint>
#include <iostream>
#include <evhttp.h>
using namespace std;
int main()
{
if (!event_init()) {
cout << "Failed to init libevent." << endl;
}
else {
cout << "Libevent initialised!" << endl;
char const SrvAddress[] = "192.168.10.53";
uint16_t SrvPort = 5555;
unique_ptr<evhttp, decltype(&evhttp_free)> Server(evhttp_start(SrvAddress, SrvPort), &evhttp_free);
if (!Server)
{
cout << "Failed to init http server." << std::endl;
return -1;
}
void(*OnReq)(evhttp_request *req, void *) = [](evhttp_request *req, void *)
{
auto *OutBuf = evhttp_request_get_output_buffer(req);
if (!OutBuf)
return;
evbuffer_add_printf(OutBuf, "<html><body><center><h1>Hello World! under Windows!</h1></center></body></html>");
evhttp_send_reply(req, HTTP_OK, "", OutBuf);
};
evhttp_set_gencb(Server.get(), OnReq, nullptr);
if (event_dispatch() == -1)
{
cout << "Failed to run messahe loop." << std::endl;
return -1;
}
}
return 0;
}
собирается и запускается, а после запуска выдаёт ошибку
C:\MyProjects\Cpp\LibeEx1\Debug>LibeEx1.exe
[warn] evsig_init_: socketpair: Either the application has not called
WSAStartup, or WSAStartup failed.
Libevent initialised!
[warn] socket: Either the application has not called WSAStartup, or
WSAStartup failed.
Failed to init http server.
после чего завершается.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей