Discussion:
[omniORB] basic question about sequences
debutant
2008-08-05 19:25:59 UTC
Permalink
Hello,

Is it possible to use a sequence as an idl operation parameter or return
type as follows ?

typedef sequence<short> seq_type;
interface Foo
{
seq_type foo(in seq_type seq_in, out seq_type seq_out);
};

I could not write an implementation that works.

thanks!
Michel

ps: for those who read my previous post, the book will be delivered to me
tomorrow !
--
View this message in context: http://www.nabble.com/basic-question-about-sequences-tp18831089p18831089.html
Sent from the OmniORB - User mailing list archive at Nabble.com.
Michael
2008-08-05 19:47:04 UTC
Permalink
Yes it is (you cant call the method foo, cause it will clash with the
interface name though)

The C++ signature would be

seq_type* Foo_impl::bar(const seq_type& seq_in, seq_type_out seq_out)
{
std::auto_ptr<seq_type> ret(new seq_type);
ret->length(seq_in.length());
seq_out->length(seq_in.length());
for (unsigned int i=0; i<seq_in.length(); ++i)
{
seq_out[i] = seq_in[i]*2;
(*ret)[i] = seq_in[i]*3;
}
return ret.release();
}

(of course this works without auto_ptr, but it's a good habbit to
prevent memory leaks - you could also use _var and then release it, put
personally I prefer auto_ptr)
Post by debutant
Hello,
Is it possible to use a sequence as an idl operation parameter or return
type as follows ?
typedef sequence<short> seq_type;
interface Foo
{
seq_type foo(in seq_type seq_in, out seq_type seq_out);
};
I could not write an implementation that works.
thanks!
Michel
ps: for those who read my previous post, the book will be delivered to me
tomorrow !
Clarke Brunt
2008-08-05 20:01:25 UTC
Permalink
Post by Michael
...
(of course this works without auto_ptr, but it's a good habbit to
prevent memory leaks - you could also use _var and then release it, put
personally I prefer auto_ptr)
Just to be awkward, I take the opposite view and use _var (well we _are_
using CORBA anyway) :-)

So if you want to take the _var route, then
seq_type_var ret = new seq_type; // as first line of implementation
ret[i] = whatever; // don't want a '*' here
return ret._retn(); // as last line
// other lines the same

And, without taking the time to remind myself of all the detail of this,
isn't it necessary also to create a new sequence for the 'out' parameter? I
would have thought it likely to contain a NULL otherwise.
Michael
2008-08-05 20:13:52 UTC
Permalink
Since we're using auto_ptr, boost::shared_ptr etc. a lot everywhere, I
personally prefer it the other way round :)
(actually I use a lot of STL constructs and have a little template
library for converting everything on return).

Anyway, you're right about initializing the out parameter, there
should've been be a line

seq_out = new seq_type;

in my example (but seq_out will never be NULL (but nil :)).

I just grepped through my codebase, and it appears I used out parameters
twice in 5 years :) I generally prefer returning structs/sequences
whatever, because out parameters make me feel ... bad inside :)

cheers
michael
Post by Clarke Brunt
Post by Michael
...
(of course this works without auto_ptr, but it's a good habbit to
prevent memory leaks - you could also use _var and then release it, put
personally I prefer auto_ptr)
Just to be awkward, I take the opposite view and use _var (well we _are_
using CORBA anyway) :-)
So if you want to take the _var route, then
seq_type_var ret = new seq_type; // as first line of implementation
ret[i] = whatever; // don't want a '*' here
return ret._retn(); // as last line
// other lines the same
And, without taking the time to remind myself of all the detail of this,
isn't it necessary also to create a new sequence for the 'out' parameter? I
would have thought it likely to contain a NULL otherwise.
_______________________________________________
omniORB-list mailing list
http://www.omniorb-support.com/mailman/listinfo/omniorb-list
Clarke Brunt
2008-08-05 19:51:33 UTC
Permalink
Of course it's possible.

While waiting for your book (and still useful even after you've got the
book) get the specification of the C++ language mapping for CORBA from
http://www.omg.org/ which will tell you how in/out/return arguments for all
the different types are passed. (Or if you're using some other language,
then the equivalent spec for it). Looking at the code generated by omniidl
ought also to give you a clue about the implementation. I don't think you
stand much chance by using guesswork.
debutant
2008-08-06 01:57:04 UTC
Permalink
Thank you Michael, thank you Clarke !

I tried first:

seq_type* Foo_impl::bar(const seq_type& seq_in)
{
std::auto_ptr<seq_type> ret(new seq_type);
ret->length(seq_in.length());
for (unsigned int i=0; i<seq_in.length(); ++i)
{
(*ret)[i] = seq_in[i]*3;
}
return ret.release();
}

and it works well.

then I tried:

void Foo_impl::bar(const seq_type& seq_in, seq_type_out seq_out)
{
seq_out->length(seq_in.length());
for (unsigned int i=0; i<seq_in.length(); ++i)
{
seq_out[i] = seq_in[i]*2;
}
}

Line (3) gives me a problem (segmentation fault) (and (6) too).

I looked at the .hh file generated by the idl compilation and saw:

class seq_type_out {
...
inline seq_type* operator->() { return _data; }
...
}

I tried:

(seq_out.operator->())->length(seq_in.length());

and got the same problem.

It seems that there is something wrong with the class seq_type_out ...

Thanks a lot for your help. I am still full of hope !
Sincerely,
Michel
--
View this message in context: http://www.nabble.com/basic-question-about-sequences-tp18831089p18838737.html
Sent from the OmniORB - User mailing list archive at Nabble.com.
Michael
2008-08-06 02:12:06 UTC
Permalink
Hi Michel,
Post by Michael
Anyway, you're right about initializing the out parameter, there
should've been be a line
seq_out = new seq_type;
in my example
so

void Foo_impl::bar(const seq_type& seq_in, seq_type_out seq_out)
{
seq_out = new seq_type;
seq_out->length(seq_in.length());
for (unsigned int i=0; i<seq_in.length(); ++i)
{
seq_out[i] = seq_in[i]*2;
}
}

should work ok
Post by Michael
Thank you Michael, thank you Clarke !
seq_type* Foo_impl::bar(const seq_type& seq_in)
{
std::auto_ptr<seq_type> ret(new seq_type);
ret->length(seq_in.length());
for (unsigned int i=0; i<seq_in.length(); ++i)
{
(*ret)[i] = seq_in[i]*3;
}
return ret.release();
}
and it works well.
void Foo_impl::bar(const seq_type& seq_in, seq_type_out seq_out)
{
seq_out->length(seq_in.length());
for (unsigned int i=0; i<seq_in.length(); ++i)
{
seq_out[i] = seq_in[i]*2;
}
}
Line (3) gives me a problem (segmentation fault) (and (6) too).
class seq_type_out {
...
inline seq_type* operator->() { return _data; }
...
}
(seq_out.operator->())->length(seq_in.length());
and got the same problem.
It seems that there is something wrong with the class seq_type_out ...
Thanks a lot for your help. I am still full of hope !
Sincerely,
Michel
debutant
2008-08-06 02:33:23 UTC
Permalink
I am sorry about that !
It works perfectly well !!!

Thank you very much Michael.
Michel
--
View this message in context: http://www.nabble.com/basic-question-about-sequences-tp18831089p18839364.html
Sent from the OmniORB - User mailing list archive at Nabble.com.
Loading...