Discussion:
[omniORB] Can't compile client that retrieves a struct which contains a sequence
Tom O'Reilly
2008-05-01 06:06:54 UTC
Permalink
Skipped content of type multipart/alternative-------------- next part --------------
A non-text attachment was scrubbed...
Name: SequenceTestIF.h
Type: application/octet-stream
Size: 7404 bytes
Desc: not available
Url : http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080430/ce7a64a5/SequenceTestIF.obj
Luke Deller
2008-05-01 07:06:12 UTC
Permalink
Hi Tom,
void foo(SequenceTestIF_var seqTest) {
SequenceTestIF::Message msg;
seqTest->setMessage(msg); // compiles OK
seqTest->getMessage(msg); // Does not compile!
}
...
Looking at the generated IDL header file, getMessage() is defined as
virtual void getMessage(SequenceTestIF::Message_out msg) = 0;
So it appears that the compiler is expecting the getMessage() parameter
SequenceTestIF::Message_out msgOut;
seqTest->getMessage(msgOut); // Still does not compile!
Not quite... here's a quote from section 4.11.2 of the C++ language mapping:

| Note that the T_out types are not intended to serve as general-purpose
| data types to be created and destroyed by applications; they are used
| only as types within operation signatures to allow necessary memory
| management side-effects to occur properly.

So you don't actually construct a Message_out instance explicitly. Basically you want to pass a reference to a pointer, so that the function can point your pointer at the returned message:

SequenceTestIF::Message *msgptr;
seqTest->getMessage(msgptr);
// now you can use msgptr->body
seqTest->setMessage(*msgptr);
delete msgptr;

Alternatively you can use the Message_var type to ease memory management:

SequenceTestIF::Message_var msg;
seqTest->getMessage(msg);
// now you can use msg->body
seqTest->setMessage(msg);
// no need to delete anything; the Message_var destructor handles it

For more details, check out the IDL C++ language mapping which is available for download from:
http://www.omg.org/technology/documents/idl2x_spec_catalog.htm

Regards,
Luke.
**********************************************************************************************
Important Note
This email (including any attachments) contains information which is confidential and may be subject to legal privilege. If you are not the intended recipient you must not use, distribute or copy this email. If you have received this email in error please notify the
sender immediately and delete this email. Any views expressed in this email are not necessarily the views of IRESS Market Technology Limited.

It is the duty of the recipient to virus scan and otherwise test the information provided before loading onto any computer system.
IRESS Market Technology Limited does not warrant that the information is free of a virus or any other defect or error.
**********************************************************************************************
Tom O'Reilly
2008-05-02 00:45:45 UTC
Permalink
Post by Luke Deller
So you don't actually construct a Message_out instance explicitly. Basically you want to pass a reference to a
SequenceTestIF::Message *msgptr;
seqTest->getMessage(msgptr);
// now you can use msgptr->body
seqTest->setMessage(*msgptr);
delete msgptr;
OK, but I'm still a bit confused. What does the server implementation code do with the passed-in msgptr, which is null (it IS null to start with, right?) Is it something like this:

Server code:

class SequenceTestServer {

void getMessage(SequenceTestIF::Message *msg() {
msg = &_message;
return; // Server encounters seg-fault after return statement.
}

// Define a Message member
SequenceTestIF::Message _message;
};



I tried something like this, but the server gets a segmentation fault after returning from getMessage().

Many thanks,
Tom
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080501/d2ff38b2/attachment.htm
Tom O'Reilly
2008-05-02 02:15:00 UTC
Permalink
Ah, I see now.
The server implementation must allocate a SequenceTestIF::Message on the heap (using new operator), since the CORBA framework will automatically try to delete it after the function call is complete - right?

Thanks,
Tom

----- Original Message -----
From: Tom O'Reilly
To: Luke Deller
Cc: omniorb-***@omniorb-support.com
Sent: Thursday, May 01, 2008 11:45 AM
Subject: Re: [omniORB] Can't compile client that retrieves a structwhichcontains a sequence
Post by Luke Deller
So you don't actually construct a Message_out instance explicitly. Basically you want to pass a reference to a
SequenceTestIF::Message *msgptr;
seqTest->getMessage(msgptr);
// now you can use msgptr->body
seqTest->setMessage(*msgptr);
delete msgptr;
OK, but I'm still a bit confused. What does the server implementation code do with the passed-in msgptr, which is null (it IS null to start with, right?) Is it something like this:

Server code:

class SequenceTestServer {

void getMessage(SequenceTestIF::Message *msg() {
msg = &_message;
return; // Server encounters seg-fault after return statement.
}

// Define a Message member
SequenceTestIF::Message _message;
};



I tried something like this, but the server gets a segmentation fault after returning from getMessage().

Many thanks,
Tom



------------------------------------------------------------------------------


_______________________________________________
omniORB-list mailing list
omniORB-***@omniorb-support.com
http://www.omniorb-support.com/mailman/listinfo/omniorb-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080501/59aca04d/attachment.htm
Clarke Brunt
2008-05-01 16:38:43 UTC
Permalink
void foo(SequenceTestIF_var seqTest) {
...etc.
Hopefully the other reply has solved the actual problem. But (and
nothing to do with the problem) I'd advise against writing methods which
take _var types as arguments. Make it "SequenceTestIF_ptr seqTest"
instead.

With the _ptr version, then if in the calling function, you've already
got an xxx_var, it's no problem - it will be correctly converted to
xxx_ptr when you make the call. And if you've already got an xxx_ptr,
then that will work too.

But with your _var version, while it will work as intended if you always
call it passing another _var, if someone called it passing an xxx_ptr
(as they'd expect to be able to do), then the _var contructor will 'eat'
the _ptr and its destructor will automatically
delete/destroy/release/whatever it when the statement completes. Which
would lead to the _ptr no longer working.

Clarke Brunt
TRAFFICMASTER PLC
UNIT 22 / ST. JOHN'S INNOVATION CENTRE
COWLEY ROAD / CAMBRIDGE / CB4 0WS
T: 01223 422469
F:
E: ***@trafficmaster.co.uk


Please consider the environment before printing this email. --------------------------------------------------------

Trafficmaster PLC is a limited Company registered in England and Wales.
Registered number: 2292714 Registered office: Martell House, University Way, Cranfield, BEDS. MK43 0TR

This message (and any associated files) is intended only for the use of omniorb-***@omniorb-support.com and may contain information that is confidential, subject to copyright or constitutes a trade secret. If you are not omniorb-***@omniorb-support.com you are hereby notified that any dissemination, copying or distribution of this message, or files associated with this message, is strictly prohibited. If you have received this message in error, please notify us immediately by replying to the message and deleting it from your computer. Any views or opinions presented are solely those of the author ***@trafficmaster.co.uk and do not necessarily represent those of the company.

Warning: Although the company has taken reasonable precautions to ensure no viruses are present in this email, the company cannot accept responsibility for any loss or damage arising from the use of this email or attachments.
--------------------------------------------------------
William Bauder
2008-05-02 21:47:58 UTC
Permalink
Look closely at the code - you're not actually returning anything (you
need *msg=&_message). You should still use the Message_out as the
parameter type, instead of Message* - you'll have less heartache down
the road.

To the best of my knowledge, only the _var and _ptr types deal with
memory management - I believe that the _out stores a copy of what you
give it, but I'm not an expert in this area by any stretch of the
imagination. What you are doing should be fine as long as you return
something (assuming that you've initialized all of _message's members
somewhere).

-Bill

-----Original Message-----
From: omniorb-list-***@omniorb-support.com
[mailto:omniorb-list-***@omniorb-support.com] On Behalf Of Tom
O'Reilly
Sent: Thursday, May 01, 2008 4:14 PM
To: Tom O'Reilly; Luke Deller
Cc: omniorb-***@omniorb-support.com
Subject: Re: [omniORB] Can't compile client that retrieves
astructwhichcontains a sequence


Ah, I see now.
The server implementation must allocate a SequenceTestIF::Message on the
heap (using new operator), since the CORBA framework will automatically
try to delete it after the function call is complete - right?

Thanks,
Tom


----- Original Message -----
From: Tom O'Reilly <mailto:***@mbari.org>
To: Luke Deller <mailto:***@iress.com.au>
Cc: omniorb-***@omniorb-support.com
Sent: Thursday, May 01, 2008 11:45 AM
Subject: Re: [omniORB] Can't compile client that retrieves a
structwhichcontains a sequence
Post by Luke Deller
So you don't actually construct a Message_out instance explicitly.
Basically you want to pass a reference to a
Post by Luke Deller
pointer, so that the function can point your pointer at the returned
SequenceTestIF::Message *msgptr;
seqTest->getMessage(msgptr);
// now you can use msgptr->body
seqTest->setMessage(*msgptr);
delete msgptr;
OK, but I'm still a bit confused. What does the server implementation
code do with the passed-in msgptr, which is null (it IS null to start
with, right?) Is it something like this:

Server code:

class SequenceTestServer {

void getMessage(SequenceTestIF::Message *msg() {
msg = &_message;
return; // Server encounters seg-fault after return
statement.
}

// Define a Message member
SequenceTestIF::Message _message;
};



I tried something like this, but the server gets a segmentation fault
after returning from getMessage().

Many thanks,
Tom




_____




_______________________________________________
omniORB-list mailing list
omniORB-***@omniorb-support.com
http://www.omniorb-support.com/mailman/listinfo/omniorb-list


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080502/c2904750/attachment.htm
William Bauder
2008-05-02 22:41:49 UTC
Permalink
Make that *msg=message - I'm not paying attention either..

-----Original Message-----
From: omniorb-list-***@omniorb-support.com
[mailto:omniorb-list-***@omniorb-support.com] On Behalf Of William
Bauder
Sent: Friday, May 02, 2008 11:48 AM
To: 'Tom O'Reilly'; 'Luke Deller'
Cc: omniorb-***@omniorb-support.com
Subject: RE: [omniORB] Can't compile client that
retrievesastructwhichcontains a sequence


Look closely at the code - you're not actually returning anything (you
need *msg=&_message). You should still use the Message_out as the
parameter type, instead of Message* - you'll have less heartache down
the road.

To the best of my knowledge, only the _var and _ptr types deal with
memory management - I believe that the _out stores a copy of what you
give it, but I'm not an expert in this area by any stretch of the
imagination. What you are doing should be fine as long as you return
something (assuming that you've initialized all of _message's members
somewhere).

-Bill

-----Original Message-----
From: omniorb-list-***@omniorb-support.com
[mailto:omniorb-list-***@omniorb-support.com] On Behalf Of Tom
O'Reilly
Sent: Thursday, May 01, 2008 4:14 PM
To: Tom O'Reilly; Luke Deller
Cc: omniorb-***@omniorb-support.com
Subject: Re: [omniORB] Can't compile client that retrieves
astructwhichcontains a sequence


Ah, I see now.
The server implementation must allocate a SequenceTestIF::Message on the
heap (using new operator), since the CORBA framework will automatically
try to delete it after the function call is complete - right?

Thanks,
Tom


----- Original Message -----
From: Tom <mailto:***@mbari.org> O'Reilly
To: Luke Deller <mailto:***@iress.com.au>
Cc: omniorb-***@omniorb-support.com
Sent: Thursday, May 01, 2008 11:45 AM
Subject: Re: [omniORB] Can't compile client that retrieves a
structwhichcontains a sequence
Post by Luke Deller
So you don't actually construct a Message_out instance explicitly.
Basically you want to pass a reference to a
Post by Luke Deller
pointer, so that the function can point your pointer at the returned
SequenceTestIF::Message *msgptr;
seqTest->getMessage(msgptr);
// now you can use msgptr->body
seqTest->setMessage(*msgptr);
delete msgptr;
OK, but I'm still a bit confused. What does the server implementation
code do with the passed-in msgptr, which is null (it IS null to start
with, right?) Is it something like this:

Server code:

class SequenceTestServer {

void getMessage(SequenceTestIF::Message *msg() {
msg = &_message;
return; // Server encounters seg-fault after return
statement.
}

// Define a Message member
SequenceTestIF::Message _message;
};



I tried something like this, but the server gets a segmentation fault
after returning from getMessage().

Many thanks,
Tom




_____




_______________________________________________
omniORB-list mailing list
omniORB-***@omniorb-support.com
http://www.omniorb-support.com/mailman/listinfo/omniorb-list


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080502/73fedb3c/attachment.htm
Loading...