[omniORB] setting return type to be an array

Svetlana G. Shasharina sveta@tech-x.txcorp.com
Mon Sep 23 20:50:01 2002


Hi Duncan,

Please ignore my previous e-mail if you got some garbage from me.
Here is my Demo.idl file:

  typedef long LongArray [3];

  interface Demo {

        LongArray doLongArray1(in LongArray xi);
        void doLongArray2(in LongArray xi);
  };


Note that the length of the array is 3.  But when I query
the IFR about this length in the client code, it gives me 2. Here 
is my client:

int run(CORBA::ORB_ptr orb) {

// Get Demo object reference
        const char* refFile = "../bridge/Demo.ref";
        ::ifstream in(refFile);
        char s[2048];
        in >> s;
        CORBA::Object_var obj0 = orb -> string_to_object(s);
        if(CORBA::is_nil(obj0)) {
                cerr << "Cannot read IOR from Demo.ref" << endl;
                return -1;
        }

// Get DynAny factory
        CORBA::Object_var obj;
        obj = orb->resolve_initial_references("DynAnyFactory");
        DynamicAny::DynAnyFactory_ptr fctry = DynamicAny::DynAnyFactory::_narrow(obj.in());


// Find out the return type
        obj = orb->resolve_initial_references("InterfaceRepository");
        CORBA::Repository_var repV = CORBA::Repository::_narrow(obj);
        CORBA::Contained_var contV = repV->lookup("Demo");
        CORBA::InterfaceDef_var interfaceV = CORBA::InterfaceDef::_narrow(contV);
        CORBA::InterfaceDef::FullInterfaceDescription_var fullInterface = interfaceV->describe_interface();
        size_t i;

        CORBA::OperationDescription method;

        for(i=0; i<fullInterface->operations.length(); ++i)
        {
                string s(fullInterface->operations[i].name);
                if(s.compare("doLongArray2") ==0) {
                        method = fullInterface->operations[i];
                        cerr << "Found the method!" << endl;
                        break;
                }
        }

        CORBA::TypeCode_var retType = method.result;

// Find out the type of the parameter
        CORBA::TypeCode_var paramType = method.parameters[0].type;
        int arraylength = paramType->content_type()->length();
        cerr <<"arraylength = " << arraylength << endl;

// Create any for the argument
        int length = 3;
        long int* x = new long int [length];
        x[0] = 1;
        x[1] = 7;
        x[2] = 8;

        obj = fctry->create_dyn_any_from_type_code(paramType);
        DynamicAny::DynArray_ptr dynArr = DynamicAny::DynArray::_narrow(obj.in());

        for (int i=0; i<length; ++i) {
                DynamicAny::DynAny_var elmnt = dynArr->current_component();
                elmnt->insert_long(x[i]);
                dynArr->next();
                cerr <<"i = " << i << endl;
        }

        CORBA::Any_var any = dynArr->to_any();

// Make request
        CORBA::Request_var req = obj0->_request("doLongArray2");
        req->add_in_arg() = any;
        req->set_return_type(retType);
        req->invoke();

        if (req->env()->exception()) {
                cerr << "Method threw an exception!" << endl;
                return -1;
        }

    return 0;
}

int main(int argc, char* argv[], char*[]) {
        int status = 0;
        CORBA::ORB_var orb;
        char** x = new char*[2];
        x[0] = "-ORBInitRef";
        x[1] = "InterfaceRepository=corbaloc::dipole.txcorp.com:50053/DefaultRepository";

        int l = 2;
        try {
                orb = CORBA::ORB_init(l, x, "omniORB4");
                status = run(orb);
        }
        catch(const CORBA::Exception& ex)
        {
                cerr <<"CORBA::exception caught in run"<<endl;
                status = -1;
        }

        if(!CORBA::is_nil(orb))
        {
                try
                {
                        orb -> destroy();
                }
                catch(const CORBA::Exception& ex)
                {
                        status = -1;
                }
        }
        delete x;
        return status;
}
/////////////////////////////////////////////////////

Here is what I get from the client:

dipole.sveta$ clientIOR
Found the method!
arraylength = 2
i = 0
i = 1
omniORB: ERROR -- the application attempted to invoke an operation
 on a nil pseudo-object reference.
CORBA::exception caught in run
dipole.sveta$ 

It is clear that when I create an any, I am trying to treat
the array as 3 dimensional, but it has become 2-dimensional
in the IFR.  I use omniifr for the interface repository.

Thanks,

Sveta Shasharina


> 
> On Monday 9 September, "Sveta Shasharina" wrote:
> 
> > After I query an Interface Repository and fugure out that the return
> > type is an array, I want to set this type to return type in my request
> > object:
> 
> OK.
> 
> > CORBA::TypeCode_var retType = method.result;
> > //I check on this to see that retType->kind() is CORBA::tk_alias
> > //and I know that it is of type
> > //typedef long LongArray [3]
> > //so I do this:
> > retType = retType->content_type();
> 
> You shouldn't need to do this, but it shouldn't hurt.
> 
> > //At this point it of kind CORBA::tk_array.
> > //After that I create request object req: skipped here
> > //And set the return type
> > 
> > req->set_return_type(retType);
> > 
> > When I try to invoke, I get an exception as if the IFR does not
> > recongnize the return type as the correct return type of the method.
> 
> What exception do you get?  The IfR is not involved at all in a DII
> call, so you can't be getting an exception from that. I've just tried
> an example, by modifying the omniORB DII example, and it works fine
> for me.
> 
> Can you post a more complete code example that shows the problem?
> 
> Cheers,
> 
> Duncan.
> 
> -- 
>  -- Duncan Grisby         --
>   -- duncan@grisby.org     --
>    -- http://www.grisby.org --
>