创建使用 Boost ASIO 且不公开它的静态库

Posted

技术标签:

【中文标题】创建使用 Boost ASIO 且不公开它的静态库【英文标题】:Creating static library that uses Boost ASIO and does not expose it 【发布时间】:2011-09-19 19:37:48 【问题描述】:

我正在尝试创建一个使用 Boost ASIO(UDP 多播,异步)并且不公开它的库。基本上我遵循异步 udp 示例,除了我已将 io_service 对象设为库的静态私有成员。

如果直接编译成可执行文件,代码可以正常工作。如果我尝试创建一个静态库,然后在应用程序中使用它,代码会在构建我的类时抛出异常。

如果有人有示例或创建了一个使用 Boost ASIO 的库并且没有公开它并且可以发表评论,我将非常感谢您的帮助。

我还尝试将 io_service 设为类的私有成员,并尝试将其传递给构造函数。到目前为止,我尝试过的所有事情都引发了异常。

这是该库的示例代码:

#ifdef _LIB
static boost::asio::io_service asio_service;
#endif

class udpframereader

public:
    udpframereader() : m_socket(asio_service)
    
        m_packetCount = 0;
        ...
    

    unsigned long long asio_error_count();
    ...

#ifdef _LIB
private:  
    void handle_receive(const boost::system::error_code& error, std::size_t bytes_transferred);

    boost::asio::ip::udp::socket   m_socket;
    boost::asio::ip::udp::endpoint m_remote_endpoint;
    boost::array<char, 4096>       m_buffer;
    boost::crc_ccitt_type          m_crc;

    unsigned long long m_packetCount;
    ...
#endif
;

【问题讨论】:

ifdef _LIBs 是怎么回事? @bdonlan ifdef _LIB 允许我在库和使用该库的应用程序中使用相同的 .h 文件。 _LIB 在应用程序使用时未定义。此外,构造函数实际上是在一个单独的 cpp 文件中,但我复制粘贴它只是为了显示它的外观。 你遇到了什么异常? 你不能像你一样通过_LIB进行条件编译。在 C++ 中,库中 udpframereader 的类定义必须与库中用户看到的相同。除其他原因外,C++ 必须为udpframereader 的每个对象分配相同大小的数据结构。 有一个讨厌的黑客叫做Pimpl idiom。基本上,您的面向客户端的类有一个指向用户不需要的不同结构的指针。这隐藏了实现细节,但增加了运行时开销,并且库代码可能变得难以阅读。 【参考方案1】:

您不能像您展示的那样在库和应用程序之间更改类的定义;这将导致(除其他外)应用程序和库在对象的大小上存在分歧,从而在您尝试初始化这些对象时导致缓冲区溢出。

如果要隐藏对象的私有实现,请使用pImpl idiom,并且不要将实现类暴露给应用程序

【讨论】:

以上是关于创建使用 Boost ASIO 且不公开它的静态库的主要内容,如果未能解决你的问题,请参考以下文章

使用boost bind时无效使用非静态成员函数 - c ++

使用 boost::asio 通过 UDP 发送结构

Boost Asio初探

基于 Boost.ASIO 的 HTTP 客户端库(如 libcurl)[关闭]

boost库中优秀的网络库asio

Boost.Asio Win32 Windows 应用程序