微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

对 boost::serialization 的未定义引用

如何解决对 boost::serialization 的未定义引用

我正在尝试使用 boost::asio 创建一些带有结构序列化的简单服务器。但是,在我的项目中尝试使用 boost::archives 时,我遇到了一些链接错误。我收到很多未定义的引用。你能帮我找出错误吗?

src/libserver.a(session.cpp.o): In function `boost::archive::text_iarchive::text_iarchive(std::istream&,unsigned int)':
session.cpp:(.text._ZN5boost7archive13text_iarchiveC2ERSij[_ZN5boost7archive13text_iarchiveC5ERSij]+0x25): undefined reference to `boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::text_iarchive_impl(std::istream&,unsigned int)'

我的项目结构如下:

.
├── CMakeLists.txt
├── main.cpp
└── src
    ├── CMakeLists.txt
    ├── server.cpp
    ├── server.hpp
    ├── session.cpp
    └── session.hpp

我的根 CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(mainServer)

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)

add_subdirectory(src)

find_package(Boost 1.65.1.0 required system)

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_Dirs})
    add_executable(mainServer main.cpp)
    target_link_libraries(mainServer ${Boost_LIBRARIES})
    target_link_libraries(mainServer server)
endif()

和我的 src CMakeLists.txt

add_library(
    server
    server.cpp
    session.cpp
)

set_target_properties(server PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(server PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")

以及 session.hpp 中产生链接错误代码

#pragma once

#include <boost/asio.hpp>
#include <string>
#include <deque>
#include <memory>
#include <message/message.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/bind/bind.hpp>

class Session : public std::enable_shared_from_this<Session>
{
public:
    Session(boost::asio::ip::tcp::socket socket) : socket(std::move(socket))
    {
    }

    void run();
    void printMessage(const boost::system::error_code &e);
    boost::asio::streambuf stream_buf;

private:
    boost::asio::ip::tcp::socket socket;
    common::message::Message msg;

    template <typename Handler>
    void readMsg(Handler handler)
    {
        void (Session::*f)(
            const boost::system::error_code &,common::message::Message &,boost::tuple<Handler>) = &Session::handle_read_header<common::message::Message,Handler>;
        boost::asio::async_read(socket,boost::asio::buffer(inboundHeader),boost::bind(f,this,boost::asio::placeholders::error,boost::ref(msg),boost::make_tuple(handler)));
    }

    template <typename T,typename Handler>
    void handle_read_header(const boost::system::error_code &e,T &t,boost::tuple<Handler> handler)
    {
        if (e)
        {
            boost::get<0>(handler)(e);
        }
        else
        {
            std::istringstream is(std::string(inboundHeader,headerLength));
            std::size_t inbound_data_size = 0;
            if (!(is >> std::hex >> inbound_data_size))
            {
                boost::system::error_code error(boost::asio::error::invalid_argument);
                boost::get<0>(handler)(error);
                return;
            }

            inboundData.resize(inbound_data_size);
            void (Session::*f)(
                const boost::system::error_code &,T &,boost::tuple<Handler>) = &Session::handle_read_data<T,Handler>;
            boost::asio::async_read(socket,boost::asio::buffer(inboundData),boost::ref(t),handler));
        }
    }

    template <typename T,typename Handler>
    void handle_read_data(const boost::system::error_code &e,boost::tuple<Handler> handler)
    {
        if (e)
        {
            boost::get<0>(handler)(e);
        }
        else
        {
            try
            {
                std::string archive_data(&inboundData[0],inboundData.size());
                std::istringstream archive_stream(archive_data);
                boost::archive::text_iarchive archive(archive_stream);
                archive >> t;
            }
            catch (std::exception &e)
            {
                boost::system::error_code error(boost::asio::error::invalid_argument);
                boost::get<0>(handler)(error);
                return;
            }
            boost::get<0>(handler)(e);
        }
    }

    static const size_t headerLength{8};
    std::string outboundHeader;
    std::string outboundData;
    char inboundHeader[headerLength];
    std::vector<char> inboundData;
};

解决方法

序列化是一个预构建库,因此您必须将它包含在您的 find 命令中: find_package(Boost 1.65.1.0 REQUIRED system serialization)

只搜索Boost和Boost::system只会包含boost和系统库的头文件,不包含序列化库的二进制文件。 它编译的原因是,Boost::boost 包含了序列化标头,但它无法链接,因为您没有链接到实现。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?