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

+ Reply to Thread
Results 1 to 3 of 3

Arrays as return values without _alloc() everytime?

  1. Default 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

    }

  2. Default 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


  3. Default 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.


+ Reply to Thread

Similar Threads

  1. Two arrays: return only values that exist in both arrays?
    By Application Development in forum RUBY
    Replies: 8
    Last Post: 11-23-2007, 02:04 PM
  2. Replies: 0
    Last Post: 10-17-2007, 12:10 PM
  3. Return Arrays from a C# COM object
    By Application Development in forum CSharp
    Replies: 1
    Last Post: 09-11-2007, 02:02 PM
  4. Return an Array that contains only the diffrent items from 2 arrays
    By Application Development in forum Inetserver
    Replies: 1
    Last Post: 04-26-2007, 11:07 AM
  5. Can functions (not subs) return [control] arrays?
    By Application Development in forum basic.visual
    Replies: 0
    Last Post: 08-30-2004, 06:51 AM