Forums | Admin

Discussion Forums: help

Start New Thread Start New Thread

 

By: Paul Brannan
RE: Constructors with parameter [ reply ]  
2008-02-22 11:04
Any type conversion which does not exist can be defined (as indicated in the documentation) by defining the corresponding to_ruby<> or from_ruby<> template function.

For type conversions that don't fit this model, define a method that works on a Rice:Object type and do your own conversion, e.g.:

Rice::Object my_function(Foo const & self)
{
int x = self.my_function();
return to_ruby(x);
}

Overloaded operators that are member functions can be defined with the usual C++ syntax for member function pointers:

rb_cFoo.define_method("+", &Foo::operator+);

but overloaded operators at global scope need a cast so the function pointer can be resolved:

typedef Foo (*FooAdditionOperator)(Foo const & f);
rb_cFoo.define_method("+", FooAdditionOperator(operator+);

(I think I got that syntax right; I haven't tried to compile it).

By: Jordi p
RE: Constructors with parameter [ reply ]  
2008-02-22 05:39

So, at least for the 1.0.x series no automatic return type conversion is provided. That behavior can be improved in next releases.

What should be the syntax for defining return types?

Also, overloaded operants (I have whole bunch of them on the most basic classes) have special syntax?


By: Rubystuff.org Autobuild
RE: Constructors with parameter [ reply ]  
2008-02-22 05:21
I'll have to give this one some thought.

Rice needs to make a copy of the returned temporary on the heap in order for this function to have the right semantics. Blindly adding a conversion function that does this could have unintended side-effects, though.

You'd have the same compile error with a function that returns a const reference. I realize now, though, that the recent commit to fix your last problem has some issues -- namely, it assumes ownership of the returned pointer.

I think it makes sense to by default make a copy of returned objects, whether they are returned by reference, by pointer, or by copy. However, I can imagine libraries where the calling code takes ownership of the returned pointer (CORBA does this, for example). In that case we might want a way to override the default behavior.

I think all these issues may be why I didn't implement the conversions for return types in the first place. It's impossible to write a conversion that works correctly for every situation.

By: Jordi p
RE: Constructors with parameter [ reply ]  
2008-02-22 02:26

That problem is solved in current SVN but when an object (instead of a pointer) is returned:

public: Vector3 GetPerpendicular() const;

wrapped as:

.define_method("Perpendicular", &Vector3::GetPerpendicular)

will get the following compilation error:

/usr/local/include/rice/to_from_ruby_defn.hpp: In function ‘Rice::Object to_ruby(const T&) [with T = gazebo::Vector3]’:
/usr/local/include/rice/detail/../detail/Auto_Member_Function_Wrapper.ipp:1364: instantiated from ‘static VALUE Rice::detail::Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>::call(VALUE) [with Func_T = gazebo::Vector3 (gazebo::Vector3::*)()const, Ret_T = gazebo::Vector3, Self_T = gazebo::Vector3]’
/usr/local/include/rice/detail/../detail/Auto_Member_Function_Wrapper.ipp:1347: instantiated from ‘Rice::detail::Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>::Auto_Member_Function_Wrapper(Func_T, const Rice::detail::Exception_Handler*) [with Func_T = gazebo::Vector3 (gazebo::Vector3::*)()const, Ret_T = gazebo::Vector3, Self_T = gazebo::Vector3]’
/usr/local/include/rice/detail/../detail/wrap_function.ipp:42: instantiated from ‘Rice::detail::Wrapped_Function* Rice::detail::wrap_function(Ret_T (Self_T::*)()const, const Rice::detail::Exception_Handler*) [with Ret_T = gazebo::Vector3, Self_T = gazebo::Vector3]’
/usr/local/include/rice/detail/../detail/define_method_and_auto_wrap.ipp:16: instantiated from ‘void Rice::detail::define_method_and_auto_wrap(VALUE, const char*, Fun_T, const Rice::detail::Exception_Handler*) [with Fun_T = gazebo::Vector3 (gazebo::Vector3::*)()const]’
/usr/local/include/rice/detail/../Module_impl.ipp:66: instantiated from ‘Derived_T& Rice::Module_impl<Base_T, Derived_T>::define_method(const char*, Func_T) [with Func_T = gazebo::Vector3 (gazebo::Vector3::*)()const, Base_T = Rice::Data_Type_Base, Derived_T = Rice::Data_Type<gazebo::Vector3>]’
Model.cc:36: instantiated from here
/usr/local/include/rice/to_from_ruby_defn.hpp:67: error: no matching function for call to ‘Rice::detail::to_ruby_<gazebo::Vector3>::convert(const gazebo::Vector3&)’
/usr/local/include/rice/detail/../detail/to_ruby.ipp:4: note: candidates are: static Rice::Object Rice::detail::to_ruby_<T>::convert(T&) [with T = gazebo::Vector3]
make: *** [Model.o] Error 1

By: Jordi p
RE: Constructors with parameter [ reply ]  
2008-02-19 16:07
What I meant is how to use a C++ pointer in Ruby?

Return values are also automagic?
I have this in the Entity class:

public: void SetParent(Entity *parent);
public: Entity *GetParent() const;

I do this (lines 28 and 29 of the Model.cc file):

.define_method("Parent=", &Entity::SetParent)
.define_method("Parent", &Entity::GetParent)

and got this the following compilation error:


$ make
g++ -I. -I. -I/usr/lib64/ruby/1.8/x86_64-linux -I. -I/usr/local/include -I /usr/local/include/gazebo -I /home/jordi/source/gazebo/server/physics -I /home/jordi/source/gazebo/server/rendering -I /home/jordi/source/gazebo/server -I /home/jordi/source/gazebo/server/sensors -I /usr/include/OGRE -fPIC -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wall -fPIC -Wall -g -c Model.cc
/usr/local/include/rice/detail/../detail/to_ruby.ipp: In static member function ‘static Rice::Object Rice::detail::to_ruby_<T>::convert(const T&) [with T = gazebo::Entity*]’:
/usr/local/include/rice/to_from_ruby_defn.hpp:67: instantiated from ‘Rice::Object to_ruby(const T&) [with T = gazebo::Entity*]’
/usr/local/include/rice/detail/../detail/Auto_Member_Function_Wrapper.ipp:1364: instantiated from ‘static VALUE Rice::detail::Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>::call(VALUE) [with Func_T = gazebo::Entity* (gazebo::Entity::*)()const, Ret_T = gazebo::Entity*, Self_T = gazebo::Entity]’
/usr/local/include/rice/detail/../detail/Auto_Member_Function_Wrapper.ipp:1347: instantiated from ‘Rice::detail::Auto_Member_Function_Wrapper<Func_T, Ret_T, Self_T, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>::Auto_Member_Function_Wrapper(Func_T, const Rice::detail::Exception_Handler*) [with Func_T = gazebo::Entity* (gazebo::Entity::*)()const, Ret_T = gazebo::Entity*, Self_T = gazebo::Entity]’
/usr/local/include/rice/detail/../detail/wrap_function.ipp:42: instantiated from ‘Rice::detail::Wrapped_Function* Rice::detail::wrap_function(Ret_T (Self_T::*)()const, const Rice::detail::Exception_Handler*) [with Ret_T = gazebo::Entity*, Self_T = gazebo::Entity]’
/usr/local/include/rice/detail/../detail/define_method_and_auto_wrap.ipp:16: instantiated from ‘void Rice::detail::define_method_and_auto_wrap(VALUE, const char*, Fun_T, const Rice::detail::Exception_Handler*) [with Fun_T = gazebo::Entity* (gazebo::Entity::*)()const]’
/usr/local/include/rice/detail/../Module_impl.ipp:66: instantiated from ‘Derived_T& Rice::Module_impl<Base_T, Derived_T>::define_method(const char*, Func_T) [with Func_T = gazebo::Entity* (gazebo::Entity::*)()const, Base_T = Rice::Data_Type_Base, Derived_T = Rice::Data_Type<gazebo::Entity>]’
Model.cc:29: instantiated from here
/usr/local/include/rice/detail/../detail/to_ruby.ipp:7: error: creating array with negative size (‘no_to_ruby_conversion_defined’)
make: *** [Model.o] Error 1

By: Jason Roelofs
RE: Constructors with parameter [ reply ]  
2008-02-19 15:53
From what I see, it should be

define_constructor(Constructor<Entity, Entity*>())

As for method parameters, that is taken care of automagically. The only case you need to worry about is method overloading. Then you should follow the documentation and typedef as needed.

By: Jordi p
RE: Constructors with parameter [ reply ]  
2008-02-19 15:40

Thanks
What is it supposed to be an Entity* or any pointer in the Ruby world?

It is possible to define the parameters a method needs or return using define_method() ?
Or I need to make typedef for them (as done with overloaded functions in the rice documentation)?

By: Jason Roelofs
RE: Constructors with parameter [ reply ]  
2008-02-19 15:26
At closer look, it's the Ruby code that's the problem. You're trying to pass a FixNum (0) into the constructor that expects an Entity*. Though also, you're defining the constructor as taking an Entity when it actually takes an Entity*.

We'll be making a few changes to ensure that when a type passed in is wrong, you'll see an appropriate string error. In your case, you'll see something along the lines of "Unable to convert Fixnum to gazebo::Entity*".

By: Jordi p
RE: Constructors with parameter [ reply ]  
2008-02-19 15:16
#include "rice/Data_Type.hpp"
#include "rice/Constructor.hpp"
#include "../../Model.hh"
#include "../../Entity.hh"

using namespace Rice;
using namespace gazebo;


extern "C"
void Init_model()
{

Data_Type<Entity> rb_cEntity =
define_class<Entity>("Entity")
.define_constructor(Constructor<Entity, Entity>())
.define_method("Id", &Entity::GetId)
.define_method("ParentId", &Entity::GetParentId)
.define_method("Name", &Entity::GetName);

Data_Type<Model> rb_cModel =
define_class<Model,Entity>("Model")
.define_constructor(Constructor<Model>())
.define_method("Update", &Model::Update)
.define_method("Init", &Model::Init)
.define_method("Fini", &Model::Fini)
.define_method("Reset", &Model::Reset);
}

All the c++ classes are under the gazebo namespace.




By: Jason Roelofs
RE: Constructors with parameter [ reply ]  
2008-02-19 14:34
Could you post your full code?

By: Jordi p
Constructors with parameter [ reply ]  
2008-02-19 10:54

I think it is explained in the documentation but I don't quite understand some parts of it (I guess I need prior knowledge of the Ruby C API).

How should I manage this case?:

class Entity
{
public: Entity(Entity *parent = NULL);

};

I wrote:
Data_Type<Entity> rb_cEntity =
define_class<Entity>("Entity")
.define_constructor(Constructor<Entity, Entity>())

And I got:

irb(main):001:0> require 'model'
=> true
irb(main):002:0> Entity.new 0
RuntimeError: No conversion defined for N6gazebo6EntityE
from (irb):2:in `initialize'
from (irb):2:in `new'
from (irb):2



Other question, how are parameters in methods handled?
Thank you very much!