Search code examples
c++corba

Compilation errors when inheriting PortableServer::RefCountServantBase


I am working on a corba application where in create_servant() method we are creating new servant and returning it to the callee. To make the memory management easier, I am inheriting PortableServer::RefCountServantBase class to the implementation class.
I get the below compilation errors.

"simples.cpp", line 108: Error: Cannot create a variable for abstract class Simple_i.
"simples.cpp", line 108: Error: PortableServer::ServantBase::invoke(CORBA::ServerRequest*) has not been overridden.
"simples.cpp", line 108: Error: PortableServer::ServantBase::_primary_interface(const PortableServer::ObjectId&, PortableServer::POA*) has not been overridden.
3 Error(s) detected.

If I don't inherit RefCountServantBase I don't get any compilation errors. In samples.cpp, which is not shown here we are creating an instance of sample_i and returning it.

Here is the sample code:

// sample_i.h

#include "simple_s.h"
extern char* generate_unique_id();           // Generate unique uuids

class Simple_i : public virtual POA_Simple
                 , virtual public PortableServer::RefCountServantBase
{
  public:
    virtual char* to_lower(const char* val);
    virtual void  to_upper(char*&      val);
    virtual char* to_print(const char* val);
};

class SimpleFactory_i : public virtual POA_SimpleFactory
                        // , virtual public PortableServer::RefCountServantBase
{
  public:
    virtual Simple_ptr find_simple();

    // To make simpapp scalable have the SimpleFactory use the user
    // supplied identifier in the Simple object reference it creates.
};

================================================================================ // sample_s.h

#include <string.h>
#include "orbminor.h"
#include <Tobj_ServantBase.h>

#include "simple_c.h"

class POA_Simple : public Tobj_ServantBase 
{
    public:

        virtual ::CORBA::Char * to_lower (
            const char * str) = 0; 

        virtual void to_upper (
            ::CORBA::Char *& str) = 0; 

        virtual ::CORBA::Char * to_print (
            const char * str) = 0; 

        ::Simple_ptr _this();

        void invoke (::CORBA::ServerRequest_ptr _nasreq);

        ::CORBA::RepositoryId _primary_interface (
        const PortableServer::ObjectId &,
            PortableServer::POA_ptr);

    protected:
        virtual ~POA_Simple(){ }

    private:
        OBBArgument *getparams (::CORBA::Short, OBB::ServerRequest * SrvReq, ::CORBA::ULong & ArgCnt);

};
class POA_SimpleFactory : public Tobj_ServantBase 
{
    public:

        virtual ::Simple_ptr find_simple () = 0; 

        ::SimpleFactory_ptr _this();

        void invoke (::CORBA::ServerRequest_ptr _nasreq);

        ::CORBA::RepositoryId _primary_interface (
        const PortableServer::ObjectId &,
            PortableServer::POA_ptr);

    protected:
        virtual ~POA_SimpleFactory(){ }

    private:
        OBBArgument *getparams (::CORBA::Short, OBB::ServerRequest * SrvReq, ::CORBA::ULong & ArgCnt);

};
#endif

Update: I changed the inheritance and did not inherit PortableServer::RefCountServantBase, since RefCountServantBase itself is getting inherited by Tobj_ServantBase.
Now, I have the code as below. Is this fine? Do I need to care about memory management here ? Or am I missing something?

Tobj_Servant Server::create_servant(const char* intf_repos_id)
{
    Tobj_Servant servant = NULL;
    if (!strcmp(intf_repos_id, _tc_SimpleFactory->id())) {

        servant = new SimpleFactory_i();
    }
    if (!strcmp(intf_repos_id, _tc_Simple->id())) {
        servant = new Simple_i();
    }

    servant->_add_ref();
    return servant; // unknown interface
}

Solution

  • In newer versions of CORBA, RefCountServantBase is deprecated. You no longer need to inherit from it because the auto-generated C++ servants now provide the same functionality. You should verify that the ORB you are using has implemented this change.

    As to the part of your question about your create_servant() function. It should be fine from the servant creation aspect. However it looks strange that you can assign multiple things to your servant variable. If this happened you would leak.

    I also can't say about _tc_SimpleFactory->id() or _tc_Simple->id() because I'm not familiar with those functions. If they return CORBA strings then you are leaking memory.