• Welcome to Valhalla Legends Archive.
 

Compilation error

Started by Telos, April 17, 2004, 11:51 AM

Previous topic - Next topic

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?

iago

Posting the problem code would be w00t
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Eibro

#2
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:
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;
};
Eibro of Yeti Lovers.

Telos

That was exactly it thanx Eibro