"pure virtual method called", where's the bug?

Bastiaan Bakker Bastiaan.Bakker@harbinger.nl
Wed, 15 Oct 1997 16:12:05 +0200


Wow, that's a quick response!

I'll try to explain what I've been trying to do, more detailed.

I have a server, which is an instance of event::ProgressReporter and a
client which is an event::ProgressListener. The client notifies the server
it want's to receive progress reports by calling addProgressListener(...).
Once in a while the server reports to this client by calling either
acceptProgressReportAction(...) or acceptProgressReportPercentage(...).
Now, in some cases these calls fail because actually the
event::ProgressListener::acceptProgressReportAction(...) method is invoked
instead of event::_sk_ProgressListener::acceptProgressReportAction(...),
resulting in a "pure virtual method called" exception.

The client and the server are in different ORBs and the client does not
implement any other CORBA interfaces than ProgressListener (not even
interfaces derived from ProgressListener). The server on the other hand
does.

Here's the IDL description:

#include <StandardTypes.idl>

module event {
   typedef unsigned long ActionType;
   interface ProgressListener;

   interface ProgressReporter {
      void addProgressListener(in ProgressListener listener)
raises(APIRETException);
      void removeProgressListener(in ProgressListener listener)
raises(APIRETException);
   };

   interface ProgressListener {
      oneway void acceptProgressReportPercentage(in ProgressReporter
reporter, in unsigned long percentage);
      oneway void acceptProgressReportAction(in ProgressReporter reporter,
in ActionType action, in string description);
   };
};

And here is the actual implementation:

class eventImpl::ProgressReporterImpl : public virtual
event::_sk_ProgressReporter {
public:
   ProgressReporterImpl();
   virtual ~ProgressReporterImpl();
   virtual void addProgressListener(event::ProgressListener_ptr listener);

   virtual void removeProgressListener(event::ProgressListener_ptr
listener);

protected:
   virtual event::ProgressListener_ptr getProgressListener();
   virtual void sendProgressReportPercentage(CORBA::ULong percentage);
   virtual void sendProgressReportAction(event::ActionType action, const
char* description);

   //event::ProgressListener_var _listener;
   event::ProgressListener_ptr _listener;
   thread::Mutex _listenerMutex;
};

void
eventImpl::ProgressReporterImpl::addProgressListener(event::ProgressListener_ptr
listener) {
   thread::MutexGuard guard(_listenerMutex);
   {
      cerr << "adding listener" << endl;
      if (CORBA::is_nil(listener)) {
          // throw NullPointerException
         cerr << "listener is nil" << endl;
         return;
      }

      if (listener->_is_equivalent(_listener)) {
         // listener already registered
         cerr << "listener already registered" << endl;
         return;
      }

      if (CORBA::is_nil(_listener)) {
         _listener = event::ProgressListener::_duplicate(listener);
          cerr << "added exclusive listener" << endl;
          return;
      } else  {
          // throw TooManyListenersException
          cerr << "too many listeners" << endl;
          return;
      }
   }
}

void
eventImpl::ProgressReporterImpl::sendProgressReportAction(event::ActionType
action, const char* description) {
   thread::MutexGuard guard(_listenerMutex);
   {
      cerr << "send progress report action" << endl;
      if (!(CORBA::is_nil(_listener))) {
  try{
     _listener->acceptProgressReportAction(_this(), action, description);
// <<< here's the problem call
     cerr << "sent report" << endl;
  } catch(...) {
     CORBA::release(_listener);
     _listener = event::ProgressListener::_nil();
     cerr << "caught exception" << endl;
  }
      } else {
  cerr << "listener is nil" << endl;
      }
   }
   //cerr << "done sending" << endl;
}

I hope this gives enough information about what I'm trying to do. If not,
I'll try to make a simple example demonstrating the behaviour.

Regards,

Bastiaan Bakker

S.Lo@orl.co.uk wrote:

> It is not possible to deduce what is wrong from your description. Can
> you
> supply more details, do you use any interface inheritance in your call
> back
> interface, for instance?
>
> Sai-Lai
> --
> E-mail:         S.Lo@orl.co.uk          |       Olivetti & Oracle
> Research Lab
>                                         |       24a Trumpington Street
> Tel:            +44 223 343000          |       Cambridge CB2 1QA
> Fax:            +44 223 313542          |       ENGLAND