【发布时间】: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 headerLength{8};
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 有问题。