Discussion:
[omniORB] DII and struct as operation argument
Smits, Martin
2009-07-22 14:37:05 UTC
Permalink
Hi all

I am trying to write a truly dynamic client using DII which talks to a server that is using the IDL generated header and stubs.
I do this because I will ultimately not be in control of the functions in the API implemented by the server (the client is some kind of engine processing an interpreted language which can construct objects to represent calls to the server. So the input 'script' and the server are the only ones that depend on changes in the API and I don't want to recompile the client engine each time the API changes).
Currently the client doesn't use an IFR to retrieve the API operation signatures, but that will be my next step.
Still I am having a problem with this situation and am unclear how to handle passing structs to the operations correctly.

What I have done so far...
The IDL:
interface Complex {
struct add_info {
long count;
sequence<long> item_list;
};

long add(in add_info input);
}

On the client side:

- Create the _request("add")

- Create the TypeCode for the item_list sequence and the add_info struct

- Create DynamicAnys for the item_list and add_info from the TypeCodes

- Fill in the values of all the fields

- Convert the DynamicAny to an Any

- Use add_in_arg("input") to add the Any as argument

- Set the return type for the request

- Call invoke() to call the server-side function
On the server side (using the generated files from the IDL):

- Implement the virtual function which takes an 'const Complex::add_info&' as parameter

When I run the server and client program, I see an MARSHAL_SequenceIsTooLong exception thrown on the server and propagate to the client.

Running with ORBtraceLevel=40 shows that the client includes the complete TypeCode in the GIOP that goes to the server for the add() call. When I use a non-DII client program (which uses the header and stub generated from the IDL) I see that this TypeCode info is not sent to the server as part of the add() call.

What am I doing wrong here?

Some further experimenting shows two working solutions which I am not happy with (and kind of defeat the purpose of using CORBA/DII).

1. Using the Any type in the parameter list of the add() operation in the IDL, like 'long add(in Any unput)'
The problem with this is, that when I want to load the IDL in the IFR (in the future) and retrieve the operation signature, I can't see that the actual argument I have to generate is to be of the type add_info.

2. Using the following IDL: 'long add(in CORBA::TypeCode tc, in add_info input)'
Then in the server I just ignore the TypeCode parameter. I can't believe this is the OK way to handle this as it is way ugly.

Can someone enlighten me on this issue?

Greetings,
--
Martin Smits
E-Mail: ***@task24.nl

Progress isn't made by early risers. It's made by lazy men trying to find
easier ways to do something.
- Robert Heinlein

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20090722/5ec19172/attachment.htm
Duncan Grisby
2009-07-24 20:25:48 UTC
Permalink
On Wednesday 22 July, "Smits, Martin" wrote:

[...]
- Create the _request(?add?)
- Create the TypeCode for the item_list sequence and the add_info
struct
- Create DynamicAnys for the item_list and add_info from the
TypeCodes
- Fill in the values of all the fields
- Convert the DynamicAny to an Any
- Use add_in_arg(?input?) to add the Any as argument
Exactly what code are you using? From the symptoms, it looks as though
you are inserting your Any into the in arg Any -- i.e. you have an Any
inside an Any. That means the client is marshalling the request with an
Any as the argument.

I expect your code is something like this:

CORBA::Any arg = // value from the DynamicAny
CORBA::Request_var req = obj->_request("add");

req->add_in_arg() <<= arg;

That is inserting the Any into the Any that's returned by add_in_arg().
Instead, just use assignment:

req->add_in_arg() = arg;


Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Smits, Martin
2009-07-28 14:25:48 UTC
Permalink
Thanx Duncan

That was indeed the problem. Checking my other code that uses the IFR now, also uses the = operator.
I was using the example code I found in a series of articles on using the dynamic interfaces of CORBA in de DDJ. The example they implemented inserted a String in the argument and then you don't have the problem I had. And the example on the DynAny and Any only went so far as to convert the DynamicAny to the Any and then had some ...

Now I understand some more about what is going on.

Greetz,
Martin

-----Original Message-----
From: Duncan Grisby [mailto:***@grisby.org]
Sent: vrijdag 24 juli 2009 16:26
To: Smits, Martin
Cc: omniorb-***@omniorb-support.com
Subject: Re: [omniORB] DII and struct as operation argument

On Wednesday 22 July, "Smits, Martin" wrote:

[...]
- Create the _request(?add?)
- Create the TypeCode for the item_list sequence and the add_info struct
- Create DynamicAnys for the item_list and add_info from the TypeCodes
- Fill in the values of all the fields
- Convert the DynamicAny to an Any
- Use add_in_arg(?input?) to add the Any as argument
Exactly what code are you using? From the symptoms, it looks as though
you are inserting your Any into the in arg Any -- i.e. you have an Any
inside an Any. That means the client is marshalling the request with an
Any as the argument.

I expect your code is something like this:

CORBA::Any arg = // value from the DynamicAny
CORBA::Request_var req = obj->_request("add");

req->add_in_arg() <<= arg;

That is inserting the Any into the Any that's returned by add_in_arg().
Instead, just use assignment:

req->add_in_arg() = arg;


Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
Loading...