Valhalla Legends Forums Archive | C/C++ Programming | Compilation error

AuthorMessageTime
Telos
error C2440: 'type cast' : cannot convert from 'void (__stdcall SocketClient::* )(DWORD,DWORD,LPOVERLAPPED)' to 'LPOVERLAPPED_COMPLETION_ROUTINE'

Its practically the definition of LPOVERLAPPED_COMPLETION_ROUTINE the only thing I can think of is that it doesnt like the fact that the completion routine is inside of a class

Does anyone know whats causing this?
April 17, 2004, 4:51 PM
iago
Posting the problem code would be w00t
April 17, 2004, 5:14 PM
Eibro
My guess is you're trying to pass a member function as an overlapped completion routine. Can't do that, just as you can't pass a member function as a windproc. You need to make the completion routine static, and route notification to objects. Here's how I did it:
[code]class IOverlappedCompletionClientEx
{
public:
//typedef std::list< wslib::Buffer* > BufferList;
typedef std::map< WSAOVERLAPPED*, IOverlappedCompletionClientEx* > ClientMap;

public:
explicit IOverlappedCompletionClientEx( const wslib::InternetAddress& addr ) {
registerClient( this );
memset( &overlapped_, 0, sizeof( WSAOVERLAPPED ) );
this->connect( addr );
}

~IOverlappedCompletionClientEx() {
unregisterClient( this );
if ( isConnected_ )
this->disconnect( true );
}

inline bool connect( const wslib::InternetAddress& addr ) {

if ( isConnected_ ) return false;

socket_.create( SOCK_STREAM );
socket_.connect( addr );
isConnected_ = true;
this->onConnect( addr );

return true;
}

inline void disconnect( bool forceDisconnect = false ) {

if ( forceDisconnect )
{
socket_.destroy();
isConnected_ = false;

this->onDisconnect();
} else {
socket_.shutdown( SD_SEND );
}
}

inline bool isConnected() const { return isConnected_; }

protected:
virtual void onConnect( const wslib::InternetAddress& addr ) = 0;
virtual void onDisconnect() = 0;
virtual void onSendComplete( DWORD dwTransferred, DWORD dwFlags ) = 0;
virtual void onRecvComplete( DWORD dwTransferred, DWORD dwFlags ) = 0;
virtual void onError( DWORD dwErrorCode ) = 0;

protected:
wslib::InternetAddress address_;
wslib::Socket socket_;
WSAOVERLAPPED overlapped_;
bool isConnected_;

private:
static void CALLBACK staticRecvComplete( DWORD dwError, DWORD dwTransferred,
WSAOVERLAPPED* lpOverlapped, DWORD dwFlags )
{
ClientMap::iterator iter = clientMap.find( lpOverlapped );
if ( iter != clientMap.end() )
{
if ( dwError )
iter->second->onError( dwError );

if ( 0 == dwTransferred )
{
iter->second->disconnect( true );
} else {
iter->second->onRecvComplete( dwTransferred, dwFlags );
}
}
#ifdef _DEBUG
assert( iter != clientMap.end() );
#endif
}

static void CALLBACK staticSendComplete( DWORD dwError, DWORD dwTransferred,
WSAOVERLAPPED* lpOverlapped, DWORD dwFlags )
{
ClientMap::iterator iter = clientMap.find( lpOverlapped );
if ( iter != clientMap.end() )
{
if ( dwError )
iter->second->onError( dwError );

iter->second->onSendComplete( dwTransferred, dwFlags );
}
#ifdef _DEBUG
assert( iter != clientMap.end() );
#endif
}

static void registerClient( IOverlappedCompletionClientEx* c ) {
clientMap[ &c->overlapped_ ] = c;
}

static void unregisterClient( IOverlappedCompletionClientEx* c ) {
clientMap.erase( &c->overlapped_ );
}

static ClientMap clientMap;
};
[/code]
April 17, 2004, 5:31 PM
Telos
That was exactly it thanx Eibro
April 17, 2004, 5:43 PM

Search