制作Boost::Asio chat的头文件“服务器示例为我提供了”;找到一个或多个已定义符号;错误 我是C++和Boost库的新手,尝试从这个例子中学习三个单独的文件来学习头文件。 chat_message.hpp在这里,尽管我认为这不会导致问题
目标是将示例分为三个部分制作Boost::Asio chat的头文件“服务器示例为我提供了”;找到一个或多个已定义符号;错误 我是C++和Boost库的新手,尝试从这个例子中学习三个单独的文件来学习头文件。 chat_message.hpp在这里,尽管我认为这不会导致问题,c++,sockets,boost,header,boost-asio,C++,Sockets,Boost,Header,Boost Asio,目标是将示例分为三个部分 main.cpp chat_server.h-用于声明的头文件 chat_server.cpp-实现 这是我的实现,但我得到两个错误 错误列表- 输出 Build started... 1>------ Build started: Project: main, Configuration: Debug Win32 ------ 1>main.obj : error LNK2005: "void __cdecl boost::asio::dummy
Build started...
1>------ Build started: Project: main, Configuration: Debug Win32 ------
1>main.obj : error LNK2005: "void __cdecl boost::asio::dummy_return<void>(void)" (??$dummy_return@X@asio@boost@@YAXXZ) already defined in chat_server.obj
1>C:\Users\Offline User\source\repos\main\Debug\main.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Done building project "main.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
已开始生成。。。
1> ----构建已启动:项目:主,配置:调试Win32------
1> main.obj:错误LNK2005:“void uu cdecl boost::asio::dummy u return(void)”(??$dummy_return@X@asio@boost@@YAXXZ)已在chat_server.obj中定义
1> C:\Users\Offline User\source\repos\main\Debug\main.exe:致命错误LNK1169:找到一个或多个多重定义符号
1> 已完成生成项目“main.vcxproj”--失败。
======生成:0成功,1失败,0最新,0跳过==========
示例代码在分成三部分之前运行良好。
我不知道这是否与typedef或virtual有关,因为其他类和方法对我来说非常简单(从我在网上学到的内容)。请帮帮我,让我知道我错过了什么??谢谢
#包括“chat_server.h”
int main(int argc,char*argv[])
{
尝试
{
如果(argc<2)
{
std::cerr start();
}
你接受吗;
});
}
请参见
include/boost/asio/impl/use\u waitiable.hpp
有一个错误,dummy\u return
应该标记为inline
更改:
template <>
void dummy_return()
{
}
模板
无效虚拟_返回()
{
}
致:
模板
内联void dummy_return()
{
}
应避免在头文件中使用命名空间
,请发布完整的编译器错误输出。我无法在聊天服务器.h
中发现头保护。你有吗,你只是不在这里?如果不这样做,很可能在链接阶段会出现多个定义错误。@πάνταῥεῖ 缺少包含保护通常会导致编译器而不是链接器的多个定义错误。由于该文件在每个cpp文件中只包含一次,因此不应导致problem@AlanBirtles哦,是的。我的错。如果没有其他证明,最有可能是OP的问题。@AlanBirtles我在帖子中编辑了错误列表。如果格式不对,我很抱歉。我把boost::asio::dummy\u return
放进了谷歌,这是最热门的结果之一(实际上是链接到asio-PR的)。将错误消息粘贴到google(最好是从编译器输出,而不是IDE错误列表)通常可以解决您的问题。
#include "chat_server.h"
int main(int argc, char* argv[])
{
try
{
if (argc < 2)
{
std::cerr << "Usage: chat_server <port> [<port> ...]\n";
return 1;
}
boost::asio::io_context io_context;
std::list<chat_server> servers;
for (int i = 1; i < argc; ++i)
{
tcp::endpoint endpoint(tcp::v4(), std::atoi(argv[i]));
servers.emplace_back(io_context, endpoint);
}
io_context.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
#ifndef CHAT_SERVER_H
#define CHAT_SERVER_H
#include <cstdlib>
#include <deque>
#include <iostream>
#include <list>
#include <memory>
#include <set>
#include <utility>
#include <boost/asio.hpp>
#include "chat_message.hpp"
using boost::asio::ip::tcp;
//----------------------------------------------------------------------
typedef std::deque<chat_message> chat_message_queue;
//----------------------------------------------------------------------
class chat_participant
{
public:
virtual ~chat_participant() {};
virtual void deliver(const chat_message& msg) = 0;
};
typedef std::shared_ptr<chat_participant> chat_participant_ptr;
//----------------------------------------------------------------------
class chat_room
{
public:
void join(chat_participant_ptr participant);
void leave(chat_participant_ptr participant);
void deliver(const chat_message& msg);
private:
std::set<chat_participant_ptr> participants_;
enum { max_recent_msgs = 100 };
chat_message_queue recent_msgs_;
};
//----------------------------------------------------------------------
class chat_session
: public chat_participant,
public std::enable_shared_from_this<chat_session>
{
public:
chat_session(tcp::socket socket, chat_room& room);
void start();
void deliver(const chat_message& msg);
private:
void do_read_header();
void do_read_body();
void do_write();
tcp::socket socket_;
chat_room& room_;
chat_message read_msg_;
chat_message_queue write_msgs_;
};
//----------------------------------------------------------------------
class chat_server
{
public:
chat_server(boost::asio::io_context& io_context,
const tcp::endpoint& endpoint);
private:
void do_accept();
tcp::acceptor acceptor_;
chat_room room_;
};
#endif
#include "chat_server.h"
void chat_room::join(chat_participant_ptr participant)
{
participants_.insert(participant);
for (auto msg : recent_msgs_)
participant->deliver(msg);
}
void chat_room::leave(chat_participant_ptr participant)
{
participants_.erase(participant);
}
void chat_room::deliver(const chat_message& msg)
{
recent_msgs_.push_back(msg);
while (recent_msgs_.size() > max_recent_msgs)
recent_msgs_.pop_front();
for (auto participant : participants_)
participant->deliver(msg);
}
//----------------------------------------------------------------------
chat_session::chat_session(tcp::socket socket, chat_room& room)
: socket_(std::move(socket)),
room_(room)
{
}
void chat_session::start()
{
room_.join(shared_from_this());
do_read_header();
}
void chat_session::deliver(const chat_message& msg)
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress)
{
do_write();
}
}
void chat_session::do_read_header()
{
auto self(shared_from_this());
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(), chat_message::header_length),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if (!ec && read_msg_.decode_header())
{
do_read_body();
}
else
{
room_.leave(shared_from_this());
}
});
}
void chat_session::do_read_body()
{
auto self(shared_from_this());
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.body(), read_msg_.body_length()),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
room_.deliver(read_msg_);
do_read_header();
}
else
{
room_.leave(shared_from_this());
}
});
}
void chat_session::do_write()
{
auto self(shared_from_this());
boost::asio::async_write(socket_,
boost::asio::buffer(write_msgs_.front().data(),
write_msgs_.front().length()),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
write_msgs_.pop_front();
if (!write_msgs_.empty())
{
do_write();
}
}
else
{
room_.leave(shared_from_this());
}
});
}
//----------------------------------------------------------------------
chat_server::chat_server(boost::asio::io_context& io_context,
const tcp::endpoint& endpoint)
: acceptor_(io_context, endpoint)
{
do_accept();
}
void chat_server::do_accept()
{
acceptor_.async_accept(
[this](boost::system::error_code ec, tcp::socket socket)
{
if (!ec)
{
std::make_shared<chat_session>(std::move(socket), room_)->start();
}
do_accept();
});
}
template <>
void dummy_return()
{
}
template <>
inline void dummy_return()
{
}