tags:

views:

49

answers:

2

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
}
A: 

Is PortableServer::RefCountServantBase an abstract class? Could you post its declaration?

First compilation error says Simple_i is not implementing all the abstract methods declared in the base classes. The other two compilation errors refer to methods in PortableServer::ServantBase that are not being implemented in Simple_i. I guess they are abstract methods. I note also that one of them is called invoke, and that POA_Simple declares an invoke method. That is, Simple_i is inheriting a method called invoke by two different base classes. I am not sure if this can lead to further issues.

rturrado
I Binged/googled it and did not find the class declaration of RefCountServantBase :-( .
Jagannath
You should have the source for it.
Brian Neal
A: 

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.

Brian Neal
Got you. The condition should be else if and not ifs. Is that what you are talking about the memory leak? Anyways thanks. I would look at the ORB if it had already made the change.
Jagannath
Yes, if both of those ifs got executed you would be leaking. Also watch those calls to `_tc_SimpleFactory->id()` and `_tc_Simple->id()`. Are they returning strings that you must free yourself? If so, those are leaks too.
Brian Neal