[C++-sig] Py++ - one header file including all project header files
Hello, I'm attempting to create python module for CREAM Client API (http://grid.pd.infn.it/cream/). After reading Py++ "best practices" I tried to include all needed headers into one and then add it to Py++. But then the resulting .cpp file doesn't have any wrappers inside, only for one function which was declared directly in that one header file. What is possibly wrong in my approach? Here are the scripts based on pyogre project: http://fatcat.ftj.agh.edu.pl/~sitarzm/pycream/pycream_module_20100317.tar.bz2 Thanks, -- Maciek Sitarz ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Py++ - one header file including all project header files
On Wed, Mar 17, 2010 at 9:38 AM, Maciej Sitarz wrote: > Hello, > > I'm attempting to create python module for CREAM Client API > (http://grid.pd.infn.it/cream/). > > After reading Py++ "best practices" I tried to include all needed headers > into one and then add it to Py++. But then the resulting .cpp file doesn't > have any wrappers inside, only for one function which was declared directly > in that one header file. > > What is possibly wrong in my approach? Nothing, really. Please take a look on the following document: http://language-binding.net/pyplusplus/documentation/tutorials/module_builder/module_builder.html#declarations-customization and let me know whether is makes sense to you. If not come back and we will resolve the issue -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Ownership of a C++ object extended in Python using wrapper
Alexandre Hamez wrote: > > On 16 mars 2010, at 13:12, Neal Becker wrote: > >> Alexandre Hamez wrote: >> >>> Hi all, >>> >>> I have a C++ library that needs to store in a hash map user's code, that >>> is, Python-extended objects. To make the C++ interface available to >>> Python, I use boost::python::wrapper, as stated in the tutorial >>> >> (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). >>> Because I store this extend objects, I need to tell Python that I've got >>> a reference on these objects. >>> A thread from 2007 >>> (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) >>> states there is a problem for this particular use case, but in the end, >>> no solution is given. So my question is the following: as of today, what >>> is >>> the correct way to tell Python we hold a reference to Python extend >>> objects of C++ classes, using the boost::python::wrapper mechanism? >>> >>> Thanks, >>> - >>> Alexandre Hamez >> > > Thanks for answering so quickly. >> I've use 2 methods: >> >> 1) with_custodian_and_ward > OK, I didn't think of this method. Seems a good way to do it. > >> 2) boost::shared_ptr > > For this point, do you mean you just take the objects that should seen > they references increased by a shared_ptr? Just after having asked this > question, I tried with this simple solution, and it seems to work. I hope > there is no hidden potential crash :-) > > Do you use these two methods conjointly in the same project? Or did you > identify some use cases which favor a method rather the other one? > Looking at some of my old code, I'd say I used one method or the other depending on the phase of the moon. Haven't mixed them (sounds like a bad idea). ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Ownership of a C++ object extended in Python using wrapper
On 16 mars 2010, at 22:21, Jim Bosch wrote: > On Tue, 2010-03-16 at 20:56 +0100, Alexandre Hamez wrote: >> On 16 mars 2010, at 13:12, Neal Becker wrote: >> >>> Alexandre Hamez wrote: >>> Hi all, I have a C++ library that needs to store in a hash map user's code, that is, Python-extended objects. To make the C++ interface available to Python, I use boost::python::wrapper, as stated in the tutorial >>> (http://www.boost.org/doc/libs/1_42_0/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions). Because I store this extend objects, I need to tell Python that I've got a reference on these objects. A thread from 2007 (http://mail.python.org/pipermail/cplusplus-sig/2007-March/011790.html) states there is a problem for this particular use case, but in the end, no solution is given. So my question is the following: as of today, what is the correct way to tell Python we hold a reference to Python extend objects of C++ classes, using the boost::python::wrapper mechanism? Thanks, - Alexandre Hamez >>> >> >> Thanks for answering so quickly. >>> I've use 2 methods: >>> >>> 1) with_custodian_and_ward >> OK, I didn't think of this method. Seems a good way to do it. >> >>> 2) boost::shared_ptr >> >> For this point, do you mean you just take the objects that should seen they >> references increased by a shared_ptr? Just after having asked this question, >> I tried with this simple solution, and it seems to work. I hope there is no >> hidden potential crash :-) >> > > If you get a boost::shared_ptr to a Python object (either by wrapping a > function taking a shared_ptr or by using boost::python::extract), that > shared_ptr will properly manage the Python reference count via a custom > deleter that decref's the PyObject* when it goes out of scope. The only > catch is that shared_ptr doesn't do garbage collection, so you can get > cycles that don't get deleted if your shared_ptrs own other shared_ptrs. > Other than that, you're should be safe if you just use shared_ptr > everywhere. > > This will work differently internally if you declare your wrapped > classes to have shared_ptr storage (that's generally what I do), but the > effects should be mostly the same. Note that you can also declare your > storage to be shared_ptr to a wrapper class. > >> Do you use these two methods conjointly in the same project? Or did you >> identify some use cases which favor a method rather the other one? >> > > I generally use shared_ptr storage for everything, but I often mix that > with with_custodian_and_ward and its cousins (return_internal_reference, > in particular) when I don't have access to a shared_ptr on the C++ side. > > > Jim Bosch > > ___ > Cplusplus-sig mailing list > Cplusplus-sig@python.org > http://mail.python.org/mailman/listinfo/cplusplus-sig OK, thank you very much for your answer! - Alexandre Hamez ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Ownership of a C++ object extended in Python using wrapper
One tradeoff, I believe, If you have, say: class A { A (boost::shared_ptr) boost::shared_ptr B_obj; }; Then each time you use B_obj, there is additional dereference overhead IIUC. If I used with_custodian_and_ward, there should not be this additional overhead. ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] errors while setting arguments description for the method
I've got specification like this: class_( "Foo", "Foo descr" ) .def( "__init__", bp::make_constructor( &make_foo ), bp::args( "self", "str" ), "Constructor based on string representation.\n" ) ... I am getting compilation error below from VC9.0. Error disappears if I avoid bp::args( "self", "str" ) part. Please advise, Gennadiy 1>...\boost-1.39\boost/python/def_visitor.hpp(43) : error C2784: 'void boost::python::api::object_operators::visit(ClassT &,const char *,const boost::python::detail::def_helper &) const' : could not deduce template argument for 'const boost::python::detail::def_helper &' from 'const boost::python::detail::def_helper' 1>with 1>[ 1>U=boost::python::api::object 1>] 1>and 1>[ 1>T1=boost::python::detail::keywords<2>, 1>T2=const char [106] 1>] 1>\boost-1.39\boost/python/object_core.hpp(188) : see declaration of 'boost::python::api::object_operators::visit' 1>with 1>[ 1>U=boost::python::api::object 1>] 1>\boost-1.39\boost/python/def_visitor.hpp(74) : see reference to function template instantiation 'void boost::python::def_visitor_access::visit,classT,OptionalArgs>(const V &,classT &,const char *, const OptionalArgs &)' being compiled 1>with 1>[ 1>DerivedVisitor=boost::python::api::object, 1> classT=boost::python::class_, 1> OptionalArgs=boost::python::detail::def_helper,const char [106]>, 1>V=boost::python::def_visitor 1>] 1...\boost-1.39\boost/python/class.hpp(524) : see reference to function template instantiation 'void boost::python::def_visitor::visit,Helper>(classT &,const char *,const OptionalArgs &)const' being compiled 1>with 1>[ 1>DerivedVisitor=boost::python::api::object, 1>W=Foo, 1>X1=FooSP, 1>X2=boost::python::detail::not_specified, 1>X3=boost::python::detail::not_specified, 1> Helper=boost::python::detail::def_helper, const char [106]>, 1> classT=boost::python::class_, 1> OptionalArgs=boost::python::detail::def_helper,const char [106]> 1>] 1>...\boost-1.39\boost/python/class.hpp(259) : see reference to function template instantiation 'void boost::python::class_::def_impl,Fn,U>(T *,const char *,LeafVisitor,const Helper &,const boost::python::def_visitor *)' being compiled 1>with 1>[ 1>W=Foo, 1>X1=FooSP, 1>X2=boost::python::detail::not_specified, 1>X3=boost::python::detail::not_specified, 1>T1=boost::python::detail::keywords<2>, 1>T2=const char [106], 1>Fn=boost::python::api::object, 1>U=boost::python::api::object, 1>T=Foo, 1>LeafVisitor=boost::python::api::object, 1> Helper=boost::python::detail::def_helper,const char [106]>, 1>DerivedVisitor=boost::python::api::object 1>] 1>.\src\my_export.cpp(422) : see reference to function template instantiation 'boost::python::class_ &boost::python::class_::def,const char[106]>(const char *, Fn,const A1 &,A2 (&))' being compiled 1>with 1>[ 1>W=Foo, 1>X1=FooSP, 1>X2=boost::python::detail::not_specified, 1>X3=boost::python::detail::not_specified, 1>nkeywords=2, 1>Fn=boost::python::api::object, 1>A1=boost::python::detail::keywords<2>, 1>A2=const char [106] 1>] ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] errors while setting arguments description for the method
On Wed, 2010-03-17 at 22:21 +, Gennadiy Rozental wrote: > I've got specification like this: > > class_( "Foo", "Foo descr" ) > .def( "__init__", bp::make_constructor( &make_foo ), >bp::args( "self", "str" ), >"Constructor based on string representation.\n" ) > ... > > I am getting compilation error below from VC9.0. Error disappears if I avoid > bp::args( "self", "str" ) part. > > Please advise, > You have to pass the keywords to make_constructor: .def("__init__", bp::make_constructor(&make_foo, bp::default_call_policies(), bp::args("self","str")) ) I'm not actually sure whether to put the docstring in the call to make_constructor (I'll let you experiment), but you do have to supply the call policies argument manually if you want to supply keywords - make_constructor just doesn't have the overloads that make_function does. Jim Bosch ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Having problems with returned object.
On Mon, 2010-03-15 at 21:25 -0600, Fabzter wrote: > void export_jugada() > { > class_("MyClass") > .def("setPos", setPosicion_with_int(&MyClass::setPos) ) > .def("setPos", setPosicion_with_vect(&MyClass::setPos) ) > > .def("getPosicion", &MyClass::getPosicion, > return_value_policy()) > ; > } Unless you've also wrapped std::vector, I don't think your getPosicion() wrapper will work in Python (it should throw an exception when you call it). And by the way, you probably want "return_internal_reference<>" instead of "reference_existing_object" to be a little safer - that tells Python your MyClass instance owns the vector, rather than stating "I promise this reference will stay valid". > --- > > Now, I have a little script that does something like: > > --- > ... > def get() > m = MyClass() > m.setPos(4, 9) > return m > ... > --- > > I have debugged (as much as my knowledge lets me!!!) to this point and > everything seem fine. "get()" gets properly called, and when it calls > MyClass::setPos(int, int), it seems to do everything fine (filling up > the vector). Well, now, in the main program, after reading the script, > I do something like this: > > --- > ...extracting get() from script... > MyClass m ( getObj() ); > --- > I don't really understand what you're doing here. Where is getObj() defined, and what does it do? I gather that your "main program" is written in C++, not Python - are you embedding? I'm not sure the std::vector stuff above is related to your problem, but without knowing more I can't say. Jim Bosch ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] passing pointers from python
Hi all, i'm trying to wrap c++ functions that have pointer variables. The test example i'm using is shown below: int World::addition(int* a, int* b) { int z = *a + *b; return z; } Now, i defined it in my wrapper as : .def("addition", &World::addition) My code compiles, but when I try to execute it from python, i get this error: Python Argument types in World.Addition(World, int, int) did not match C++ signature: addition(class World {lvalue}, int* , int*) The problem is, how to get hold of a pointer in python? Or is there a workaround to define the function differently in the wrapper file? -- Regards, Hitesh Dhiman Electrical Engineering National University of Singapore ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Overriding Virtual Functions
I have a C++ class like so: namespace Foo { class TypeA {}; class TypeB {}; class Connection { template void Publish(const T&); virtual void OnEvent(const TypeA&) {} virtual void OnEvent(const TypeB&) {} }; } I've exported it like so: namespace { class ConnectionWrap : public Foo::Connection, wrapper { virtual void OnEvent(const TypeA& event) { if (override f = get_override("OnEvent_TypeA")) { f(event); } // no need to call Connection::OnEvent since it does nothing } virtual void OnEvent(const TypeB& event) { if (override f = get_override("OnEvent_TypeB")) { f(event); } // no need to call Connection::OnEvent since it does nothing } }; } BOOST_PYTHON_MODULE(_mypywrap) { class_("Connection") .def("Publish", &ConnectionWrap::Publish) .def("Publish", &ConnectionWrap::Publish) ; } It compiles, imports, etc.. However if I remove .def("Publish", &ConnectionWrap::Publish), and I try: import _mypywrap connection = _mypywrap.Connection() # ok connection.Publish(_mypywrap.TypeA()) # not ok but expected. The error msg is "Connection.Publish(Connection, TypeA) did not match C++ signature:..." and it dumps a list of signatures it knows about which would be "publish(Foo::Connection {lvalue}, Foo::TypeB)" if I instead do the following: connection.Publish(_mypywrap.TypeB()) I get a seg fault, looking at the stack trace shows it blew up in get_override(char const*, _typeobject*) const, and if I go to that frame, both arguments have been optimized out. Whew. So my questions are: (besides what am I doing wrong - unless that's easier to answer) In the first example where I did not export the first publish, it failed as expected. However the namespaces are not consistent between the signature attempted to match and the known signatures. I'm puzzled by that, but I suspect its just a formatting difference - since the second example actually does call publish (which I know because the stack trace shows me it received a message from the C++ class and blew up trying to jump the chasm back into python land). Am I doing something wrong with the namespaces here, and is that why my functions aren't visible? In the second example... I know that the python function "OnEvent_TypeB" hasn't been created. I don't get why it blows up in get_override rather than fails. The other examples I've found indicate that I should be able to use that mechanism to provide access to the base class virtual functions which do have bodies. In fact, I'm running into this problem with my ConnectionWrap class, not something derived from it. Does the override need to exist, and if so, how can I accomplish this goal (of only overriding behavior I want to implement)? ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
[C++-sig] Executing scripts in other namespace than __main__
Hi everybody, it's my annoying again. I have a pure virtual class in C++ wich I have wrapped and exposed (call it BaseClass), and I let the users inherit from it to make their own class in their script. It's worth noting that I do not know the name of such class they are creating. When I load only one script, there's no problem in doing this: ___ object module_main = import("__main__"); object namespace_module_main = module_main.attr("__dict__"); exec("import sys\n", namespace_module_main, namespace_module_main); object ignored = exec_file(boost::python::str("path/file1.py"), namespace_module_main, namespace_module_main); //and as i don't know how the class they defined was named... object ignored_ = exec("l = dir()\n" //get everything defined in current dictionary "class_ = None\n" "for i in l:\n" "res = eval(i)\n" "if type(res) == type(BaseClass): class_ = res\n" //if we've got a class derived from BaseClass, we save it to "class_" "if class_ is None: raise Error()\n" , this->namespace_modulo_local, this->namespace_modulo_local); object class_ = namespace_module_main["class_"]; //get the class object object instance_ = class_(); BaseClass *bc = extract(instance_); ___ This works quite well when I only load one module. But if I load 2 or more modules, the method I use to extract a class derived from BaseClass is useless, since there are two or more classes derived from BaseClass in __main__ and I don't know which one I will get. So I thought I could run each script in it's own namespace, and then using the same method for retrieving the class, but in every individual namespace, ensuring I will get the derived class from the specified script. How can I acommplish this? (: ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig