RTT Methode Call-by-Reference

Hello Everyone,

I think I've already understood it in the manual. But just want to double check.

I can't use >call by reference< with The Method Interface - right?

Thanks in advance and sorry for bothering!
Johannes

RTT Methode Call-by-Reference

On Monday 11 August 2008 09:29:10 Johannes wrote:
> Hello Everyone,
>
> I think I've already understood it in the manual. But just want to double
> check.
>
> I can't use >call by reference< with The Method Interface - right?

Could you give an example of what you want to do? You can pass arguments by
reference using Methods, like

RTT::Method the_method = ... ;
int i;
the_method(i);
// now use i...

Peter

Re

Thanks for the reply!

I'm trying to call the function "static int rev(const float aW[6], float w[6],const Trans& t);" form another thread. "Trans" is a other class and represents something like your KDL::Frame.

So this is how I do it:
In my Header file:
class Math : public RTT::TaskContext {
private:
RTT::Method M_rev;
.... }

The constructor:
Math::Math(std::string n) : TaskContext(n)
, M_rev ("rev", &Math::rev , this) {
....
this->methods()->addMethod( &M_rev, "rev", "const float", "aW","const float", "nW", "Trans&", " Transformation");
...
}

Now I want to Call the method from another Thread:

{....
float jo[6], j[6];
Trans &p;

RTT::Method math_rev = math->methods()->getMethod("rev");

l = math_rev (jo, j, p);
....}

If I try to compile I get an error:
Fehler: keine Übereinstimmung für Aufruf von »(RTT::Method) (float [6], float [6], const Trans&)«
That says something like that: Can't find corresponding call
(RTT::Method) (float [6], float [6], const Trans&)

Thanks,
Johannes

Re

On Monday 11 August 2008 14:50:07 Johannes wrote:
> Thanks for the reply!
>
> I'm trying to call the function "static int rev(const float aW[6], float
> w[6],const Trans& t);" form another thread. "Trans" is a other class and
> represents something like your KDL::Frame.

So this is a 'C' function or a class function ?

I don't think I have a unit test for the const float[6] case. It's not the
const Trans& causing it, because that is tested. However, from a
multithreaded point of view, the 't' reference will not be protected when the
owner TaskContext changes it after the Method call and the calling
TaskContext reads it. Methods do not offer any protection in multi-threaded
environments.

>
> So this is how I do it:
> In my Header file:
> class Math : public RTT::TaskContext {
> private:
> RTT::Method M_rev;

This is illegal ?! You should have written:

RTT::Method M_rev;

> .... }
>
> The constructor:
> Math::Math(std::string n) : TaskContext(n)
> , M_rev ("rev", &Math::rev , this) {

If rev is static, I don't see how the 'this' is accepted. static class
functions do not require an object. For static function, you'd write
M_rev("rev", &Math::rev)

> ....
> this->methods()->addMethod( &M_rev, "rev", "const float", "aW","const
> float", "nW", "Trans&", " Transformation"); ...
> }
>
> Now I want to Call the method from another Thread:
>
>
> {....
> float jo[6], j[6];
> Trans &p;
>
> RTT::Method math_rev = math->methods()->getMethod("rev");

Same as above: You should have written:

RTT::Method math_rev = ...

>
> l = math_rev (jo, j, p);
> ....}
>
> If I try to compile I get an error:
> Fehler: keine Übereinstimmung für Aufruf von »(RTT::Method) (float [6],
> float [6], const Trans&)« That says something like that: Can't find
> corresponding call
> (RTT::Method) (float [6], float [6], const Trans&)

A first thing I would try is to drop the 'const' from the float argument (both
in Method and 'rev' function) and see if that helps. But from your code it
looks like you have more issues than this one which must be solved first.

Peter

Re

On Mon, 11 Aug 2008, Johannes wrote:

>
> I'm trying to call the function "static int rev(const float aW[6], float
> w[6],const Trans& t);" form another thread.

Okay, I see. In most operating systems, different threads do not share
their private data (stack, locally constructed data, etc), so passing a
pointer (to a function or data structure on that stack) can be
meaningless... This is one of the consequences of "component-based
programming" :-)

Herman

> "Trans" is a other class and
> represents something like your KDL::Frame.
> So this is how I do it:
> In my Header file: class Math : public RTT::TaskContext {
> private:
> RTT::Method M_rev;
> .... }
>
> The constructor: Math::Math(std::string n) : TaskContext(n)
> , M_rev ("rev", &Math::rev , this) {
> ....
> this->methods()->addMethod( &M_rev, "rev", "const float", "aW","const float",
> "nW", "Trans&", " Transformation");
> ...
> }
>
> Now I want to Call the method from another Thread:
>
> {....
> float jo[6], j[6];
> Trans &p;
>
> RTT::Method math_rev = math->methods()->getMethod("rev");
>
> l = math_rev (jo, j, p);
> ....}
>
> If I try to compile I get an error:
> Fehler: keine Übereinstimmung für Aufruf von »(RTT::Method) (float [6], float
> [6], const Trans&)«
> That says something like that: Can't find corresponding call (RTT::Method)
> (float [6], float [6], const Trans&)
>
>
> Thanks,
> Johannes
>

Re

On Monday 11 August 2008 15:51:26 Herman Bruyninckx wrote:
> On Mon, 11 Aug 2008, Johannes wrote:
> > I'm trying to call the function "static int rev(const float aW[6], float
> > w[6],const Trans& t);" form another thread.
>
> Okay, I see. In most operating systems, different threads do not share
> their private data (stack, locally constructed data, etc), so passing a
> pointer (to a function or data structure on that stack) can be
> meaningless... This is one of the consequences of "component-based
> programming" :-)

It's not said that Trans& t points to data on a thread's stack (if so, it's a
bug!). It can be part of a dynamically allocated or global object (such as a
TaskContext).

Peter

Re: Re

On Wed, 2008-08-13 07:25 sspr wrote:
>On Monday 11 August 2008 15:51:26 Herman Bruyninckx wrote:
>> On Mon, 11 Aug 2008, Johannes wrote:
>> > I'm trying to call the function "static int rev(const float aW[6], float
>> > w[6],const Trans& t);" form another thread.
>>
>> Okay, I see. In most operating systems, different threads do not share
>> their private data (stack, locally constructed data, etc), so passing a
>> pointer (to a function or data structure on that stack) can be
>> meaningless... This is one of the consequences of "component-based
>> programming" :-)
>
>It's not said that Trans& t points to data on a thread's stack (if so, it's a
>bug!). It can be part of a dynamically allocated or global object (such as a
>TaskContexti).
>
>Peter

Hello,

That's what i mean: It doesn't make sense to give the address of an array to another thread (call by reference) because he shouldn't be able to write on it.

But in my case it seams to work:
With the RTT::Method math_getAngle1 = com->methods()->getMethod("getAngles1");
I give the other thread the address of the float array - and he can manipulate the array elements. Is this coincident, a bug or a feature?

And back to my other question: That means if i want that my method returns more than just the return value - I have to use the Data Flow Interface or the Attributes and Properties Interface - right?

Sorry for bothering and thanks for the replies!
Johannes

Re

On Wednesday 13 August 2008 10:26:08 Johannes wrote:
> On Wed, 2008-08-13 07:25 sspr wrote:
> >On Monday 11 August 2008 15:51:26 Herman Bruyninckx wrote:
> >> On Mon, 11 Aug 2008, Johannes wrote:
> >> > I'm trying to call the function "static int rev(const float aW[6],
> >> > float w[6],const Trans& t);" form another thread.
> >>
> >> Okay, I see. In most operating systems, different threads do not share
> >> their private data (stack, locally constructed data, etc), so passing a
> >> pointer (to a function or data structure on that stack) can be
> >> meaningless... This is one of the consequences of "component-based
> >> programming" :-)
> >
> >It's not said that Trans& t points to data on a thread's stack (if so,
> > it's a bug!). It can be part of a dynamically allocated or global object
> > (such as a TaskContexti).
> >
> >Peter
>
> Hello,
>
> That's what i mean: It doesn't make sense to give the address of an array
> to another thread (call by reference) because he shouldn't be able to write
> on it.
>
> But in my case it seams to work:
> With the RTT::Method math_getAngle1 =
> com->methods()->getMethod("getAngles1"); I give the other thread the
> address of the float array - and he can manipulate the array elements. Is
> this coincident, a bug or a feature?

A "feature" (which you must use with care). I believe references even work
across CORBA components: After the method is executed, the 'arguments' are
notified that they may have changed and the data is sent back to the calling
component. There was quite some code required to make this work.

>
> And back to my other question: That means if i want that my method returns
> more than just the return value - I have to use the Data Flow Interface or
> the Attributes and Properties Interface - right?

Since references are supposed to work, your method may return data by
argument. However, we have been using data ports in combination with methods
to solve issues like you have now. The advantage of ports is also that they
are thread safe. So you could write data to a connected port, call a method
(with some arguments) and read the result from another data port. That's
perfectly fine.

Properties and attributes are not thread safe and do not serve this purpose,
but are best used during the configure() step.

> Sorry for bothering and thanks for the replies!

No problem !

Peter

Re

On Wed, 13 Aug 2008, Peter Soetens wrote:

> On Wednesday 13 August 2008 10:26:08 Johannes wrote:
>> On Wed, 2008-08-13 07:25 sspr wrote:
>>> On Monday 11 August 2008 15:51:26 Herman Bruyninckx wrote:
>>>> On Mon, 11 Aug 2008, Johannes wrote:
>>>>> I'm trying to call the function "static int rev(const float aW[6],
>>>>> float w[6],const Trans& t);" form another thread.
>>>>
>>>> Okay, I see. In most operating systems, different threads do not share
>>>> their private data (stack, locally constructed data, etc), so passing a
>>>> pointer (to a function or data structure on that stack) can be
>>>> meaningless... This is one of the consequences of "component-based
>>>> programming" :-)
>>>
>>> It's not said that Trans& t points to data on a thread's stack (if so,
>>> it's a bug!). It can be part of a dynamically allocated or global object
>>> (such as a TaskContexti).
>>>
>>> Peter
>>
>> Hello,
>>
>> That's what i mean: It doesn't make sense to give the address of an array
>> to another thread (call by reference) because he shouldn't be able to write
>> on it.
>>
>> But in my case it seams to work:
>> With the RTT::Method math_getAngle1 =
>> com->methods()->getMethod("getAngles1"); I give the other thread the
>> address of the float array - and he can manipulate the array elements. Is
>> this coincident, a bug or a feature?
>
> A "feature" (which you must use with care). I believe references even work
> across CORBA components: After the method is executed, the 'arguments' are
> notified that they may have changed and the data is sent back to the calling
> component. There was quite some code required to make this work.
>
>>
>> And back to my other question: That means if i want that my method returns
>> more than just the return value - I have to use the Data Flow Interface or
>> the Attributes and Properties Interface - right?
>
> Since references are supposed to work, your method may return data by
> argument. However, we have been using data ports in combination with methods
> to solve issues like you have now. The advantage of ports is also that they
> are thread safe. So you could write data to a connected port, call a method
> (with some arguments) and read the result from another data port. That's
> perfectly fine.

You should take this simple rule of thumb: _never_ use references for stuff
that works between activities/threads/components/processes... Only use them
when you are sure you will never leave the same address space.

Orocos has put so much effort in data ports because it wants to be the best
possible _component_ framework... :-)

Herman

> Properties and attributes are not thread safe and do not serve this purpose,
> but are best used during the configure() step.
>
>> Sorry for bothering and thanks for the replies!
>
> No problem !
>
> Peter
>
>
>

Re

okay that's what i thought.

So if i want that my method returns more than just the return value - I have to use the Data Flow Interface or the Attributes and Properties Interface - right?

Regards
Johannes