Références indéfinies avec bind
Bonjour,
J'ai un léger soucis à la compilation avec Boost, concernant boost::bind, dont je n'arrive pas à trouver la cause.
Voici le rapport de compilation (incomplet, mais le reste ne comporte ni warnings, ni erreurs, ...) :
Citation:
Envoyé par CMake
[ 15%] Built target ScheduleEngine
Scanning dependencies of target NetworkEngine
[ 19%] Building CXX object CommunicationClients/CMakeFiles/NetworkEngine.dir/tcp_sock.cpp.o
Linking CXX shared library ../libNetworkEngine.so
[ 34%] Built target NetworkEngine
[ 38%] Built target DbEngine
Linking CXX executable server.bin
./libNetworkEngine.so: undefined reference to `void TcpSock::async_write<EngineEvent, boost::_bi::bind_t<void, boost::_mfi::mf1<void, NetworkMachine, boost::system::error_code>, boost::_bi::list2<boost::_bi::valu
ost::_bi::bind_t<void, boost::_mfi::mf1<void, NetworkMachine, boost::system::error_code>, boost::_bi::list2<boost::_bi::value<NetworkMachine*>, boost::arg<1> (*)()> >)'
./libNetworkEngine.so: undefined reference to `void TcpSock::async_read<EngineEvent, boost::_bi::bind_t<void, boost::_mfi::mf2<void, NetworkMachine, EngineEvent, boost::system::error_code>, boost::_bi::list3<boos
st::arg<1> (*)()> > >(EngineEvent&, boost::_bi::bind_t<void, boost::_mfi::mf2<void, NetworkMachine, EngineEvent, boost::system::error_code>, boost::_bi::list3<boost::_bi::value<NetworkMachine*>, boost::_bi::value
collect2: ld a retourné 1 code d'état d'exécution
make[2]: *** [server.bin] Erreur 1
make[1]: *** [CMakeFiles/server.bin.dir/all] Erreur 2
make: *** [all] Erreur 2
Dans la classe TcpSock, j'ai bel et bien les fonctions async_write et async_read, publiques et tout et tout... Les voilà :
async_write :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| /**
* send serializable object
*\param t event to send
*/
template <typename T, typename Handler>
void TcpSock::async_write(const T& t, Handler handler) {
std::ostringstream archiveStream;
boost::archive::text_oarchive archive(archiveStream);
archive << t;
const std::string &outboundData = archiveStream.str();
boost::system::error_code error;
m_sock->write_some(boost::asio::buffer(outboundData), error);
if (error)
boost::bind(handler, error);
} |
Et async_read :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| /**
* sets a callback called when a T is received
*\param t T to receive
*\param handler callback
*/
template <typename T, typename Handler>
void TcpSock::async_read(T& t, Handler handler) {
void (TcpSock::*f)(const boost::system::error_code&, T&, boost::tuple<Handler>) = &TcpSock::handle_read<T, Handler>;
boost::asio::async_read(m_sock, boost::asio::buffer(m_networkBuffer),
boost::bind(f,
this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred, boost::ref(t), boost::make_tuple(handler)));
} |
La fonction handle_read, déclarée private, elle (ce n'est pas la source de l'erreur, vu qu'elle n'est pas utilisée par async_write, qui me pose problème aussi), est la suivante, au cas où... :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| template <typename T, typename Handler>
void TcpSock::handle_read(const boost::system::error_code& e, size_t pBytesReceived, T& t, boost::tuple<Handler> handler) {
if (e) {
boost::get<0>(handler)(t, e);
}
else {
try {
std::string strData(&m_networkBuffer[0], pBytesReceived);
std::istringstream archiveStream(strData);
boost::archive::text_iarchive archive(archiveStream);
archive >> t;
} catch (std::exception& e) {
// En cas d'échec
boost::system::error_code error(boost::asio::error::invalid_argument);
boost::get<0>(handler)(t, error);
return;
}
// On informe l'appelant que tout s'est bien passé.
boost::get<0>(handler)(t, e);
}
} |
Ces fonctions (async_read et async_write) sont utilisées de la manière suivante :
async_write :
Code:
1 2 3 4 5 6 7 8
| /**
* send event via tcp to this machine
*\param pE event to send
*/
void NetworkMachine::tcpSend(const EngineEvent& pE) {
m_tcpSock->async_write(pE, boost::bind(&NetworkMachine::handleWrite, this,
boost::asio::placeholders::error));
} |
(Où m_tcpSock est un TcpSock*)
async_read :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| /**
* massively used constructor
*\param pP pointor to parent
*\param pSo tcp socket attached to this network machine
*\param pI id for this network machine
*\param pAcctName name of the account linked with the machine
*/
NetworkMachine::NetworkMachine(NetworkEngine* pP, boost::asio::ip::tcp::socket *pSo, int pI, std::string pAcctName) : m_parent(pP), m_id(pI), m_acctName(pAcctName) {
m_tcpSock = new TcpSock(pSo);
// (...)
// set up the async reading
EngineEvent e;
m_tcpSock->async_read(e, boost::bind(&NetworkMachine::handleRead, this, e,
boost::asio::placeholders::error));
} |
Voili voilà, ça fait quelques heures que je sèche là dessus, j'ai beau chercher, je trouve rien... Si quelqu'un a la moindre piste, je suis preneur.
Merci