libevent: how to link it to a Windows project?

Gentlemen, I have a serious and important question, over which I have been banging my head on the keyboard for more than a week. I'm even willing to discuss a reward for someone who helps me. The question is this: I need to learn how to properly check the boxes in the linker settings for VS 2015, so that I have the libevent library linked to the c++ project (and, perhaps, build this library correctly).

Background to the question: I read a couple of motivational articles about the libevent library (for example), this one: https://habrahabr.ru/post/217437/ ). I started with the fact that I made a developer's machine for Ubuntu 16 LTS, where I put g++ and built a library from the source code for instructions from github. ( https://github.com/libevent/libevent ) Then I wrote a simple program test.cpp, in which I tried to initialize the library:

#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;
}

After a little confusion, I built this program normally with the command g++ - std=c++11-o test. ex test.cpp -levent and launched her. ./test.ex Everything works. That's great. Then I rewrote from the examples a slightly more complex example... but as soon as I started writing it myself - I needed debugging. And my native system in this sense is Windows. Well, you know... relatives are not chosen...

And under Windows, everything is not so smooth at all. First, you need to build a library from the source code. According to the instructions, I do this using 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 swears at the lack of OpenSSL when building, and there is no longer no dancing with tambourines helps: to use OpenSSL under Windows, you need to define three magic environment variables

OPENSSL_ROOT_DIR
OPENSSL_INCLUDE_DIR
OPENSSL_CRYPTO_LIBRARY

And how to define these variables is not written anywhere. Fortunately, if the door is closed, you can check the window ... libevent allows you to build yourself without OpenSSL support, adding the key-DEVENT__DISABLE_OPENSSL=on, that is, with the command cmake-DEVENT__DISABLE_OPENSSL=on-G "Visual Studio 14 2015" I am, however, a little confused by some warnings, who wrote me this command, its output can be seen here: le_pic0.jpg But *.sln file is created after you run the compiled I got a set of *.lib files in the directory Debug: event.lib event_core.lib event_extra.lib. le_pic1.jpg But then the problems started. No amount of dancing with a tambourine allows me to link these libraries to a C++ project. To complete the picture: on my system, the path to these *. lib files is C:\Programs\includes\libevent\lib\Debug I've been collecting them here: le_pic2.jpg and here: le_pic3.jpg and here: le_pic4.jpg and even here: le_pic5.jpg

At the last attempt, the illusion that something had happened was created. that is, the project was assembled normally. But on startup I instantly got an error: le_pic6.jpg

Then I made two more pathetic attempts to understand: to link (because the assembly of the obj file passes without errors, note) under Windows from the command line (the result is the same, does not see libraries) le_pic7.jpg and try to compare the contents of obj files, using the nm utility under linux, and under windows - dumpbin with the /symbols option But the difference is too big, I just see in the windows object file that the character _event_init is UNDEFined. le_pic8.jpg In general, I did not achieve success. Please help me, for example-by telling me how to define magic variables for OpenSSL (maybe the library only got the idea that it was built normally?), or by trying it yourself you may be able to build this project with this library.

Thank you in advance for your advice.

Author: S.H., 2018-02-14

2 answers

Gentlemen, thank you so much for your advice, they helped me, and especially the hint on cyberforum.ru. So, I, as a reasonable person and have already tried to run all this under linux and run it without effort - argued that there can be no question of any special initialization of winsock, because the library is the same, everything should be done in it internally! And this is exactly my opinion I wrote in response to the advice to do something with winsocket hands.

It turned out that I I was wrong.

The hint sounded like this: "Look at the example of libevent/sample/hello-world. c-you need to call it." Exactly ... Yes, I started comparing it, and in the taskmaster I found where initialization occurs in one case and does not occur in the other. It turned out that under Windows, you REALLY need to write {[2] at the very beginning of the main function]}

#ifdef _WIN32
    WSADATA wsa_data;
    WSAStartup(0x0201, &wsa_data);
#endif

As they say, it never was, and here it is again!

No, it never gets boring!

Thank you to everyone who helped me.

( my personal opinion - it is necessary to write about such things on every fence. to get out of work, you see a fence-and there it is written about vinsok under windows. )

 1
Author: S.H., 2018-02-15 01:40:06

Gentlemen, I have made new progress: as it turned out, when I build libevent, the same DLLs are created. I just didn't notice them right away. Now I copy them to the same folder where the Ekheshnik is located. Now I have the following stage: the program

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

    }

It is assembled and started, and after starting it gives an error

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.

After that, it is completed.

 0
Author: S.H., 2018-02-14 14:31:03