Разделянето на библиотека включва от програма, използваща библиотека

Създавам DLL библиотека, която ще експортира някои функции, които да се използват в други C++ проекти. В моята библиотека използвам предварително компилирани заглавки, както и Boost ASIO. Искам обаче да знам дали е възможно да съдържам всички неща, свързани с ASIO, в самата библиотека, така че другата програма да не трябва да ги включва. Например:

stdafx.h (библиотека):

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <WinSock2.h>
#include <iostream>
#include <string.h>

#pragma comment(lib, "ws2_32")

#include <boost/asio.hpp>

Client.h (библиотека):

#pragma once

#ifdef LIB_EXPORTS
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif

using boost::asio::ip::tcp;

namespace TestLib {
    class Client {
        boost::asio::io_service io_service_;
        tcp::resolver resolver_;
        tcp::socket socket_;

    public:
        LIB_API Client();

        LIB_API bool Connect(const std::string& szHost, const std::string& szPort);

        virtual ~Client();
    };
}

Въпреки това, в моята програма, която използва тази библиотека, искам да мога да включа Client.h, без да се налага да включвам и Boost ASIO. Тъй като включвам тази заглавка, без да включвам Boost ASIO, получавам грешки за всички редове в Client.h, които препращат към помощните програми на Boost, като оператора using и трите частни променливи член.

Как да създам библиотеката по такъв начин, че другата ми програма да трябва да включва само Client.h, например?


person John    schedule 17.11.2015    source източник
comment
Потърсете pimpl в този сайт. Това е един от начините да скриете подробностите за внедряването, така че да можете да премахнете зависимостите за включване.   -  person Anon Mail    schedule 17.11.2015
comment
@KryziK Съжалявам, че не прочетох внимателно последната част.   -  person Sreekar    schedule 17.11.2015


Отговори (1)


Реших проблема си с помощта на предложението на Anon Mail. Ето решението:

Client.h (библиотека):

#pragma once

#ifdef LIB_EXPORTS
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif

namespace TestLib {
    class Client {
        struct Imp;
        std::unique_ptr<Imp> imp_;

    public:
        LIB_API Client();

        LIB_API bool Connect(const std::string& szHost, const std::string& szPort);

        LIB_API virtual ~Client();
    };
}

Client.cpp (библиотека):

namespace TestLib {
    struct Client::Imp {
        Client::Imp() : 
            io_service_(new boost::asio::io_service()), 
            resolver_(new tcp::resolver(*io_service_)),
            socket_(new tcp::socket(*io_service_)) {

        }

        std::shared_ptr<boost::asio::io_service> io_service_;
        std::shared_ptr<tcp::resolver> resolver_;
        std::shared_ptr<tcp::socket> socket_;
    };

    Client::Client() : imp_(new Imp) {
    }

    bool Client::Connect(const std::string& szHost, const std::string& szPort) {
        tcp::resolver::query query(szHost, szPort);

        tcp::resolver::iterator endpoint_iter = imp_->resolver_->resolve(query);

        boost::asio::connect(*imp_->socket_, endpoint_iter);

        return true;
    }
}

Извинете ме, ако използвам грешни типове указатели. Всякакви насоки относно това решение ще бъдат много оценени!

person John    schedule 18.11.2015