对 boost::serialization 的未定义引用
Posted
技术标签:
【中文标题】对 boost::serialization 的未定义引用【英文标题】:Undefined reference to boost::serialization 【发布时间】:2021-02-21 10:49:54 【问题描述】:我正在尝试使用 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::bind(f, this,
boost::asio::placeholders::error, boost::ref(t), handler));
template <typename T, typename Handler>
void handle_read_data(const boost::system::error_code &e,
T &t, 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 headerLength8;
std::string outboundHeader;
std::string outboundData;
char inboundHeader[headerLength];
std::vector<char> inboundData;
;
【问题讨论】:
如果你用-lboost_serialization
手动构建,可以吗?
你需要将你的 add_subdirectory(src) 移到 Boost 之后。否则未知。
我尝试了以下 g++ main.cpp src/server.cpp src/session.cpp -lboost_serialization 和同样的问题。
如果您在使用-lboost_serialization
手动构建时遇到同样的问题,我会说您的安装已损坏。
我根据 boost 文档重新安装了 boost,得到了最新的 cmake,现在手动构建工作正常,所以我认为现在 CMake 有问题。
【参考方案1】:
序列化是一个预编译库,因此您必须将它包含在您的 find 命令中:
find_package(Boost 1.65.1.0 REQUIRED system serialization)
只搜索 Boost 和 Boost::system 只会包含 boost 和系统库的头文件,而不包含序列化库的二进制文件。 它编译的原因是,序列化标头包含在 Boost::boost 中,但它无法链接,因为您没有链接到实现。
【讨论】:
我将它添加到我的根 CMakeLists,按照@vre 的建议将 add_subdirectory(src) 移到 find_package 之后,但仍然是同样的问题:/ 您正在使用 boost 的共享库,您能否测试将Boost_USE_STATIC_LIBS
更改为 ON
或确保您的 boost 二进制文件 (.dll / .so) 位于您的全局路径中.以上是关于对 boost::serialization 的未定义引用的主要内容,如果未能解决你的问题,请参考以下文章
我可以告诉 Boost.MPI 哪个类版本与 Boost.Serialization 一起使用吗?
如何为 boost::serialization 指定一个 nvp 包装器?
来自boost / serialization / vector #include的链接器错误