我很高兴编码,认为一切都很好,直到......
libtool: link: g++ -g -O2 -o bbcp bbcp-main.o bbcp-server.o bbcp-client.o bbcp-client_manager.o bbcp-bbcp.pb.o -pthread -lconfig++ /usr/lib/libprotobuf.so -lz -lpthread -lglog -L/usr/lib -lboost_thread-mt -lboost_system -pthread
bbcp-client_manager.o: In function `BBCP::Server::ClientManager::send_message(boost::shared_ptr<BBCP::Server::Client>, BBCP::Protocol::Message const&)':
/home/eax/BBCP/src/client_manager.cpp:63: undefined reference to `void BBCP::Server::Client::sendPacket<BBCP::Protocol::Message>(BBCP::Protocol::PacketType, BBCP::Protocol::Message const&)'
collect2: ld returned 1 exit status
这不是那么开心的错误让我一无所知......
client_manager.cpp:
void BBCP::Server::ClientManager::send_message(BBCP::Server::client_ptr client, BBCP::Protocol::Message const &message) {
google::protobuf::RepeatedPtrField<BBCP::Protocol::Destination> destinations = message.destination();
BBCP::Protocol::Destination *tmp;
BBCP::Protocol::Message msg = message;
std::string tmp_nickname;
client_ptr tmp_target;
int x;
if (!msg.has_sender() || msg.destination_size() == 0) {
return;
}
for (x = 0; x < msg.destination_size(); ++x) {
tmp_nickname = (destinations.Get(x)).nickname();
if ((tmp_target = get_nickname(tmp_nickname))) {
msg.clear_destination();
tmp = msg.add_destination();
tmp->set_nickname(tmp_nickname);
tmp_target->sendPacket<BBCP::Protocol::Message>(BBCP::Protocol::SINGLE_MESSAGE, msg); // this is the line of the error
}
else {
client->sendError(BBCP::Protocol::DESTINATION_UNKNOWN, tmp_nickname);
}
}
return;
}
client_ptr
等于boost::shared_ptr<BBCP::Server::Client>
。
然后我们有client.cpp:
template<class T>
void BBCP::Server::Client::sendPacket(enum BBCP::Protocol::PacketType type, T const &packet) {
std::vector<unsigned char> pbuffer;
BBCP::Protocol::Header header;
header.set_type(type);
header.set_length(packet.ByteSize());
pbuffer.resize(BBCP_HDR_MSG_SIZE + packet.ByteSize());
if (!header.SerializeToArray(&pbuffer[0], BBCP_HDR_MSG_SIZE)) {
LOG(ERROR) << "Header of type " << type << " and length " << packet.ByteSize() << " failed to serialize to array. Send aborted.";
}
else if (!packet.SerializeToArray(&pbuffer[BBCP_HDR_MSG_SIZE], packet.ByteSize())) {
LOG(ERROR) << "Packet of type " << type << " and length " << packet.ByteSize() << " failed to serialize to array. Send aborted.";
}
else {
boost::asio::async_write(*socket, boost::asio::buffer(&pbuffer[0], pbuffer.size()), boost::bind(&BBCP::Server::Client::sendPacketWriteHandler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
return;
}
此功能在BBCP::Server::Client
中以与公共成员相同的方式定义。
与往常一样,任何帮助都将受到赞赏。
儒略。
答案 0 :(得分:2)
只要您在相应的源文件中显式实例化模板,就可以在C ++源代码中定义[member]函数模板。只是在源中定义成员函数模板并在不同的源中使用它将不起作用。您可以尝试在成员函数模板的定义之后添加类似的内容:
template void BBCP::Server::Client::sendPacket<BBCP::Protocol::Message>(
BBCP::Protocol::PacketType, BBCP::Protocol::Message const &packet);
当然,这假设此时定义了BBCP::Protocol::Message
。