[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 --
>