Arrays as return values without _alloc() everytime? - Object
This is a discussion on Arrays as return values without _alloc() everytime? - Object ; Hi everyone,
I have a question about whether it is possible to write a method with an
array (fixed-
or variable- length shouldn't matter to this question) as a return
value.
As far as I have seen this is only ...
-
Arrays as return values without _alloc() everytime?
Hi everyone,
I have a question about whether it is possible to write a method with an
array (fixed-
or variable- length shouldn't matter to this question) as a return
value.
As far as I have seen this is only portably possible with using the
method _alloc()
and iterating through the whole array (which could be huge!) and filling
in the
values.
Below is some example code which is an extract of the relevant parts of
my code (didn't try
whether the example as such works but the complete version it comes from
does).
What I want to do is to initialize the array in the private member
'mPicture' of the 'inf_i'
object only once in its constructor and then being able to return it as
often as desired
by 'mpic()' but without making an additional copy in the method mpic()
using 'Picture_alloc()' or
something like that. However, I suspect CORBA needs _alloc() to get
control over the data and
copying it over the network, but wanted to ask you whether this is true.
But I thougt:
"When mpic() returns the 'Picture_slice*' pointer, why CORBA only seems
to copy the whole array
over the network - and not just the adress in the *server's* adress
space, which is meaningless
to the client and should not be used by it (which it does, however, if
done like in the example
below of the first entry of the array - when this pointer points to an
additional copy of
mPicture made using Picture_alloc()? Why isn't CORBA able to do the same
when just returning the
ordinary pointer to mPicture whithout using Picture_alloc()?"
Is there is a way to tell CORBA (omniORB) to copy it directly from
mPicture?
Again, when I used Picture_alloc() in the method mpic() it worked
because then CORBA seemed to
be aware of copying the array over the network in the client adress
space, allocating it there
and simultanously deallocating it in the server adress space.
But its inefficient to always Picture_alloc() a new array, iterating the
whole array to copy it
in the newly allocated space and then return that newly allocated array.
Isn't there a way (like using C++ locally, what about the promised
Location transparency
CORBA promises) to maintain the array in the private member 'mPicture'
of the 'inf_i' object
and directly copying it over the net without the additional
Picture_alloc()-copying and 'for'
iteration?
Return by value also isn't supported for arrays by C++ which would be a
possible solution which,
however, would also make the inefficient copy of the (huge!) array on
the function call stack
which is wasting both time and memory.
So, please help: Is there an efficient solution for my problem?
Thanks in advance if you are so kind for reading this.
Greetings,
Peter.
Here comes the code:
Let's consider the following IDL fragment ():
typedef octet Picture[3*320*200];
interface inf {
attribute Picture mpic;
};
omniIDL generates (besides all the other stuff, the _alloc, _free etc.
methods) something like:
class _impl_inf : public virtual omniServant
{
public:
virtual Picture_slice* mpic() = 0;
virtual void mpic(const Picture _v) = 0;
}
and class 'POA_inf' from which I derive 'inf_i' and implement the
interface:
class inf_i : public POA_inf, public
PortableServer::RefCountServantBase
{
public:
inf_i();
virtual ~inf_i() {}
virtual Picture_slice* mpic();
virtual void mpic(const Picture _v);
private:
Picture mPicture;
}
inf_i::inf_i() { //Initialize mPicture in the constructor by a for
loop}
Picture_slice* inf_i::mpic()
{
return mPicture;
}
void inf_i::mpic(const Picture _v)
{
int sizeOf_v = sizeof(Picture) / sizeof(*_v);
for( int counter = 0; counter < sizeOf_v; counter++ ) {
mPicture[counter] = _v[counter];
}
}
then in client.cxx:
int
main (int argc, char **argv)
{
try {
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
CORBA::Object_var obj = getObjectReference(orb);
inf_var infref = inf::_narrow(obj);
Picture pic;
int sizeOfpic = sizeof(pic) / sizeof(*pic);
for( int counter = 0; counter < sizeOfpic; counter++ ) {
pic[counter] = 199;
}
// setting internal array of infref to pic;
infref->myRGBPic( pic );
Picture_slice* testPic;
testPic = infref->mpic();
cout << "client.cxx.main().testPic: " << testPic[0] << endl; //
segmentation fault
}
-
Re: Arrays as return values without _alloc() everytime?
"Peter Fischer" <pfischer@ira.uka.de> wrote in message
news:40400F02.1DEF6AAF@ira.uka.de...
> What I want to do is to initialize the array in the private member
> 'mPicture' of the 'inf_i'
> object only once in its constructor and then being able to return it as
> often as desired
> by 'mpic()' but without making an additional copy in the method mpic()
> using 'Picture_alloc()' or
> something like that. However, I suspect CORBA needs _alloc() to get
> control over the data and
> copying it over the network, but wanted to ask you whether this is true.
Yes. The skeleton on the server side expects to get a pointer that it can
deallocate, and the stub on the server side returns a pointer to something
that the application is expected to deallocate.
Due to the decision to map IDL arrays to raw C++ arrays, this
allocation/deallocation is unavoidable. It would have been better
to map arrays to a C++ class. That not only would have allowed
instances of an array class to be reference counted (thereby
avoiding the allocation/deallocation in your example, at least on the
server side), but it would also have permitted bounds checking on
the array (instead of undefined behavior).
One possible way to alleviate the problem is to use a sequence instead
of an array, store the initialized sequence in the servant class, and to
then return a sequence that shares its buffer with the initialized sequence.
This will still require you to allocate the sequence, but avoids the allocation
of the sequence contents and the data copying. Have a look at the
sequence mapping for details on how to initialize a sequence with a buffer
that isn't owned by the sequence.
> But I thougt:
> "When mpic() returns the 'Picture_slice*' pointer, why CORBA only seems
> to copy the whole array
> over the network - and not just the adress in the *server's* adress
> space, which is meaningless
> to the client and should not be used by it (which it does, however, if
> done like in the example
> below of the first entry of the array - when this pointer points to an
> additional copy of
> mPicture made using Picture_alloc()? Why isn't CORBA able to do the same
> when just returning the
> ordinary pointer to mPicture whithout using Picture_alloc()?"
The problem is that the skeleton gets a return value from the operation,
and that return value has to tell the skeleton whether a deallocation is
required or not. But there is only one return value, pointer to element,
for both cases, so the skeleton can't distinguish the two cases. And,
moreover, the skeleton wouldn't have a way to distinguish, for a
particular invocation, which version of an operation you would like
to have called (the one that makes a copy of the array vs the one
that doesn't).
> Is there is a way to tell CORBA (omniORB) to copy it directly from
> mPicture?
The only way I'm aware of is to use a sequence, as I mentioned above.
Cheers,
Michi.
--
Michi Henning Ph: +61 4 1118-2700
ZeroC, Inc. http://www.zeroc.com
-
Re: Arrays as return values without _alloc() everytime?
"Michi Henning" <michi@triodia.com> wrote in message news:<QZs0c.82192$Wa.5644@news-server.bigpond.net.au>...
>
> > Is there is a way to tell CORBA (omniORB) to copy it directly from
> > mPicture?
>
> The only way I'm aware of is to use a sequence, as I mentioned above.
>
You can also use valuetype or valuebox to wrap the array, if OBV is supported.
Regards,
Ke
> Cheers,
>
> Michi.
Similar Threads
-
By Application Development in forum RUBY
Replies: 8
Last Post: 11-23-2007, 02:04 PM
-
By Application Development in forum labview
Replies: 0
Last Post: 10-17-2007, 12:10 PM
-
By Application Development in forum CSharp
Replies: 1
Last Post: 09-11-2007, 02:02 PM
-
By Application Development in forum Inetserver
Replies: 1
Last Post: 04-26-2007, 11:07 AM
-
By Application Development in forum basic.visual
Replies: 0
Last Post: 08-30-2004, 06:51 AM