From rodlist at hotmail.com Mon May 1 18:28:30 2006 From: rodlist at hotmail.com (Rod Cloutier) Date: Mon, 1 May 2006 12:28:30 -0400 Subject: [C++-sig] Working with python unicode strings without wstring Message-ID: Hi, I am trying to wrap an external library that uses "const wchar_t *" a arguments for several methods. I know that if they would have used std::wstring the conversion would have been straight forward. Is there anyway to convert python unicode string to wchar_t pointers ? Can I make the following code work without writting a wrapper function that uses a wstring as an argument ? in C++: void printText( const wchar_t* str ) { std::wcout << str; } in python: MyModule.printText( u"The message" ) Thanks Rodrigue Cloutier -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at a-beyer.de Tue May 2 14:43:17 2006 From: mail at a-beyer.de (Andreas Beyer) Date: Tue, 02 May 2006 14:43:17 +0200 Subject: [C++-sig] tuples::tuple -> python::tuple Message-ID: <445753E5.3080900@a-beyer.de> Hi, I tried to implement an example given on this list earlier this year: http://mail.python.org/pipermail/c++-sig/2006-January/010103.html I ran into the following issues. Suggested code: >>/ namespace my >/>/ { >/>/ template >/>/ python::tuple tuple_to_python(tuples::cons const& x) >/>/ { >/>/ return python::make_tuple(x) + my::tuple_to_python(x.tail); >/>/ } >/ ^^^ > >I guess it should rather be: > > return python::make_tuple(x.head) + my::tuple_to_python(x.tail); > > If I try to compile this example (with the changes from *Fran?ois as shown above) *I get the following compiler message (which refers to that line of code): tuple_test.cpp:13: error: 'const struct boost::tuples::cons' has no member named 'tail' I think, the line should actually read: return python::make_tuple(x.get_head()) + my::tuple_to_python(x.get_tail()); because 'x' is tuples:cons, which provides those methods for accessing head and tail. (I don't understand why the compiler seems to accept x.head but not x.tail.) When compiling the eample with this additional change, I get the following error message: tuple_test.cpp:13: error: conversion from `boost::python::api::object' to non-scalar type `boost::python::tuple' requested which refers to the above line of code. I don't understand the message, because both python::make_tuple() and my::tuple_to_python() return python::tuple and not python::object. Thanks, Andreas Here is the complete, minimal example: --- begin tuple_test.cpp --- #include #include using namespace boost; namespace my { template python::tuple tuple_to_python(tuples::cons const& x) { return python::make_tuple(x.get_head()) + my::tuple_to_python(x.get_tail()); } python::tuple tuple_to_python(tuples::null_type) { return python::tuple(); } template struct tupleconverter { static PyObject* convert(T const& x) { return python::incref(my::tuple_to_python(x).ptr()); } }; } typedef tuples::tuple a_tuple; BOOST_PYTHON_MODULE(tuple_tester) { python::to_python_converter >(); } --- end tuple_test.cpp --- -- Dr. Andreas Beyer mail at a-beyer.de www.andreas-beyer.de From te_sanders at yahoo.com Wed May 3 05:55:41 2006 From: te_sanders at yahoo.com (Thomas Sanders) Date: Tue, 2 May 2006 20:55:41 -0700 (PDT) Subject: [C++-sig] Visual Studio 2005 Revisited Message-ID: <20060503035541.26727.qmail@web37904.mail.mud.yahoo.com> I was wondering if anyone had (secretly?) had success getting Python 2.4.3 to run under a Visual Studio 2005 (VC++ 8) compilation? I ran into the winsig.c assertion issue (http://tinyurl.com/jra7b), and figured the patch might become part of 2.5. There was also some back-and-forth (http://tinyurl.com/e84yf) about whether VS 2005 would officially be supported at all -- I don't mind getting my hands dirty tweaking 2.4.3 if I could get the compilation to run properly. The alternatives would be to fall back to VS6 or to obtain VS7, but since MS is giving VS 2005 Standard away for "free" (http://tinyurl.com/rcfaa), it'd be a shame. Any thoughts on how I might approach this? Thanks, Thomas __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From duranlef at iro.umontreal.ca Wed May 3 18:02:03 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Wed, 3 May 2006 12:02:03 -0400 (EDT) Subject: [C++-sig] tuples::tuple -> python::tuple In-Reply-To: <445753E5.3080900@a-beyer.de> References: <445753E5.3080900@a-beyer.de> Message-ID: On Tue, 2 May 2006, Andreas Beyer wrote: > If I try to compile this example (with the changes from *Fran?ois as > shown above) *I get the following compiler message (which refers to that > line of code): > > tuple_test.cpp:13: error: 'const struct boost::tuples::cons boost::tuples::null_type>' has no member named 'tail' > > I think, the line should actually read: > return python::make_tuple(x.get_head()) + > my::tuple_to_python(x.get_tail()); > > because 'x' is tuples:cons, which provides those methods for accessing > head and tail. (I don't understand why the compiler seems to accept > x.head but not x.tail.) I guess that's because boost::tuple uses a "compression" for null_type (like boost::compressed_pair). x.head will always existe for sure because the only way it could be null_type is with a tuple with no elements, which doesn't make much sense. > When compiling the eample with this additional change, I get the > following error message: > > tuple_test.cpp:13: error: conversion from `boost::python::api::object' to > non-scalar type `boost::python::tuple' requested > > which refers to the above line of code. I don't understand the message, > because both python::make_tuple() and my::tuple_to_python() return > python::tuple and not python::object. I see the problem. operator+ is inherited from boost::python::object (actually, boost::python::api::object), and it returns a boost::python::object. However, there is not implicit conversion from that type to boost::python::tuple, but you can use an explicit one, e.g.: #include #include using namespace boost; namespace my { // My compiler complained about this not being declared first: python::tuple tuple_to_python(tuples::null_type) { return python::tuple(); } template python::tuple tuple_to_python(tuples::cons const& x) { // Here is the explicit conversion return python::tuple( python::make_tuple(x.get_head()) + my::tuple_to_python(x.get_tail()) ); } template struct tupleconverter { static PyObject* convert(T const& x) { return python::incref(my::tuple_to_python(x).ptr()); } }; } typedef tuples::tuple a_tuple; BOOST_PYTHON_MODULE(tuple_tester) { python::to_python_converter >(); } Actually, you don't really need that convertion in this application, you could simply write my::tuple_to_python as template python::object tuple_to_python(tuples::cons const& x) { // Here is the explicit conversion return python::make_tuple(x.get_head()) + my::tuple_to_python(x.get_tail()); } and that's it. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "When there are others, I can perceive myself as an individual. If I am alone, then I will be the same as everything else. There will be no difference between myself and nothing!" - from _Neon Genesis Evangelion_ From mail at a-beyer.de Wed May 3 10:19:14 2006 From: mail at a-beyer.de (Andreas Beyer) Date: Wed, 03 May 2006 10:19:14 +0200 Subject: [C++-sig] tuples::tuple -> python::tuple In-Reply-To: References: <445753E5.3080900@a-beyer.de> Message-ID: <44586782.1060602@a-beyer.de> Hi Fran?ois, Thank you very much! Fran?ois Duranleau wrote: > On Tue, 2 May 2006, Andreas Beyer wrote: [...] >> When compiling the eample with this additional change, I get the >> following error message: >> >> tuple_test.cpp:13: error: conversion from >> `boost::python::api::object' to >> non-scalar type `boost::python::tuple' requested >> >> which refers to the above line of code. I don't understand the message, >> because both python::make_tuple() and my::tuple_to_python() return >> python::tuple and not python::object. > > > I see the problem. operator+ is inherited from boost::python::object > (actually, boost::python::api::object), and it returns a > boost::python::object. However, there is not implicit conversion from > that type to boost::python::tuple, but you can use an explicit one, e.g.: [...] > > Actually, you don't really need that convertion in this application, > you could simply write my::tuple_to_python as > > template > python::object tuple_to_python(tuples::cons const& x) > { > // Here is the explicit conversion > return python::make_tuple(x.get_head()) + > my::tuple_to_python(x.get_tail()); > } > > and that's it. This solves the problem in a very elegant way! Just for the records, here is the complete working example (@Dave: Maybe such converter could go into the next release of boost::python?): --- begin file --- #include #include using namespace boost; namespace my { template python::object tuple_to_python(tuples::cons const& x) { // operator+ creates python::api::object return python::make_tuple(x.get_head()) + my::tuple_to_python(x.get_tail()); } python::object tuple_to_python(tuples::null_type) { return python::tuple(); } template struct tupleconverter { static PyObject* convert(T const& x) { return python::incref(my::tuple_to_python(x).ptr()); } }; } // an example how to use the tuple converter: typedef tuples::tuple a_tuple; a_tuple get_a_tuple(int a, double b) { return a_tuple(a, b); } BOOST_PYTHON_MODULE(tuple_test) { python::to_python_converter >(); python::def("get_a_tuple", &get_a_tuple); } --- end file --- -- Dr. Andreas Beyer mail at a-beyer.de www.andreas-beyer.de From mail at a-beyer.de Wed May 3 15:26:40 2006 From: mail at a-beyer.de (Andreas Beyer) Date: Wed, 03 May 2006 15:26:40 +0200 Subject: [C++-sig] export std::set Message-ID: <4458AF90.1050800@a-beyer.de> Hi, I created an interface for exporting std::set<> to python. It is still incomplete, but I figured it might be usefull for others to adopt to their needs. The idea of the interface somewhat resembles the indexing_suite. There are two template functions for exporting set<>-types: export_set publishes an interface for mutable sets to python (like python's "set"). export_frozenset publishes the immutable equivalent. Both functions take the desired python names of the classes as arguments. You can use the functions as follows: BOOST_PYTHON_MODULE(your_module) { export_set("StrSet"); // use set's key-type as template argument } You cannot mix set and frozenset for the same C++ type in one module, because then the mapping of the type to python becomes ambigious. Subclassing the original set<>-types might help (Untested!). In python you can do things like this: >>> from set_test import * >>> >>> s1 = StrSet() # create set from python >>> s1.add('a') # add a new element >>> s1.add('b') >>> s2 = make_str_set('b', 'c') # create & return set from C++ >>> list(s1) ['a', 'b'] >>> list(s2) ['b', 'c'] >>> list(s1 & s2) # set intersection ['b'] >>> list(s1 | s2) # set union ['a', 'b', 'c'] >>> list(s1 - s2) # set difference ['a'] >>> list(s1 ^ s2) # symmetric set difference ['a', 'c'] >>> s1.remove('a') >>> s1.remove('x') # attempt removing non-existent element Traceback (most recent call last): File "", line 1, in ? RuntimeError: unidentifiable C++ exception >>> >>> d = {s1:0} # mutable object, no hashing allowed Traceback (most recent call last): File "", line 1, in ? RuntimeError: unidentifiable C++ exception >>> >>> # using immutable sets >>> s1 = make_int_set(0,1) # create immutable set in C++ >>> s2 = FrozenIntSet() >>> s3 = make_int_set(0, 1) >>> s1 == s2 False >>> s1 == s3 True >>> s1 < s2 False >>> s2 < s1 True >>> d = {s1:1, s2:2, s3:3} # immutable sets are hashable >>> Please, excuse the kinky way of printing the sets' contents, but I didn't create a __str__() method yet. Also, there is no python constructor accepting lists/tuples/iterators. Send me the code if you write one! Eventually, it would be preferable if set<> would be directly translated into python's set types. However, I see no easy solution and some issues, e.g. how would such automated converter decide, if the given C++-set should become python-set or python-frozenset? Andreas Here is the complete code: (Please, don't mind my Java-style of using '{'. It is hard-coded in my fingers ;-) ) --- begin py_set.hpp --- #include #include #include #include #include using namespace boost; template class py_set : public std::set, public python::wrapper< std::set > { public: // some typedefs for convinience typedef std::set source_type; typedef py_set wrap_type; // constructors py_set () {}; py_set (const source_type& s ) { insert(s.begin(), s.end()); } // element access bool contains(const KeyType key) { return count(key)>0; } // we must define add() for it gets explicit argument types void add(const KeyType key) { insert(key); } void remove(const KeyType key) // improve error handling here { if (!contains(key)) throw "element not in set"; erase(key); } // set operations source_type set_union(wrap_type &other) { source_type result; std::set_union(begin(), end(), other.begin(), other.end(), inserter(result, result.begin())); return result; } source_type set_intersection(wrap_type &other) { source_type result; std::set_intersection(begin(), end(), other.begin(), other.end(), inserter(result, result.begin())); return result; } source_type set_difference(wrap_type &other) { source_type result; std::set_difference(begin(), end(), other.begin(), other.end(), inserter(result, result.begin())); return result; } source_type set_symmetric_difference(wrap_type &other) { source_type result; std::set_symmetric_difference(begin(), end(), other.begin(), other.end(), inserter(result, result.begin())); return result; } }; inline void block_hashing(python::object) { // do something more intelligent here throw "objects of this type are unhashable"; } // export mutable set template void export_set(const char* py_name) { typedef py_set set_T; python::class_ (py_name, "mutable set") .def("__len__", &set_T::size) .def("__contains__", &set_T::contains) .def("add", &set_T::add, "add element") .def("__delitem__", &set_T::remove) .def("remove", &set_T::remove, "remove element") .def("__iter__", python::iterator ()) .def("__hash__", &block_hashing) .def("union", &set_T::set_union, "set union") .def("__or__", &set_T::set_union, "set union") .def("intersection", &set_T::set_intersection, "set intersection") .def("__and__", &set_T::set_intersection, "set intersection") .def("difference", &set_T::set_difference, "elements not in second set") .def("__sub__", &set_T::set_difference, "set difference") .def("symmetric_difference", &set_T::set_symmetric_difference, "elements unique to either set") .def("__xor__", &set_T::set_symmetric_difference, "symmetric set difference") ; python::implicitly_convertible, std::set >(); python::implicitly_convertible, py_set >(); } // export immutable set template void export_frozenset(const char* py_name) { typedef py_set set_T; python::class_ (py_name, "immutable set") .def("__len__", &set_T::size) .def("__contains__", &set_T::contains) .def("__iter__", python::iterator ()) .def(python::self < python::self) .def(python::self == python::self) .def("union", &set_T::set_union, "set union") .def("__or__", &set_T::set_union, "set union") .def("intersection", &set_T::set_intersection, "set intersection") .def("__and__", &set_T::set_intersection, "set intersection") .def("difference", &set_T::set_difference, "elements not in second set") .def("__sub__", &set_T::set_difference, "set different") .def("symmetric_difference", &set_T::set_symmetric_difference, "elements unique to either set") .def("__xor__", &set_T::set_symmetric_difference, "symmetric set different") ; python::implicitly_convertible, std::set >(); python::implicitly_convertible, py_set >(); } --- end py_set.hpp --- --- begin set_test.cpp --- #include "py_set.hpp" // examples using the above code: std::set make_str_set(std::string a, std::string b) { std::set s; s.insert(a); s.insert(b); return s; } std::set make_int_set(int a, int b) { std::set s; s.insert(a); s.insert(b); return s; } BOOST_PYTHON_MODULE(set_test) { export_set("StrSet"); // don't export the same C++ type twice // export_frozenset("FrozenStrSet"); export_frozenset("FrozenIntSet"); // create set<> instances in C++ python::def("make_str_set", &make_str_set); python::def("make_int_set", &make_int_set); } --- end set_test.cpp --- -- Dr. Andreas Beyer mail at a-beyer.de www.andreas-beyer.de From abhi at qualcomm.com Thu May 4 02:31:20 2006 From: abhi at qualcomm.com (Abhi) Date: Wed, 03 May 2006 17:31:20 -0700 Subject: [C++-sig] Exposing a class with private ctor and private dtor Message-ID: <3C41BF3554E1B4847206FE26@ASACHDEV.na.qualcomm.com> Question 1. How do I expose a class which has a private dtor? The class has static method to destroy it instead? class PrivateCtorDtor { public: int nonStaticVariable; static int staticVariable; static PrivateCtorDtor* allocate(); static void free(PrivateCtorDtor* ); static int getStaticVariable() { return staticVariable; } private: ~PrivateCtorDtor(); private: PrivateCtorDtor(); }; Observation 1: Running py++ on it does not produce the right code! It takes care of the case of private ctor in the above case, but does not take care of the private dtor. Question 2: I think this can be done by wrapping the class with a derived class. For example: bp::class_("PrivateCtorDtor", bp::no_init) where PrivateCtorDtor_YWrapper class is derived from the PrivateCtorDtor class. And PrivateCtorDtor_YWrapper dtor calls the free static method of the PrivateCtorDtor class. But I __could not get it to work__. Question 3: Is it possible to do this without creating the derived class as above? For example, by doing a .def on some python function name (either "__del__" or something like that) thanks - Abhi From abhi at qualcomm.com Thu May 4 02:51:43 2006 From: abhi at qualcomm.com (Abhi) Date: Wed, 03 May 2006 17:51:43 -0700 Subject: [C++-sig] Exposing c++ classes with static arrays using Boost.Python and py++ Message-ID: While running py++ on a class with a static array inside it, py++ generates Boost.Python bindings using a derived class for the original C++ class. Let me illustrate with the help of the following example: class AttributesTest { public: int staticIntArray[10]; }; Notice this class has an array inside it Running py++ generates the following code, with a wrapper class that derives from the AttributesTest class. struct AttributesTest_wrapper : AttributesTest, bp::wrapper< AttributesTest > { AttributesTest_wrapper(AttributesTest const & arg ) : AttributesTest( arg ) , bp::wrapper< AttributesTest >() {} AttributesTest_wrapper( ) : AttributesTest( ) , bp::wrapper< AttributesTest >() {} pyplusplus::containers::static_sized::array_1_t< int, 10 > pyplusplus_staticIntArray_wrapper(){ return pyplusplus::containers::static_sized::array_1_t< int, 10 >( staticIntArray ); } }; and BOOST_PYTHON_MODULE(PYPP_YodaPacketCommon){ if( true ){ typedef bp::class_< AttributesTest_wrapper > AttributesTest_exposer_t; AttributesTest_exposer_t AttributesTest_exposer = AttributesTest_exposer_t( "AttributesTest" ); bp::scope AttributesTest_scope( AttributesTest_exposer ); AttributesTest_exposer.def( bp::init< >()[bp::default_call_policies()] ); pyplusplus::containers::static_sized::register_array_1< int, 10, bp::default_call_policies >( "__array_1_int_10" ); AttributesTest_exposer.add_property( "staticIntArray" , bp::make_function( (pyplusplus::containers::static_sized::array_1_t< int, 10 > ( AttributesTest_wrapper::* )( ) )(&AttributesTest_wrapper::pyplusplus_staticIntArray_wrapper) , bp::with_custodian_and_ward_postcall< 0, 1, bp::default_call_policies >() ) );; Note that it maps the python name "AttributesTest" to the derived class AttributesTest_wrapper. Why not just keep it simple and rather than creating a derived class just map the variable "staticIntArray" via a global method, such as: .add_property( "staticIntArray" , bp::make_function( (&::someglobal_staticIntArray_wrapper) , bp::with_custodian_and_ward_postcall< 0, 1, bp::default_call_policies >() ) );; and define the someglobal_staticIntArray_wrapper method as: pyplusplus::containers::static_sized::array_1_t< int, 10 > someglobal_staticIntArray_wrapper(){ return pyplusplus::containers::static_sized::array_1_t< int, 10 >( staticIntArray ); } Is there any drawback with just mapping the array variable to a global method rather than mapping the whole class. thanks - Abhi From roman.yakovenko at gmail.com Thu May 4 07:25:10 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 4 May 2006 08:25:10 +0300 Subject: [C++-sig] Exposing c++ classes with static arrays using Boost.Python and py++ In-Reply-To: References: Message-ID: <7465b6170605032225i3ea790a3g5a86383dbebef4e3@mail.gmail.com> On 5/4/06, Abhi wrote: > While running py++ on a class with a static array inside it, py++ generates > Boost.Python bindings using a derived class for the original C++ class. > > pyplusplus::containers::static_sized::array_1_t< int, 10 > > pyplusplus_staticIntArray_wrapper(){ > return pyplusplus::containers::static_sized::array_1_t< int, 10 >( > staticIntArray ); > } I should make this function static and to take an instance as the first argument. Then generated code will work for derived classes too. I will fix it in few days > > Is there any drawback with just mapping the array variable to a global > method rather than mapping the whole class. Obviously, the generated code represents my understanding, preferences and personal taste of how it should be done. In this specific case py++ should mangle into function name: namespace name, class name, variable name. Or it should create some scope/namespace where IntArray will be unique name. Such scope already exists - class wrapper, so I reused it. Also the approach I choose, simplifies py++ code ( == less bugs ). I will re-think my approach, if you will give 3 good reasons, why it should be changed. :-) > thanks > - Abhi -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Thu May 4 07:41:21 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 4 May 2006 08:41:21 +0300 Subject: [C++-sig] Exposing a class with private ctor and private dtor In-Reply-To: <3C41BF3554E1B4847206FE26@ASACHDEV.na.qualcomm.com> References: <3C41BF3554E1B4847206FE26@ASACHDEV.na.qualcomm.com> Message-ID: <7465b6170605032241j2f1cde26qfe27e786d6db7e7c@mail.gmail.com> On 5/4/06, Abhi wrote: > Question 1. How do I expose a class which has a private dtor? The class has > static method to destroy it instead? I don't know, please post the question in a separate thread. > > Observation 1: Running py++ on it does not produce the right code! It takes > care of the case of private ctor in the above case, but does not take care > of the private dtor. I thought, but did not tested, that bp::class_< PrivateCtorDtor, boost::noncopyable >( "PrivateCtorDtor", bp::no_init ) should work, obviously I was wrong ( twice ). I hope, you will find the answer to your first question and will post it here. Thus I will be able to implement the solution in py++ > Question 2: I think this can be done by wrapping the class with a derived > class. > For example: > > bp::class_("PrivateCtorDtor", bp::no_init) > > where PrivateCtorDtor_YWrapper class is derived from the PrivateCtorDtor > class. > And PrivateCtorDtor_YWrapper dtor calls the free static method of the > PrivateCtorDtor class. > > But I __could not get it to work__. May be it could not be done this way :-)? > Question 3: Is it possible to do this without creating the derived class as > above? For example, by doing a .def on some python function name (either > "__del__" or something like that) Interesting idea. You want to map PrivateCtorDtor::free function to __del__ method, right? > thanks > - Abhi -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Thu May 4 08:09:28 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 4 May 2006 09:09:28 +0300 Subject: [C++-sig] export std::set In-Reply-To: <4458AF90.1050800@a-beyer.de> References: <4458AF90.1050800@a-beyer.de> Message-ID: <7465b6170605032309m359345f4k50a72de1de21334d@mail.gmail.com> On 5/3/06, Andreas Beyer wrote: > Hi, Good morning. > I created an interface for exporting std::set<> to python. It is still > incomplete, but I figured it might be usefull for others to adopt to > their needs. It could be very useful addition to boost.python library. Meanwhile ... pyplusplus has functionality I call "code repository". Right now the repository contains code, that helps to export static arrays ( http://tinyurl.com/fzxds ). The main idea after repository is to have code, that provides solution for common problems. pyplusplus will identify the problem and will generate right code using "code repository". I would like to insert your code into "code repository". Do you agree? Do you release the code under boost software license ( http://boost.org/LICENSE_1_0.txt )? Thanks -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From andreas at a-beyer.de Thu May 4 17:37:49 2006 From: andreas at a-beyer.de (Andreas Beyer) Date: Thu, 04 May 2006 08:37:49 -0700 Subject: [C++-sig] export std::set In-Reply-To: <7465b6170605032309m359345f4k50a72de1de21334d@mail.gmail.com> References: <4458AF90.1050800@a-beyer.de> <7465b6170605032309m359345f4k50a72de1de21334d@mail.gmail.com> Message-ID: <1146757069.445a1fcd50089@ssl.lux01.de> Hi Roman, Roman Yakovenko : > On 5/3/06, Andreas Beyer wrote: > > > I created an interface for exporting std::set<> to python. It is still > > incomplete, but I figured it might be usefull for others to adopt to > > their needs. > > It could be very useful addition to boost.python library. > [...] > I would like to insert your code into "code repository". Do you agree? > Do you release > the code under boost software license ( http://boost.org/LICENSE_1_0.txt )? > I usually publsh under GPL. In this particular case I mentioned no copyright, so you are free to use it as you like. Andreas -- Andreas Beyer - andreas at a-beyer.de www.andreas-beyer.de From duranlef at iro.umontreal.ca Thu May 4 18:26:41 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Thu, 4 May 2006 12:26:41 -0400 (EDT) Subject: [C++-sig] export std::set In-Reply-To: <4458AF90.1050800@a-beyer.de> References: <4458AF90.1050800@a-beyer.de> Message-ID: On Wed, 3 May 2006, Andreas Beyer wrote: > Here is the complete code: If I may make a few suggestions: > // element access > bool contains(const KeyType key) > { return count(key)>0; } > // we must define add() for it gets explicit argument types > void add(const KeyType key) > { insert(key); } > void remove(const KeyType key) > // improve error handling here > { if (!contains(key)) throw "element not in set"; erase(key); } Why not put the key parameter as a const reference instead of copying? Also, for remove, it would probably be best to write it like this: void remove( const KeyType& key ) { typename source_type::iterator i = this->find( key ) ; if ( i == this->end() ) { throw "element not in set" ; } this->erase( i ) ; } This way you look up for the key only once, not twice. Also, everywhere in py_set<>, you need to either make all calls to some base class's (with template arguments dependent on the current class) method qualified (e.g. with this-> as above) or "import" them with 'using' declarations, or else this code is not standard and won't compile on some compilers (the one I use, g++-4.0, for instance). -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "The real source of wealth is correct ideas: workable ideas: that is, negative entropy -- Information." - Robert Anton Wilson, _Prometheus Rising_, 1983 From roman.yakovenko at gmail.com Thu May 4 18:52:31 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 4 May 2006 19:52:31 +0300 Subject: [C++-sig] export std::set In-Reply-To: <1146757069.445a1fcd50089@ssl.lux01.de> References: <4458AF90.1050800@a-beyer.de> <7465b6170605032309m359345f4k50a72de1de21334d@mail.gmail.com> <1146757069.445a1fcd50089@ssl.lux01.de> Message-ID: <7465b6170605040952k785eb129je715e5f4e639bd7c@mail.gmail.com> On 5/4/06, Andreas Beyer wrote: > Hi Roman, > > > Roman Yakovenko : > > > On 5/3/06, Andreas Beyer wrote: > > > > > > I created an interface for exporting std::set<> to python. It is still > > > incomplete, but I figured it might be usefull for others to adopt to > > > their needs. > > > > It could be very useful addition to boost.python library. > > > [...] > > > I would like to insert your code into "code repository". Do you agree? > > Do you release > > the code under boost software license ( http://boost.org/LICENSE_1_0.txt )? > > > I usually publsh under GPL. In this particular case I mentioned no copyright, so > you are free to use it as you like. Thanks > Andreas > > > -- > Andreas Beyer - andreas at a-beyer.de > www.andreas-beyer.de > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Thu May 4 18:53:18 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 4 May 2006 19:53:18 +0300 Subject: [C++-sig] export std::set In-Reply-To: References: <4458AF90.1050800@a-beyer.de> Message-ID: <7465b6170605040953k5dd69bc4p42abbdfa62a8aa7a@mail.gmail.com> On 5/4/06, Fran?ois Duranleau wrote: > On Wed, 3 May 2006, Andreas Beyer wrote: > > > Here is the complete code: > > If I may make a few suggestions: > > > // element access > > bool contains(const KeyType key) > > { return count(key)>0; } > > // we must define add() for it gets explicit argument types > > void add(const KeyType key) > > { insert(key); } > > void remove(const KeyType key) > > // improve error handling here > > { if (!contains(key)) throw "element not in set"; erase(key); } > > Why not put the key parameter as a const reference instead of copying? > > Also, for remove, it would probably be best to write it like this: > > void remove( const KeyType& key ) > { > typename source_type::iterator i = this->find( key ) ; > if ( i == this->end() ) > { > throw "element not in set" ; > } > this->erase( i ) ; > } > > This way you look up for the key only once, not twice. > > Also, everywhere in py_set<>, you need to either make all calls to some > base class's (with template arguments dependent on the current class) > method qualified (e.g. with this-> as above) or "import" them with 'using' > declarations, or else this code is not standard and won't compile on some > compilers (the one I use, g++-4.0, for instance). Thanks, I will take this into account > -- > Fran?ois Duranleau > LIGUM, Universit? de Montr?al > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From mail at a-beyer.de Thu May 4 10:05:01 2006 From: mail at a-beyer.de (Andreas Beyer) Date: Thu, 04 May 2006 10:05:01 +0200 Subject: [C++-sig] export std::set In-Reply-To: References: <4458AF90.1050800@a-beyer.de> Message-ID: <4459B5AD.4010603@a-beyer.de> Fran?ois Duranleau wrote: > > If I may make a few suggestions: > >> // element access >> bool contains(const KeyType key) >> { return count(key)>0; } >> // we must define add() for it gets explicit argument types >> void add(const KeyType key) >> { insert(key); } >> void remove(const KeyType key) >> // improve error handling here >> { if (!contains(key)) throw "element not in set"; >> erase(key); } > > > Why not put the key parameter as a const reference instead of copying? > Good point, no problem with contains() and remove(). Is there no risk with add()? What if the object that is passed to add() does not exist beyond its current scope? Like this: void some_function(py_set& a_set) { string s = "hello world"; a_set.add(s); } py_set my_set; some_function(my_set); // Is it certain that 's' in 'my_set' still exists at this point? > Also, for remove, it would probably be best to write it like this: > > void remove( const KeyType& key ) > { > typename source_type::iterator i = this->find( key ) ; > if ( i == this->end() ) > { > throw "element not in set" ; > } > this->erase( i ) ; > } > > This way you look up for the key only once, not twice. Another good point. > > Also, everywhere in py_set<>, you need to either make all calls to > some base class's (with template arguments dependent on the current > class) method qualified (e.g. with this-> as above) or "import" them > with 'using' declarations, or else this code is not standard and won't > compile on some compilers (the one I use, g++-4.0, for instance). > Ups. I wasn't aware of that. Thanks for the warning! Andreas From abhi at qualcomm.com Thu May 4 19:32:21 2006 From: abhi at qualcomm.com (Abhi) Date: Thu, 04 May 2006 10:32:21 -0700 Subject: [C++-sig] Exposing a class with private dtor Message-ID: <4CA0F4DA2F3A95AF1E4AC2CF@[10.30.6.184]> Question 1. How do I expose a class which has a private dtor? The class has static method to destroy it instead? class PrivateCtorDtor { public: int nonStaticVariable; static int staticVariable; static PrivateCtorDtor* allocate(); static void free(PrivateCtorDtor* ); static int getStaticVariable() { return staticVariable; } private: ~PrivateCtorDtor(); private: PrivateCtorDtor(); }; Question 2: I tried doing this by wrapping the class with a derived class. For example: bp::class_("PrivateCtorDtor", bp::no_init) where PrivateCtorDtor_YWrapper class is derived from the PrivateCtorDtor class. And PrivateCtorDtor_YWrapper dtor calls the free static method of the PrivateCtorDtor class. But I __could not get it to work__. Question 3: Is it possible to do this without creating the derived class as above? For example, by doing a .def on some python function name (either "__del__" or something like that) Question 4: Is it even possible using Boost.Python? thanks - Abhi From abhi at qualcomm.com Thu May 4 19:34:59 2006 From: abhi at qualcomm.com (Abhi) Date: Thu, 04 May 2006 10:34:59 -0700 Subject: [C++-sig] Exposing a class with private ctor and private dtor In-Reply-To: <7465b6170605032241j2f1cde26qfe27e786d6db7e7c@mail.gmail.com> References: <3C41BF3554E1B4847206FE26@ASACHDEV.na.qualcomm.com> <7465b6170605032241j2f1cde26qfe27e786d6db7e7c@mail.gmail.com> Message-ID: --On Thursday, May 04, 2006 8:41 AM +0300 Roman Yakovenko wrote: > On 5/4/06, Abhi wrote: >> Question 1. How do I expose a class which has a private dtor? The class >> has static method to destroy it instead? > > I don't know, please post the question in a separate thread. will do. > >> >> Observation 1: Running py++ on it does not produce the right code! It >> takes care of the case of private ctor in the above case, but does not >> take care of the private dtor. > > I thought, but did not tested, that > bp::class_< PrivateCtorDtor, boost::noncopyable >( "PrivateCtorDtor", > bp::no_init ) > should work, obviously I was wrong ( twice ). > > I hope, you will find the answer to your first question and will post > it here. Thus I will be able > to implement the solution in py++ Once I get some responses, I will post a summary. > >> Question 2: I think this can be done by wrapping the class with a derived >> class. >> For example: >> >> bp::class_("PrivateCtorDtor", bp::no_init) >> >> where PrivateCtorDtor_YWrapper class is derived from the PrivateCtorDtor >> class. >> And PrivateCtorDtor_YWrapper dtor calls the free static method of the >> PrivateCtorDtor class. >> >> But I __could not get it to work__. > > May be it could not be done this way :-)? I am not sure if this is a Boost.Python limitation ==> cannot be done at all using Boost.Python, hence py++. > >> Question 3: Is it possible to do this without creating the derived class >> as above? For example, by doing a .def on some python function name >> (either "__del__" or something like that) > > Interesting idea. You want to map PrivateCtorDtor::free function to > __del__ method, right? Actually, that did not work at all. Seems like python calls __del__ and then calls the C++ destructor. Thus, I cannot avoid a call to the C++ destructor. Is there anyway to tell python to decrement the reference count on the object to zero rather than deleting it. Maybe using auto_ptr might help. Any Ideas? > >> thanks >> - Abhi > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ From yamokosk at ufl.edu Thu May 4 20:46:59 2006 From: yamokosk at ufl.edu (J.D. Yamokoski) Date: Thu, 04 May 2006 14:46:59 -0400 Subject: [C++-sig] Best way to use python as an API inside a Qt/C++ app? In-Reply-To: <44500E62.5060309@sympatico.ca> References: <20060426232901.8DC8F1E4005@bag.python.org> <44500E62.5060309@sympatico.ca> Message-ID: <445A4C23.1000404@ufl.edu> >>And what is the best approach (tool) to implementing >>this? PyQt, boost.python, other? > > > Qt4). How to reflect your own code into python is a different issue. > Boost.python is definitely a good choice, though if you use a lot of > Qt internally it would be best to stay with the tool used to generate > the Qt bindings, and simply add your own classes. > I am creating a Windows program using MFC in which I need to do the same thing, expose my CDocument data (if anyone is familiar with MFC programming) to Python... essentially expose my entire program state/data to Python. Like the original poster, I have come across Python wrappings for just about everything under the sun, including MFC. But as you have pointed out going from program -> Python seems to be the trickiest part. Is there a tutorial, best practices, tips, or anything for efficiently doing this? Is anyone really familiar with Blender or something similar? Would their code base be a good place to start? J.D. Yamokoski From duranlef at iro.umontreal.ca Fri May 5 19:30:22 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Fri, 5 May 2006 13:30:22 -0400 (EDT) Subject: [C++-sig] export std::set In-Reply-To: <4459B5AD.4010603@a-beyer.de> References: <4458AF90.1050800@a-beyer.de> <4459B5AD.4010603@a-beyer.de> Message-ID: On Thu, 4 May 2006, Andreas Beyer wrote: >> Why not put the key parameter as a const reference instead of copying? >> > Good point, no problem with contains() and remove(). Is there no risk > with add()? What if the object that is passed to add() does not exist > beyond its current scope? Like this: > > void some_function(py_set& a_set) > { > string s = "hello world"; > a_set.add(s); > } > py_set my_set; > some_function(my_set); > // Is it certain that 's' in 'my_set' still exists at this point? Well, what is the difference between the local variable s in this example and the 'local' variable key in add? The only way it would be a risk is if no copy of the object was put in the set, but only a reference or pointer, and in that case, passing the argument by copy is garantied to cause trouble. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "Just as a drop of water causes ripples in a pond, where there is anger and fear, there is conflict." - Folken, in _The Vision of Escaflowne_ From mail at a-beyer.de Fri May 5 14:09:24 2006 From: mail at a-beyer.de (Andreas Beyer) Date: Fri, 05 May 2006 14:09:24 +0200 Subject: [C++-sig] vector<> to string Message-ID: <445B4074.5030804@a-beyer.de> Hi! I wanted to create a convinient function for converting vectors etc. into python strings. I would like to attach that functionality to the vector_indexing_suite like this: BOOST_PYTHON_MODULE(str_test) { python::class_< std::vector >("IntList") .def(python::vector_indexing_suite< std::vector >()) .def(python::self_ns::str(python::self)) ; } I got this mechanism working if VALUE_T is some custom class. However, if VALUE_T is simply 'int' it doesn't work. So here is the code, that uses either int or MyInt as value type for the vector<>. using namespace boost; #define VALUE_T MyInt //#define VALUE_T int // wrapper for int class MyInt { public: MyInt(int v=0): i(v) {}; int i; bool operator== (const MyInt& other) { return this->i == other.i; } }; // to-string converter for MyInt std::ostream& operator<<(std::ostream& os, const MyInt& I) { os << "I" << I.i; return os; } // convert vector into python-style string std::ostream& operator<<(std::ostream& os, const std::vector& v) { typedef std::vector vtype; os << "["; vtype::const_iterator end = v.end(); for(vtype::const_iterator it = v.begin(); it!=end; it++) { operator<< (os, lexical_cast(*it) ); // convert elements from vector<> if (it for playing std::vector make_int_v() { std::vector v; v.push_back(VALUE_T(0)); v.push_back(VALUE_T(1)); return v; } BOOST_PYTHON_MODULE(str_test) { python::class_("MyInt") .def_readwrite("i", &MyInt::i) .def(python::self_ns::str(python::self)) ; python::class_< std::vector >("IntList") .def(python::vector_indexing_suite< std::vector >()) .def(python::self_ns::str(python::self)) // <<< line 82 (boom!) ; python::def("vector", &make_int_v); } If VECTOR_T is MyInt the result in python is perfect: >>> from str_test import * >>> print vector() [I0, I1] >>> However, if VECTOR_T is int I get this compiler error: vector_writer.cpp:82: instantiated from here /home/beyer/boost/boost/boost/lexical_cast.hpp:151: error: no match for 'operator<<' in 'this->boost::detail::lexical_stream, std::allocator >, std::vector > >::stream << input' /usr/include/g++/bits/ostream.tcc:63: error: candidates are: [LONG LIST OF CANDIDATES] Line 82 is indicated in the above code. Help is appreciated! Andreas PS: Of course the vector-to-string converter shall eventually become a template-function. From duranlef at iro.umontreal.ca Sat May 6 19:43:10 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Sat, 6 May 2006 13:43:10 -0400 (EDT) Subject: [C++-sig] vector<> to string In-Reply-To: <445B4074.5030804@a-beyer.de> References: <445B4074.5030804@a-beyer.de> Message-ID: On Fri, 5 May 2006, Andreas Beyer wrote: > // convert vector into python-style string > std::ostream& operator<<(std::ostream& os, const std::vector& v) { [...] > } The problem is here. boost::lexical_cast relies on ADL to find the appropriate operator<<. However, in the case for int, it cannot find it because the operator is declared outside of the namespace std (that is, this operator is not in the list of "friends" to std::vector; and it seems that base types have to associated namespaces). However, in the case of MyInt, it is declared in the global namespace, thus allowing ADL to look in the global namespace as well for the operator. The simple solution is to declare the operator<< in namespace std. Actually, it is usually better, I think, to declare operators in the same namespace as the manipulated types. P.S.: In the definition of your operator, you use: operator<<(os, lexical_cast(*it)); Why bother with the lexical_cast here? Why not simply write: os << *it; ? It would also be more efficient. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "Nothing will ever be attempted, if all possible objections must be first overcome." - Samuel Johnson, 1759. From roman.yakovenko at gmail.com Sun May 7 15:45:50 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 7 May 2006 16:45:50 +0300 Subject: [C++-sig] Exposing a class with private dtor In-Reply-To: <4CA0F4DA2F3A95AF1E4AC2CF@10.30.6.184> References: <4CA0F4DA2F3A95AF1E4AC2CF@10.30.6.184> Message-ID: <7465b6170605070645o780dfc98o8093b8ccdf2163b2@mail.gmail.com> On 5/4/06, Abhi wrote: > Question 1. How do I expose a class which has a private dtor? The class has > static method to destroy it instead? > > Question 4: Is it even possible using Boost.Python? > I think you can do it. I would like to be wrong, but.. Here is, I think, relevant piece of code from libs\python\src\object\class.cpp static void instance_dealloc(PyObject* inst) { instance<>* kill_me = (instance<>*)inst; for (instance_holder* p = kill_me->objects, *next; p != 0; p = next) { next = p->next(); p->~instance_holder(); instance_holder::deallocate(inst, dynamic_cast(p)); } > > thanks > - Abhi -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From abhi at qualcomm.com Mon May 8 23:03:40 2006 From: abhi at qualcomm.com (Abhi) Date: Mon, 08 May 2006 14:03:40 -0700 Subject: [C++-sig] Exposing a class with private dtor In-Reply-To: <7465b6170605070645o780dfc98o8093b8ccdf2163b2@mail.gmail.com> References: <4CA0F4DA2F3A95AF1E4AC2CF@10.30.6.184> <7465b6170605070645o780dfc98o8093b8ccdf2163b2@mail.gmail.com> Message-ID: hmmm.... Not sure on how to use this in my code/wrappers? The only way I can think of exposing a class with a private dtor to python is via composition. For example, class A { public: void foo1(); static destroy(A* ); private: ~A(); }; -------------------- class A_wrap { private: A* a; public: A_wrap() { a = new A(); } void foo1() { a->foo1(); } ~A_wrap() { A::destroy(a); } }; And then expose A_wrap as "A" to python. Not very scalable! thanks - Abhi thanks - Abhi --On Sunday, May 07, 2006 4:45 PM +0300 Roman Yakovenko wrote: > On 5/4/06, Abhi wrote: >> Question 1. How do I expose a class which has a private dtor? The class >> has static method to destroy it instead? > >> >> Question 4: Is it even possible using Boost.Python? >> > > I think you can do it. I would like to be wrong, but.. > > Here is, I think, relevant piece of code from > libs\python\src\object\class.cpp > > static void instance_dealloc(PyObject* inst) > { > instance<>* kill_me = (instance<>*)inst; > > for (instance_holder* p = kill_me->objects, *next; p != 0; p = > next) > { > next = p->next(); > p->~instance_holder(); > instance_holder::deallocate(inst, dynamic_cast(p)); > } > > >> >> thanks >> - Abhi > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ From ryan.gallagher at gmail.com Mon May 8 23:34:37 2006 From: ryan.gallagher at gmail.com (Ryan Gallagher) Date: Mon, 8 May 2006 21:34:37 +0000 (UTC) Subject: [C++-sig] Howto expose exception classes using boost.python? References: <4a41ceba0604251239x340ee52am7aef5c86bc6c9cb2@mail.gmail.com> <7465b6170604262244x5971cc89k89283af7c5f47837@mail.gmail.com> Message-ID: David Abrahams boost-consulting.com> writes: > Officially, it does require that exceptions be derived from > PyExc_Exception (I don't remember where that's documented), but > unofficially, you can throw anything :) > Does this really work in practice though? (With classes exposed through Boost.Python at least?) I was also working on this problem several months back, translating an exception class I exposed through Boost.Python using class_<> to raise an instance of the python class. (I had this all wrapped in an exception_<> wrapper which was nice.) This seemed to work fine if I caught the exact class type, however, it did not work if I tried to catch a base class or nothing in the exception list matched the exception that was raised. The python interpreter would always give me a stack corruption(?) in this case. (Windows python 2.4.1 I believe.) Sorry for the total lack of concrete example code. I had also tried many different approaches on this and don't remember which worked and which didn't. I'll dig up my old project that I was using for experimenting with this and post it tomorrow along with the exact error I saw in python. In the end I think I just wrote a python exception class and translated the C++ exception to raise it. Not ideal though. -Ryan From mail at a-beyer.de Mon May 8 15:15:30 2006 From: mail at a-beyer.de (Andreas Beyer) Date: Mon, 08 May 2006 15:15:30 +0200 Subject: [C++-sig] vector<> to string In-Reply-To: References: <445B4074.5030804@a-beyer.de> Message-ID: <445F4472.6040804@a-beyer.de> Fran?ois Duranleau wrote: > On Fri, 5 May 2006, Andreas Beyer wrote: > >> // convert vector into python-style string >> std::ostream& operator<<(std::ostream& os, const >> std::vector& v) { > > [...] > >> } > > [...] > > The simple solution is to declare the operator<< in namespace std. > Actually, it is usually better, I think, to declare operators in the > same namespace as the manipulated types. Excellent, this solves the issue. > > P.S.: In the definition of your operator, you use: > operator<<(os, lexical_cast(*it)); > Why bother with the lexical_cast here? Why not simply write: > os << *it; > ? It would also be more efficient. For what ever reason it only works if I use boost::lexical_cast<>. Otherwise I get the same compile error: gcc-C++-action bin/csrc/str_test.so/gcc/release/shared-linkable-true/vector_writer.o vector_writer.cpp: In function `std::ostream& std::operator<<(std::ostream&, const std::vector >&)': vector_writer.cpp:60: error: call of overloaded `operator<<( std::basic_ostream >&, const int&)' is ambiguous Andreas PS: Here is the "final" template, which works for MyInt and for int. Maybe something like this could be added to the indexing suite. namespace std{ // convert vector into python-style string template std::ostream& operator<<(std::ostream& os, const std::vector& v) { typedef std::vector vtype; os << "["; typename vtype::const_iterator end = v.end(); for(typename vtype::const_iterator it = v.begin(); it!=end; it++) { operator<< (os, boost::lexical_cast(*it) ); if (it <7465b6170604262244x5971cc89k89283af7c5f47837@mail.gmail.com> Message-ID: Ryan Gallagher gmail.com> writes: > > David Abrahams boost-consulting.com> writes: > > > Officially, it does require that exceptions be derived from > > PyExc_Exception (I don't remember where that's documented), but > > unofficially, you can throw anything :) > > > > Does this really work in practice though? (With classes exposed through > Boost.Python at least?) > > I was also working on this problem several months back, translating an > exception class I exposed through Boost.Python using class_<> to raise an > instance of the python class. > ... Here's the example output and code I had. Ignoring the hardcoded module name this seemed to be a good solution, except that it doesn't quite work. ;-) (Also, I'd prefer to map std::runtime_error to Python's equivalent.) (What I had recalled as a stack corruption was the infact just the SystemError exception.) Here's the python output I had: Python 2.4.1c1 (#63, Mar 10 2005, 10:36:41) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import pit >>> dir(pit) ['RuntimeError', '__doc__', '__file__', '__name__', 'must_be_even', 'not_even_ex ception', 'numeric_error'] >>> pit.must_be_even(6) >>> pit.must_be_even(7) Traceback (most recent call last): File "", line 1, in ? : Numeric Error: must_be_even(int) 7 is not even ! >>> try: ... pit.must_be_even(7) ... except pit.not_even_exception, e: ... print(e) ... Numeric Error: must_be_even(int) 7 is not even! >>> try: ... pit.must_be_even(7) ... except pit.numeric_error, e: ... print(e) ... Traceback (most recent call last): File "", line 4, in ? SystemError: 'finally' pops bad exception >>> try: ... pit.must_be_even(7) ... except pit.numeric_error, e: ... print('1 ') ... except pit.not_even_exception, e: ... print('2') ... 2 For this wrapper code: ########################################## #include using namespace boost::python; #include #include #include #include #include #include #include struct numeric_error : std::runtime_error { numeric_error(std::string const& msg) : std::runtime_error(boost::str(boost::format("Numeric Error: %s") % msg)) {} }; struct not_even_exception : numeric_error { not_even_exception(int i, std::string extra_message) : numeric_error(boost::str( boost::format("%s %d is not even!") % extra_message % i)) , m_i(i) , m_msg(extra_message) {} int m_i; std::string m_msg; }; void must_be_even(int i) { if(i % 2 != 0) { throw not_even_exception(i, "must_be_even(int)"); } } namespace { template std::string wrap_output(T const& exn) { return exn.what(); } } namespace wrap { template< typename CPP_ExceptionType , typename X1 = ::boost::python::detail::not_specified , typename X2 = ::boost::python::detail::not_specified , typename X3 = ::boost::python::detail::not_specified > class exception : public ::boost::python::class_ { public: typedef ::boost::python::class_ base_type; typedef exception self; // Construct with the class name, with or without docstring, and default // __init__() function exception(char const* name, char const* doc = 0) : base_type(name, doc), m_exception_name(name) { init(); } // Construct with class name, no docstring, and an uncallable // __init__ function exception(char const* name, no_init_t const& no_init_tag) : base_type(name, no_init_tag), m_exception_name(name) { init(); } // Construct with class name, docstring, and an uncallable // __init__ function exception(char const* name, char const* doc, no_init_t const& no_init_tag) : base_type(name, doc, no_init_tag), m_exception_name(name) { init(); } // Construct with class name and init<> function template inline exception(char const* name, init_base const& i) : base_type(name, i), m_exception_name(name) { init(); } // Construct with class name, docstring and init<> function template inline exception( char const* name , char const* doc , init_base const& i) : base_type(name, doc, i), m_exception_name(name) { init(); } private: std::string get_module_qualified_name() const { return boost::str(boost::format("%s.%s") % "pit" % m_exception_name); } void init() const { using namespace boost; function conversion_func = bind( &exception::to_python_exception , *this, get_module_qualified_name(), _1); ::boost::python::register_exception_translator(conversion_func); } static void to_python_exception( ::boost::python::object const& exn_type , std::string const& exception_name , typename base_type::wrapped_type const& exn ) { static const ::boost::python::to_python_value convert_argument; PyErr_SetObject(exn_type.ptr(), convert_argument(exn)); throw_error_already_set(); } std::string const m_exception_name; }; } BOOST_PYTHON_MODULE(pit) { wrap::exception("RuntimeError", init()) .def("__str__", &std::runtime_error::what) ; wrap::exception > ("numeric_error", init()) .def("__str__", &wrap_output) ; wrap::exception > ("not_even_exception", init()) .def("__str__", &wrap_output) ; def( "must_be_even" , &must_be_even , "raises not_even_exception if argument is not even."); } From abhi at qualcomm.com Wed May 10 03:00:23 2006 From: abhi at qualcomm.com (Abhi) Date: Tue, 09 May 2006 18:00:23 -0700 Subject: [C++-sig] Exposing a C++ function that takes 2 out arguments to python Message-ID: How do I expose a C++ function that takes 2 out arguments with different memory ownership semantics to python. For instance, consider A, B to be user-defined types class C { public: B* b_; void foo(A*& a, B*& b) { // create A on the heap and let caller take ownership A* a2 = new A() a = a2; // create B, but we retain ownership b_ = new B(); b = b_; } ~C() { delete b_; } }; Notice that object "a" is to be destroyed in python, while "b" is owned by C++ How do I expose this in python? I tried the following: bp::tuple foo_Wrapper(C& self) { A* a; B* b; self.foo(a, b) // Case1. In this case the "a" is never destroyed in python // -- "a" is leaked -- NOT what I want! // "b" is ok make_tuple(bp::ptr(a), bp::ptr(b) ); // Case2: In this case they get copy constructed into the tuple // -- that means memory for "a" is leaked! // -- I don't really want a copy -- Changes the semantics, I want to // modify "a" & "b" in python && it is expensive to copy make_tuple(a, b); } Any other ideas? thanks -= Abhi From Naceur.Meskini at sophia.inria.fr Wed May 10 17:23:09 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Wed, 10 May 2006 17:23:09 +0200 Subject: [C++-sig] Pyste: RuntimeError no declaration found! In-Reply-To: <445A4C23.1000404@ufl.edu> References: <20060426232901.8DC8F1E4005@bag.python.org> <44500E62.5060309@sympatico.ca> <445A4C23.1000404@ufl.edu> Message-ID: <4462055D.4040705@sophia.inria.fr> Hi all, I'm trying to use pyste to expote my code (Triangulation_3 class) in python, and some times I get this error message: Traceback (most recent call last): File "pyste.py", line 424, in ? main() File "pyste.py", line 418, in main status = Begin() File "pyste.py", line 257, in Begin return GenerateCode(parser, module, out, interfaces, multiple) File "pyste.py", line 381, in GenerateCode export.SetDeclarations(declarations) File "/home/nmeskini/TEMP/pyste/ClassExporter.py", line 62, in SetDeclarations decl = self.GetDeclaration(self.info.name) File "/home/nmeskini/TEMP/pyste/Exporter.py", line 73, in GetDeclaration decls = self.GetDeclarations(fullname) File "/home/nmeskini/TEMP/pyste/Exporter.py", line 68, in GetDeclarations raise RuntimeError, 'no %s declaration found!' % fullname RuntimeError: no Triangulation_3 declaration found! I'm sure that pyste find this class, because when I deliberately do some syntax errors in my class, I get the error message of gccxml. I'm wondering If someone got this message before and know how to deal with it. Thanks in advance. Naceur INRIA. -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Thu May 11 06:22:12 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 11 May 2006 07:22:12 +0300 Subject: [C++-sig] Pyste: RuntimeError no declaration found! In-Reply-To: <4462055D.4040705@sophia.inria.fr> References: <20060426232901.8DC8F1E4005@bag.python.org> <44500E62.5060309@sympatico.ca> <445A4C23.1000404@ufl.edu> <4462055D.4040705@sophia.inria.fr> Message-ID: <7465b6170605102122x259fe040h29c105a5dbfff01d@mail.gmail.com> On 5/10/06, Naceur Meskini wrote: > > Hi all, > > I'm trying to use pyste to expote my code (Triangulation_3 class) in > python, and some times I get this error message: Pyste is not under active development. I am almost sure you will have more luck with pyplusplus: http://www.language-binding.net/pyplusplus/pyplusplus.html and tutorials: http://www.language-binding.net/pyplusplus/tutorials/tutorials.html > Thanks in advance. > > Naceur > INRIA. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From Naceur.Meskini at sophia.inria.fr Thu May 11 10:59:59 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Thu, 11 May 2006 10:59:59 +0200 Subject: [C++-sig] Pyste: RuntimeError no declaration found! In-Reply-To: <7465b6170605102122x259fe040h29c105a5dbfff01d@mail.gmail.com> References: <20060426232901.8DC8F1E4005@bag.python.org> <44500E62.5060309@sympatico.ca> <445A4C23.1000404@ufl.edu> <4462055D.4040705@sophia.inria.fr> <7465b6170605102122x259fe040h29c105a5dbfff01d@mail.gmail.com> Message-ID: <4462FD0F.9050304@sophia.inria.fr> Roman Yakovenko wrote: >Pyste is not under active development. I am almost sure you will have >more luck with >pyplusplus: >http://www.language-binding.net/pyplusplus/pyplusplus.html >and tutorials: >http://www.language-binding.net/pyplusplus/tutorials/tutorials.html > > Thank you Roman, But according to the comparision between Pyste and pyplusplus (http://www.language-binding.net/pyplusplus/comparisons/pyste.html) pyplusplus don't support templates, and all my code is templated? >> Thanks in advance. >> >> Naceur >> INRIA. >> >> > > > From roman.yakovenko at gmail.com Thu May 11 11:37:52 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 11 May 2006 12:37:52 +0300 Subject: [C++-sig] Pyste: RuntimeError no declaration found! In-Reply-To: <4462FD0F.9050304@sophia.inria.fr> References: <20060426232901.8DC8F1E4005@bag.python.org> <44500E62.5060309@sympatico.ca> <445A4C23.1000404@ufl.edu> <4462055D.4040705@sophia.inria.fr> <7465b6170605102122x259fe040h29c105a5dbfff01d@mail.gmail.com> <4462FD0F.9050304@sophia.inria.fr> Message-ID: <7465b6170605110237kadb8cj44348a1318f403f3@mail.gmail.com> On 5/11/06, Naceur Meskini wrote: > Roman Yakovenko wrote: > > >Pyste is not under active development. I am almost sure you will have > >more luck with > >pyplusplus: > >http://www.language-binding.net/pyplusplus/pyplusplus.html > >and tutorials: > >http://www.language-binding.net/pyplusplus/tutorials/tutorials.html > > > > > Thank you Roman, > But according to the comparision between Pyste and pyplusplus > (http://www.language-binding.net/pyplusplus/comparisons/pyste.html) > pyplusplus don't support templates, and all my code is templated? It is not true. I have to correct this document. pyplusplus has same level functionality. The reason is that they both use GCC-XML as C++ parser. You can take a look on boost.date_time example. > >> Thanks in advance. > >> > >> Naceur > >> INRIA. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From abhi at qualcomm.com Thu May 11 18:26:08 2006 From: abhi at qualcomm.com (Abhi) Date: Thu, 11 May 2006 09:26:08 -0700 Subject: [C++-sig] Exposing a C++ function that takes 2 out arguments to python Message-ID: <34BABD0C0EE15EF81C8C595E@[10.50.0.174]> Roman, Any idea if py++ will handle this case? ------------- How do I expose a C++ function that takes 2 out arguments with different memory ownership semantics to python. For instance, consider A, B to be user-defined types class C { public: B* b_; void foo(A*& a, B*& b) { // create A on the heap and let caller take ownership A* a2 = new A() a = a2; // create B, but we retain ownership b_ = new B(); b = b_; } ~C() { delete b_; } }; Notice that object "a" is to be destroyed in python, while "b" is owned by C++ How do I expose this in python? I tried the following: bp::tuple foo_Wrapper(C& self) { A* a; B* b; self.foo(a, b) // Case1. In this case the "a" is never destroyed in python // -- "a" is leaked -- NOT what I want! // "b" is ok make_tuple(bp::ptr(a), bp::ptr(b) ); // Case2: In this case they get copy constructed into the tuple // -- that means memory for "a" is leaked! // -- I don't really want a copy -- Changes the semantics, I want to // modify "a" & "b" in python && it is expensive to copy make_tuple(a, b); } Any other ideas? thanks -= Abhi From roman.yakovenko at gmail.com Thu May 11 19:43:24 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 11 May 2006 20:43:24 +0300 Subject: [C++-sig] Exposing a C++ function that takes 2 out arguments to python In-Reply-To: <34BABD0C0EE15EF81C8C595E@10.50.0.174> References: <34BABD0C0EE15EF81C8C595E@10.50.0.174> Message-ID: <7465b6170605111043x1072d34am698d3e3364599d0a@mail.gmail.com> On 5/11/06, Abhi wrote: > Roman, Any idea if py++ will handle this case? > ------------- > How do I expose a C++ function that takes 2 out arguments with different > memory ownership semantics to python. For instance, > > consider A, B to be user-defined types > > class C > { > public: > B* b_; > > void foo(A*& a, B*& b) > { > // create A on the heap and let caller take ownership > A* a2 = new A() > a = a2; > > // create B, but we retain ownership > b_ = new B(); > b = b_; > } > > ~C() > { > delete b_; > } > > }; > > Notice that object "a" is to be destroyed in python, while "b" is owned by > C++ > > How do I expose this in python? > > I tried the following: > > bp::tuple foo_Wrapper(C& self) > { > A* a; > B* b; > self.foo(a, b) > // Case1. In this case the "a" is never destroyed in python > // -- "a" is leaked -- NOT what I want! > // "b" is ok > make_tuple(bp::ptr(a), bp::ptr(b) ); > > // Case2: In this case they get copy constructed into the tuple > // -- that means memory for "a" is leaked! > // -- I don't really want a copy -- Changes the semantics, I want to > // modify "a" & "b" in python && it is expensive to copy > make_tuple(a, b); > } > > > Any other ideas? Yes. I could be wrong, but from my experience boost.python does not work well with not so good C++ code. As for me this case is one of them. If you can redefine function foo little: std::pair< std::auto_ptr< A >, boost::shared_ptr > foo(); I think it is possible to expose this function with default value policy, but I could be wrong. An other way is to define your own call policies. Take a look on: CallPolicies ResultConverter[Generator] I don't feel, that I have enough knowledge to give you any advice in this area. There is another issue with this code: class C has public member variable B*. It is very difficult to expose that member. Few weeks ago, there was some thread that provided solution to "get" functionality. I implemented it in pyplusplus. I failed to implement "set" functionality. > thanks My pleasure > -= Abhi > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From Naceur.Meskini at sophia.inria.fr Thu May 11 22:36:20 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur.Meskini at sophia.inria.fr) Date: Thu, 11 May 2006 22:36:20 +0200 (CEST) Subject: [C++-sig] templated classes in pyplusplus In-Reply-To: <7465b6170605110237kadb8cj44348a1318f403f3@mail.gmail.com> References: <20060426232901.8DC8F1E4005@bag.python.org> <44500E62.5060309@sympatico.ca> <445A4C23.1000404@ufl.edu> <4462055D.4040705@sophia.inria.fr> <7465b6170605102122x259fe040h29c105a5dbfff01d@mail.gmail.com> <4462FD0F.9050304@sophia.inria.fr> <7465b6170605110237kadb8cj44348a1318f403f3@mail.gmail.com> Message-ID: <33154.82.242.109.34.1147379780.squirrel@imap-sop.inria.fr> > On 5/11/06, Naceur Meskini wrote: >> Roman Yakovenko wrote: > >> Thank you Roman, >> But according to the comparision between Pyste and pyplusplus >> (http://www.language-binding.net/pyplusplus/comparisons/pyste.html) >> pyplusplus don't support templates, and all my code is templated? > > It is not true. I have to correct this document. pyplusplus has same > level functionality. > The reason is that they both use GCC-XML as C++ parser. I'm trying to analyse the date_time example in order to do the same, but in vain, I also read all messages concerning templates in pyplusplus and I find out that you have said that there is many way to expose templated classes and one them is to use sizeof Can you please complete the explication of that, because I don't know how to use file_configuration_t ===================== #include "TempClass.h" namespace details{ inline void export_templates(){ sizeof( TempClass ); } } After this you can use pygccxml.parser.file_configuration_t to include this file to parse process. thanks Naceur MESKINI. ============================= > You can take a look on boost.date_time example. > >> >> Thanks in advance. >> >> >> >> Naceur >> >> INRIA. > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From GiselaMcC at aol.com Thu May 11 23:24:06 2006 From: GiselaMcC at aol.com (GiselaMcC at aol.com) Date: Thu, 11 May 2006 17:24:06 EDT Subject: [C++-sig] Run Time Error Message-ID: <3dc.2683df7.31950576@aol.com> Greetings, I came across your post while I was searching for a solution to a problem I am having. I am fairly computer literate, but by no means on your level. The problem I am having is every couple of minutes I get the following error: Microsoft Visual C++ Runtime (in blue) Program: C:\ Program files\Internet Explorer\explore.exe The application has requested Runtime to terminate it in an unusual way. Please contact the applications support team. I have used a number of diagnostic programs I have w/o success. I would be very grateful if you could pass along a hint or two or (gasp) the solution> Thanks in advance, Erik -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Fri May 12 12:56:43 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 12 May 2006 13:56:43 +0300 Subject: [C++-sig] templated classes in pyplusplus In-Reply-To: <33154.82.242.109.34.1147379780.squirrel@imap-sop.inria.fr> References: <20060426232901.8DC8F1E4005@bag.python.org> <44500E62.5060309@sympatico.ca> <445A4C23.1000404@ufl.edu> <4462055D.4040705@sophia.inria.fr> <7465b6170605102122x259fe040h29c105a5dbfff01d@mail.gmail.com> <4462FD0F.9050304@sophia.inria.fr> <7465b6170605110237kadb8cj44348a1318f403f3@mail.gmail.com> <33154.82.242.109.34.1147379780.squirrel@imap-sop.inria.fr> Message-ID: <7465b6170605120356idb1564ag577ecfed3b126e50@mail.gmail.com> On 5/11/06, Naceur.Meskini at sophia.inria.fr wrote: > I'm trying to analyse the date_time example in order to do the same, but > in vain, I also read all messages concerning templates in pyplusplus and I > find out that you have said that there is many way to expose templated > classes and one them is to use sizeof > Can you please complete the explication of that, because I don't know how > to use file_configuration_t file_configuration_t is rather cool feature. When you create module_builder_t class instance you should pass list of files. This list can contain string( == file paths ) and/or instances of file_configuration_t class. file_configuration_t is class with fat interface. It has 4 states: 1. it could contain reference to source file. Use "create_source_fc" function to create an instance of file_configuration_t 2. it could contain reference to source file and xml file. In this case if xml file exist, source file will not be parsed by gccxml. If xml file does not exists, source file will be parsed and xml file will be saved for future use. See create_cached_source_fc function 3. it could contain reference to xml file only See create_gccxml_fc 4. it could contain some text. In this case, parser will create temporal file on disk and will pass it as an argument to gccxml. See create_text_fc In most cases you don't all those features. If I were you, I would create regular source file and put all template instantiation there. Any way the code: tmpl_inst = """ ===================== #include "TempClass.h" namespace details{ inline void export_templates(){ sizeof( TempClass ); } } """ import module_builder mb = module_builder.module_builder_t( [ module_builder.create_text_fc( tmpl_inst ) ] , .... ) > thanks Do you understand it know? > Naceur MESKINI. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From nojhan at free.fr Sat May 13 20:38:56 2006 From: nojhan at free.fr (nojhan) Date: Sat, 13 May 2006 20:38:56 +0200 Subject: [C++-sig] Python API, Initialization, Path and classes Message-ID: I'm trying to embbed the python interpreter as a class attribute, initializing it in the constructor, and finalizing in destructor. The code is rather simple: // base_path is an attribute of the class, // initialized with argv[0] at the instanciation clog << "Python base program name asked: " << base_path << endl; Py_SetProgramName( base_path ); Py_Initialize(); clog << "Python isInitialized ? " << ( Py_IsInitialized()?"yes":"no" ) << endl; clog << "Python base program name set:" << Py_GetProgramName() << endl; clog << "Python path: " << Py_GetPath() << endl; But it produce a rather strange output : Python base program name asked: /home/nojhan/travail/openMetaheuristic/source/ometah/ometah Python isInitialized ? yes Python base program name set:/home/nojhan/travail/openMetaheuristic/source/ometah/ometah Python path: /usr/lib/python24.zip:/usr/lib/python2.4/:/usr/lib/python2.4/plat-linux2:/usr/lib/python2.4/lib-tk:/usr/lib/python2.4/lib-dynload The code ends in an ImportError if I try to import a module in the current path. Note that the python C API reference manual precise that Py_Initialize() "initializes the module search path (sys.path)" [1]. I'm searching for a way to force the python interpreter considering the current path when searching for available modules. [1] http://docs.python.org/api/initialization.html -- NoJhan From roman.yakovenko at gmail.com Sun May 14 11:12:20 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 14 May 2006 12:12:20 +0300 Subject: [C++-sig] pyplusplus template instantiation handling improvement Message-ID: <7465b6170605140212wc5fd32dj2661a894c416f7f4@mail.gmail.com> Hi. I committed a set of changes, that improves pyplusplus template instantiation handling. In order to try them you need SVN version of gccxml + pygccxml + pyplusplus. You can find more information about pygccxml and pyplusplus here: http://www.language-binding.net/ Examples 1. you have some template global function do_smth template< class X > struct basic_string{}; template< class Ch > basic_string do_smth(){ return basic_string(); } inline void inst(){ do_smth(); do_smth(); } gccxml reports that there are 2 functions with the same name - do_smth and different return types. Obviously this is wrong. This fact causes pyplusplus to generate wrong code( code, that could not be compiled ). Another example is class templates: namespace demangled{ template< unsigned long i1, unsigned long i2, unsigned long i3> struct item_t{ static const unsigned long v1 = i1; static const unsigned long v2 = i2; static const unsigned long v3 = i3; }; struct buggy{ typedef unsigned long ulong; typedef item_t< ulong( 0xDEECE66DUL ) | (ulong(0x5) << 32), 0xB, ulong(1) << 31 > my_item_t; my_item_t my_item_var; }; } gccxml reports my_item_var class name as "item_t<0deece66d,11,080000000>" Obviously the reported name is wrong. Now about solution: Recently I created a patch to gccxml, that adds demangled string to be dump to generated file. gccxml already dumps mangled string for every declaration. For example the mangled name of my_item_t class is: N9demangled6item_tILm3740067437ELm11ELm2147483648EEE If we demangle the string we will get: demangled::item_t<3740067437l, 11l, 2147483648l> As you can see, mangled string contains the correct name of the class. So, from now pygccxml + pyplusplus takes into account information extracted from demangled string. Enjoy -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From duranlef at iro.umontreal.ca Mon May 15 19:57:44 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Mon, 15 May 2006 13:57:44 -0400 (EDT) Subject: [C++-sig] Exposing boost::function In-Reply-To: References: <1137074745.15517.102.camel@chronos> <87irsoon63.fsf@boost-consulting.com> <1137142913.15517.167.camel@chronos> <878xtkmdzv.fsf@boost-consulting.com> <1137161942.15517.204.camel@chronos> <87k6d3lx18.fsf@boost-consulting.com> <1137399887.31678.25.camel@chronos> <87wtgz8zvo.fsf@boost-consulting.com> <1137487349.31678.85.camel@chronos> <87bqya7qnf.fsf@boost-consulting.com> <43CE1FEB.3090109@sophia.inria.fr> <1138348327.28594.2.camel@chronos> Message-ID: Hi all! Last weekend, I though of a few things about exposing boost::function to Python and I would like to share those ideas and know what others think about it. This is also a kind of follow up to the thread http://thread.gmane.org/gmane.comp.python.c++/9062/focus=9101 . Simply put, the problem is exposing something like: template < Func > void do_something( Func f ) { ... } where Func is a function of some kind (conceptually). The first step of the solution would be to actually expose this: using namespace boost::python ; typedef boost::function< the_appropriate_signature > function_type ; def( "do_something" , & do_something< function_type > ) ; but then (actually, before) when have to expose function_type. Suppose we do this: class_< function_type >( "Function" ) .def( "__call__" , & function_type::operator() ) ; and suppose we did something to create a Function from any callable object, then in Python, we would have to call do_something like, e.g.: do_something( Function( callable_object ) ) In C++, there is an implicit conversion between functors and functions to boost::function, so it would be very nice to do the same in Python, e.g.: do_something( callable_object ) Up to here we can ask ourselves: then is there any need to really expose boost::function? This is where I worked a few things. At first I thought: well, no, since in Python there is no need for such a class (it has its own mechanisms to abstract callbacks), then boost::function should be completely transparent. That means when we return a boost::function in C++, we should extract its content to Python. To avoid a very long message, I won't post the code here. You can find it there: http://www-etud.iro.umontreal.ca/~duranlef/python/function.hpp http://www-etud.iro.umontreal.ca/~duranlef/python/function_test.cpp http://www-etud.iro.umontreal.ca/~duranlef/python/function_test.py Read the comments. It is to note that as much as we can, we could like to avoid calling back to Python when calling the operator() of a boost::function in C++ if it contains a C++ object exposed to Python. We can achieve this to a limited extend with boost::python::implicitly_convertible<>, as presented in the code above. Now, there is a problem when a C++ function returns a boost::function, because its content might not be something exposed to Python, and as you can see in the code above (in function.hpp, the to_python converter), things can get ugly. This morning, I thought of another, simpler approach: expose boost::function "regularly", plus add some extra implicit converters to allow the above. This avoid the return problem, but we have an extra level of indirection when calling the "function" in Python. The code for that version is here: http://www-etud.iro.umontreal.ca/~duranlef/python/function_v2.hpp http://www-etud.iro.umontreal.ca/~duranlef/python/function_test_v2.cpp http://www-etud.iro.umontreal.ca/~duranlef/python/function_test_v2.py There is a Jamfile (and Jamrules, both inspired by the Boost.Python tutorial) here to compile both version: http://www-etud.iro.umontreal.ca/~duranlef/python/Jamfile http://www-etud.iro.umontreal.ca/~duranlef/python/Jamrules P.S.: the code is not complete and the way things are written is not necessarily the best way. It is mostly just a proof of concept. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "Like individual, like organization. Overspecialization leads to death." - Motoko Kusanagi, in _Ghost in the Shell_ From ypodpruzhnikov at mcode.ru Tue May 16 10:30:23 2006 From: ypodpruzhnikov at mcode.ru (Podpruzhnikov Yuri) Date: Tue, 16 May 2006 12:30:23 +0400 Subject: [C++-sig] Boost.Python and Coerce Message-ID: There is a function Coerce (type coercion at functions call) so, it?s functionality in Boost is not supported. Are there any other methods to repeat it?s functionality? example: there is a class, defining Byte, i.e. it repeats all the interface Numeric I want to make all the operations with Byte as well as with int It?s possible, using Python/C API ? I did it. It was done through Coerce. In C++ it?s possible as well, and It could be done with constructors But in Boost.python ? it?s IMPOSSIBLE As far as I understand that was supporting earlier, but now it?s not. What on earth shall I do? Shouldn?t I write two times more functions? And if I?ll have to support 3 or more types? Who faced with this problem earlier. Help me to solve it, please. From ypodpruzhnikov at mcode.ru Tue May 16 10:16:13 2006 From: ypodpruzhnikov at mcode.ru (Podpruzhnikov Yuri) Date: Tue, 16 May 2006 12:16:13 +0400 Subject: [C++-sig] Boost.Python and Coerce Message-ID: There is a function Coerce (type coercion at functions call) so, it?s functionality in Boost is not supported. Are there any other methods to repeat it?s functionality? example: there is a class, defining Byte, i.e. it repeats all the interface Numeric I want to make all the operations with Byte as well as with int It?s possible, using Python/C API ? I did it. It was done through Coerce. In C++ it?s possible as well, and It could be done with constructors But in Boost.python ? it?s IMPOSSIBLE As far as I understand that was supporting earlier, but now it?s not. What on earth shall I do? Shouldn?t I write two times more functions? And if I?ll have to support 3 or more types? Who faced with this problem earlier. Help me to solve it, please. From Naceur.Meskini at sophia.inria.fr Wed May 17 17:06:53 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Wed, 17 May 2006 17:06:53 +0200 Subject: [C++-sig] exposing a private member function? In-Reply-To: References: Message-ID: <446B3C0D.2060501@sophia.inria.fr> Hi everybody, the situation is : I have two classes, A and B defined like that: class A { public: insert(); ...... } class B: public A { pivate: insert(); ...... } and I want to expose both to python, is it possible to tell to boost that the function insert of B will be private in python. Is there someone who had encountered this probleme before. Please tell me if you have an idea. thanks a lot. Naceur INRIA. From seefeld at sympatico.ca Wed May 17 17:19:52 2006 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 17 May 2006 11:19:52 -0400 Subject: [C++-sig] exposing a private member function? In-Reply-To: <446B3C0D.2060501@sophia.inria.fr> References: <446B3C0D.2060501@sophia.inria.fr> Message-ID: <446B3F18.7080505@sympatico.ca> Naceur Meskini wrote: > Hi everybody, > > the situation is : > I have two classes, A and B defined like that: > class A > { > public: > insert(); > ...... > } > class B: public A > { > pivate: > insert(); > ...... > } > and I want to expose both to python, is it possible to tell to boost > that the function insert of B will be private in python. First of all, python doesn't have any notion of 'private'. The closest you can get is prefixing the name under which you register it by '_' or even '__'. Second, you can't expose a private method, since you'd need to dereference it ('&B::insert'), which the private access-spec prohibits. Third, I'm not sure what you mean by 'expose both'. They are simply two distinct methods of two different classes. To have them both available in the same class, they need to have different signatures, and you have to make sure that the second doesn't hide the first, for example by means of a 'using A::insert' declaration within B. Regards, Stefan From ryan.gallagher at gmail.com Thu May 18 00:29:29 2006 From: ryan.gallagher at gmail.com (Ryan Gallagher) Date: Wed, 17 May 2006 22:29:29 +0000 (UTC) Subject: [C++-sig] Ping: Howto expose exception classes using boost.python? Message-ID: Just wondering if there where any further thoughts on all this thread. http://thread.gmane.org/gmane.comp.python.c++/9664/focus=9703 I'm sure a few of us at least would like some insight into this. Thanks, -Ryan From amohr at pixar.com Thu May 18 01:35:47 2006 From: amohr at pixar.com (Alex Mohr) Date: Wed, 17 May 2006 16:35:47 -0700 Subject: [C++-sig] Ping: Howto expose exception classes using boost.python? In-Reply-To: References: Message-ID: <446BB353.9030806@pixar.com> The way I solved it was to actually implement an exception class in python (that derived from RuntimeError) and then call into my wrapped module, passing that class object. I store the class object in my C++ code, and then when I want to make an exception, I just invoke the class object's operator(), set the python exception state to that class/instance, and throw_error_already_set(). It would be lovely if boost python let you create extensions classes that derived from python classes, but I'm not sure what this would entail. Alex Ryan Gallagher wrote: > Just wondering if there where any further thoughts on all this thread. > > http://thread.gmane.org/gmane.comp.python.c++/9664/focus=9703 > > I'm sure a few of us at least would like some insight into this. > > Thanks, > > -Ryan > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From ryan.gallagher at gmail.com Thu May 18 02:34:11 2006 From: ryan.gallagher at gmail.com (Ryan Gallagher) Date: Thu, 18 May 2006 00:34:11 +0000 (UTC) Subject: [C++-sig] =?utf-8?q?Ping=3A_Howto_expose_exception_classes_using?= =?utf-8?q?=09boost=2Epython=3F?= References: <446BB353.9030806@pixar.com> Message-ID: Alex Mohr pixar.com> writes: > The way I solved it was to actually implement an exception class in > python (that derived from RuntimeError) and then call into my wrapped > module, passing that class object. Hi Alex, Yeah, I think that I mentioned in an earlier post that this was the way I solved it too. It works, just not quite as simple and pretty, and requires someone to learn a bit of Python/C API. Perhaps this is a good solution for someone to put on the boost wiki. > [snip] > It would be lovely if boost python let you create extensions classes > that derived from python classes, but I'm not sure what this would entail. I agree but am also not sure of what it would entail. I had been thinking the same thing when I first started looking into this. For exceptions, though, it appears that using PyErr_NewException is the preferred method by the Python/C API. Although, I would think that it should still be possible to set up a new exception class without using this but deriving from an Exception decendent and setting up the dictionary properly. Thanks for the reply, it sounds like we've gone down similar tracks with all this. That's encouraging. Cheers, -Ryan From ryan.gallagher at gmail.com Thu May 18 02:40:49 2006 From: ryan.gallagher at gmail.com (Ryan Gallagher) Date: Thu, 18 May 2006 00:40:49 +0000 (UTC) Subject: [C++-sig] =?utf-8?q?Ping=3A_Howto_expose_exception_classes_using?= =?utf-8?q?=09boost=2Epython=3F?= References: <446BB353.9030806@pixar.com> Message-ID: Alex Mohr pixar.com> writes: [snip] > I store the class object in my C++ code, and then when I want to make an > exception, I just invoke the class object's operator(), set the python > exception state to that class/instance, and throw_error_already_set(). [snip] I should actually read what I cut... This is a slightly different solution from what I did. Do you want to post a brief example? Interesting, -Ryan From Naceur.Meskini at sophia.inria.fr Thu May 18 10:03:23 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Thu, 18 May 2006 10:03:23 +0200 Subject: [C++-sig] exposing a private member function? In-Reply-To: <446B3F18.7080505@sympatico.ca> References: <446B3C0D.2060501@sophia.inria.fr> <446B3F18.7080505@sympatico.ca> Message-ID: <446C2A4B.6050202@sophia.inria.fr> Stefan Seefeld wrote: >Naceur Meskini wrote: > > >>Hi everybody, >> >>the situation is : >>I have two classes, A and B defined like that: >>class A >>{ >> public: >> insert(); >> ...... >>} >>class B: public A >>{ >> pivate: >> insert(); >> ...... >>} >>and I want to expose both to python, is it possible to tell to boost >>that the function insert of B will be private in python. >> >> > >First of all, python doesn't have any notion of 'private'. The closest you >can get is prefixing the name under which you register it by '_' or even '__'. > >Second, you can't expose a private method, since you'd need to dereference >it ('&B::insert'), which the private access-spec prohibits. > >Third, I'm not sure what you mean by 'expose both'. They are simply >two distinct methods of two different classes. >To have them both available in the same class, they need to have different >signatures, and you have to make sure that the second doesn't hide the first, >for example by means of a 'using A::insert' declaration within B. > > > The probleme is that when I expose A and B to python, the function A::insert is exposed because it's public and B::insert is not but when we are in the python side the user could use this code: a = A() a.insert(..) # that normal b = B() b.insert() # <------------ I don't want to allow that to users. Regards. Naceur. From roman.yakovenko at gmail.com Thu May 18 11:04:49 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 18 May 2006 12:04:49 +0300 Subject: [C++-sig] exposing a private member function? In-Reply-To: <446C2A4B.6050202@sophia.inria.fr> References: <446B3C0D.2060501@sophia.inria.fr> <446B3F18.7080505@sympatico.ca> <446C2A4B.6050202@sophia.inria.fr> Message-ID: <7465b6170605180204t4fa1740dvf294b9e6a30204fa@mail.gmail.com> On 5/18/06, Naceur Meskini wrote: > The probleme is that when I expose A and B to python, > the function A::insert is exposed because it's public and B::insert is not > but when we are in the python side the user could use this code: > a = A() > a.insert(..) # that normal > b = B() > b.insert() # <------------ I don't want to allow that to users. Python code: import your_module your_module.B.insert = \ lambda self: raise RuntimeError( "This is a private function! Don't call it." ) This should do the trick. The same thing could be done in C++. The main idea is to export function with the name "insert" but with implementation that throws/raises an exception > Regards. > Naceur. > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From Naceur.Meskini at sophia.inria.fr Thu May 18 12:05:49 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Thu, 18 May 2006 12:05:49 +0200 Subject: [C++-sig] exposing a private member function? In-Reply-To: <7465b6170605180204t4fa1740dvf294b9e6a30204fa@mail.gmail.com> References: <446B3C0D.2060501@sophia.inria.fr> <446B3F18.7080505@sympatico.ca> <446C2A4B.6050202@sophia.inria.fr> <7465b6170605180204t4fa1740dvf294b9e6a30204fa@mail.gmail.com> Message-ID: <446C46FD.6040401@sophia.inria.fr> Roman Yakovenko wrote: >On 5/18/06, Naceur Meskini wrote: > > >>The probleme is that when I expose A and B to python, >>the function A::insert is exposed because it's public and B::insert is not >>but when we are in the python side the user could use this code: >>a = A() >>a.insert(..) # that normal >>b = B() >>b.insert() # <------------ I don't want to allow that to users. >> >> > >Python code: > >import your_module >your_module.B.insert = \ > lambda self: raise RuntimeError( "This is a private function! >Don't call it." ) > >This should do the trick. The same thing could be done in C++. The >main idea is to export >function with the name "insert" but with implementation that >throws/raises an exception > > Ok, Thank you so much Roman, this will do the affair. > > >>Regards. >>Naceur. >> >> >> > > > > From dave at boost-consulting.com Thu May 18 13:34:53 2006 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 18 May 2006 07:34:53 -0400 Subject: [C++-sig] Ping: Howto expose exception classes using boost.python? References: <446BB353.9030806@pixar.com> Message-ID: Alex Mohr writes: > The way I solved it was to actually implement an exception class in > python (that derived from RuntimeError) and then call into my wrapped > module, passing that class object. > > I store the class object in my C++ code, and then when I want to make an > exception, I just invoke the class object's operator(), set the python > exception state to that class/instance, and throw_error_already_set(). > > It would be lovely if boost python let you create extensions classes > that derived from python classes, but I'm not sure what this would entail. It's been on the TODO list forever, but other priorities have kept us from addressing it. -- Dave Abrahams Boost Consulting www.boost-consulting.com From Naceur.Meskini at sophia.inria.fr Thu May 18 14:40:13 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Thu, 18 May 2006 14:40:13 +0200 Subject: [C++-sig] adding a doc_string to the overloaded functions In-Reply-To: References: <446BB353.9030806@pixar.com> Message-ID: <446C6B2D.8090802@sophia.inria.fr> Perhaps Someone of you had already encountered this probleme, How can I add a doc_string to the overloaded functions when we expose them, example I have this function: const char* nearest_vertex_doc = "the doc of my function" .def("nearest_vertex", &Triangulation_3::nearest_vertex, nearest_vertex_overloads_1_2()) Regards ------------------------------------ Naceur MESKINI. INRIA From rwgk at yahoo.com Thu May 18 18:18:45 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 18 May 2006 09:18:45 -0700 (PDT) Subject: [C++-sig] adding a doc_string to the overloaded functions In-Reply-To: <446C6B2D.8090802@sophia.inria.fr> Message-ID: <20060518161845.27298.qmail@web31511.mail.mud.yahoo.com> --- Naceur Meskini wrote: > Perhaps Someone of you had already encountered this probleme, > How can I add a doc_string to the overloaded functions when we expose > them, example I have this function: > > const char* nearest_vertex_doc = "the doc of my function" > > .def("nearest_vertex", &Triangulation_3::nearest_vertex, > nearest_vertex_overloads_1_2()) This should work: .def("nearest_vertex", &Triangulation_3::nearest_vertex, nearest_vertex_overloads_1_2(nearest_vertex_doc)) I think the docstring only shows up for one overload. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From nonexistent.ftp at gmail.com Thu May 18 21:12:35 2006 From: nonexistent.ftp at gmail.com (Garrick Chin) Date: Thu, 18 May 2006 15:12:35 -0400 Subject: [C++-sig] Polymorphism and Dangling Reference exception Message-ID: Hello all, I am trying to run a basic polymorphism test for boost::python using the following simple code: polymorphism_test.cpp: struct Shape { virtual ~Shape() {} virtual std::string draw(const std::string& param) = 0; }; struct ShapeWrap : Shape, wrapper { std::string draw(const std::string& param) { return this->get_override("draw")(param); } }; std::string printShape(Shape* shape) { return shape->draw("blah"); } BOOST_PYTHON_MODULE(test) { class_("Shape") .def("draw", pure_virtual(&Shape::draw)) ; def("printShape", &printShape); } polymorphism_test.py: import test class Circle(test.Shape): def draw(self, param): return "circle: " + param print test.printShape(Circle()) When the Python interpeter hits the "print test.printShape(Circle())" line, it throws the following exception: ReferenceError: Attempt to return dangling reference to object of type: class std::basic_string,class std::allocator > I do not understand why this would be thrown. I am not returning any references or pointers, and I basically copied this code from the documentation. What would be causing this exception? Thank you for your time. From roman.yakovenko at gmail.com Thu May 18 21:23:13 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 18 May 2006 22:23:13 +0300 Subject: [C++-sig] Polymorphism and Dangling Reference exception In-Reply-To: References: Message-ID: <7465b6170605181223q49a539daq947f8fdbf433cb16@mail.gmail.com> On 5/18/06, Garrick Chin wrote: > > class Circle(test.Shape): You should call the __init__ of the test.Shape def __init__( self ): test.Shape.__init__( self ) > def draw(self, param): > return "circle: " + param > > What would be causing this exception? Thank you for your time. You can try to use pyplusplus, it will save you a lot of time. It has nice GUI ( http://language-binding.net/pyplusplus/tutorials/tutorials.html ) so the learning curve should be short. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From nonexistent.ftp at gmail.com Thu May 18 21:54:53 2006 From: nonexistent.ftp at gmail.com (Garrick Chin) Date: Thu, 18 May 2006 15:54:53 -0400 Subject: [C++-sig] Polymorphism and Dangling Reference exception In-Reply-To: <7465b6170605181223q49a539daq947f8fdbf433cb16@mail.gmail.com> References: <7465b6170605181223q49a539daq947f8fdbf433cb16@mail.gmail.com> Message-ID: On 5/18/06, Roman Yakovenko wrote: > On 5/18/06, Garrick Chin wrote: > > > > class Circle(test.Shape): > > You should call the __init__ of the test.Shape > > def __init__( self ): > test.Shape.__init__( self ) > > > def draw(self, param): > > return "circle: " + param > > > > What would be causing this exception? Thank you for your time. > After adding the __init__() explicitly as you have shown I am still receiving the exact same error. :( > You can try to use pyplusplus, it will save you a lot of time. It has nice GUI > ( http://language-binding.net/pyplusplus/tutorials/tutorials.html ) > so the learning curve should be short. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > Thanks for the link, but I prefer wrapping with boost::python manually (although I'm not sure why). From roman.yakovenko at gmail.com Thu May 18 22:09:35 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 18 May 2006 23:09:35 +0300 Subject: [C++-sig] Polymorphism and Dangling Reference exception In-Reply-To: References: <7465b6170605181223q49a539daq947f8fdbf433cb16@mail.gmail.com> Message-ID: <7465b6170605181309h5bf3947dj7f290d44a3c46905@mail.gmail.com> On 5/18/06, Garrick Chin wrote: > After adding the __init__() explicitly as you have shown I am still > receiving the exact same error. :( It seems, that I can not help you. My guess is that there is something wrong with the build of your dll, but I could be wrong > Thanks for the link, but I prefer wrapping with boost::python manually > (although I'm not sure why). Because it is more fun? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From abierbaum at gmail.com Thu May 18 23:26:32 2006 From: abierbaum at gmail.com (Allen Bierbaum) Date: Thu, 18 May 2006 16:26:32 -0500 Subject: [C++-sig] Strange boost python error message (and solution) Message-ID: I just ran into a very strange error message in boost python that took me all afternoon to track down. I thought I would post the error and the solution here to: a) help other people out if they run into the same problem b) see if anyone can tell me what is really going on behind the scenes and if there is a way for boost python to detect it I was getting an assertion in boost::python::converter::registery::insert python: boost/libs/python/build/../src/converter/registry.cpp:162: void boost::python::converter::registry::insert(PyObject* (*)(const void*), boost::python::type_info): Assertion `slot == 0' failed. I tracked it down to having two calls to boost::python::register_ptr_to_python< boost::shared_ptr< MyClass > > . As long as there is only one call like this in the module for a single class things are fine. The second call causes a problem. So can anyone that knows the details of boost.python internals explain what is happening here? My guess (and it is only a guess) is that the registration of a to_python conversion function is detecting that it has already been set and asserting. If this is true, could the assertion be changed to something a little more descriptive like: assert((slot == 0) && "Attempted to register a to_python conversion function when one is already registered"); Thanks, Allen From nonexistent.ftp at gmail.com Fri May 19 00:15:09 2006 From: nonexistent.ftp at gmail.com (Garrick Chin) Date: Thu, 18 May 2006 18:15:09 -0400 Subject: [C++-sig] held_ptr and polymorphism Message-ID: I compiled the \python\test\polymorphism2.cpp with and without HELD_BY_AUTO_PTR defined to toggle holding the C++ defined Python objects with and without std::auto_ptr into two separate modules: polymorphism2_ext polymorphism2_auto_ptr_ext I ran the following test: class ADerived(A): def f(self): return "ADerived::f()" call_f(ADerived()) with two different imports: "from polymoprhism2_ext import" and "from polymoprhism2_auto_ptr_ext import" With the non-auto_ptr module, call_f() correctly prints "ADerived::f()". _With_ the auto_ptr module, call_f() incorrectly prints "A::f()". Is this a bug? How does one store particular C++ defined Python objects in a smart pointer without losing polymorphic behavior? From mwyatt at wi.rr.com Fri May 19 04:44:04 2006 From: mwyatt at wi.rr.com (Mike Wyatt) Date: Thu, 18 May 2006 21:44:04 -0500 Subject: [C++-sig] Static functions in Boost.Python Message-ID: <446D30F4.7010503@wi.rr.com> How can I define my C++ class' static functions in Boost.Python? I googled the subject quite a bit, and failed to find anything useful, except for this little mailing between chuzo okada and Dave: http://mail.python.org/pipermail/c++-sig/2002-July/001635.html My guess is that this is not supported, since Python has no concept of static methods (right?). If that is the case, should I simply declare "global" functions that use my Matrix class, and bind them in the BOOST_PYTHON_MODULE(matrix) block? Here is an excerpt of my Matrix class and Boost.Python mapping: class Matrix { public: /* other member functions */ static Matrix* Translation(float x, float y, float z); private: /* private variables */ } BOOST_PYTHON_MODULE(matrix) { class_("Matrix") /* other*/ .def("Translation", &Matrix::Translation) ; } Thanks, Mike -------------- next part -------------- An HTML attachment was scrubbed... URL: From mwyatt at wi.rr.com Fri May 19 05:36:50 2006 From: mwyatt at wi.rr.com (Mike Wyatt) Date: Thu, 18 May 2006 22:36:50 -0500 Subject: [C++-sig] Static functions in Boost.Python In-Reply-To: <446D30F4.7010503@wi.rr.com> References: <446D30F4.7010503@wi.rr.com> Message-ID: <446D3D52.104@wi.rr.com> Mike Wyatt wrote: > How can I define my C++ class' static functions in Boost.Python? I > googled the subject quite a bit, and failed to find anything useful, > except for this little mailing between chuzo okada and Dave: > > http://mail.python.org/pipermail/c++-sig/2002-July/001635.html > > My guess is that this is not supported, since Python has no concept of > static methods (right?). If that is the case, should I simply declare > "global" functions that use my Matrix class, and bind them in the > BOOST_PYTHON_MODULE(matrix) block? > > Here is an excerpt of my Matrix class and Boost.Python mapping: > > class Matrix > { > public: > /* other member functions */ > static Matrix* Translation(float x, float y, float z); > private: > /* private variables */ > } > > BOOST_PYTHON_MODULE(matrix) > { > class_("Matrix") > /* other*/ > .def("Translation", &Matrix::Translation) > ; > } > > Thanks, > > Mike > >------------------------------------------------------------------------ > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig > > >------------------------------------------------------------------------ > >No virus found in this incoming message. >Checked by AVG Free Edition. >Version: 7.1.392 / Virus Database: 268.6.0/342 - Release Date: 5/17/2006 > > I figured it out, thanks to pyste: BOOST_PYTHON_MODULE(matrix) { class_< Matrix >("Matrix") /* other */ .def("Translation", &Matrix::Translation, return_value_policy() ) .staticmethod("Translation") ; } -------------- next part -------------- An HTML attachment was scrubbed... URL: From Naceur.Meskini at sophia.inria.fr Fri May 19 09:48:10 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Fri, 19 May 2006 09:48:10 +0200 Subject: [C++-sig] adding a doc_string to the overloaded functions In-Reply-To: <20060518161845.27298.qmail@web31511.mail.mud.yahoo.com> References: <20060518161845.27298.qmail@web31511.mail.mud.yahoo.com> Message-ID: <446D783A.2080606@sophia.inria.fr> Ralf W. Grosse-Kunstleve wrote: >--- Naceur Meskini wrote: > > > >>Perhaps Someone of you had already encountered this probleme, >>How can I add a doc_string to the overloaded functions when we expose >>them, example I have this function: >> >>const char* nearest_vertex_doc = "the doc of my function" >> >>.def("nearest_vertex", &Triangulation_3::nearest_vertex, >>nearest_vertex_overloads_1_2()) >> >> > >This should work: > >.def("nearest_vertex", &Triangulation_3::nearest_vertex, >nearest_vertex_overloads_1_2(nearest_vertex_doc)) > >I think the docstring only shows up for one overload. > > Thank you Ralf it works very well. ------------------------ Naceur INRIA Sophia Antipolis From duranlef at iro.umontreal.ca Fri May 19 20:43:10 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Fri, 19 May 2006 14:43:10 -0400 (EDT) Subject: [C++-sig] Strange boost python error message (and solution) In-Reply-To: References: Message-ID: On Thu, 18 May 2006, Allen Bierbaum wrote: > I just ran into a very strange error message in boost python that took > me all afternoon to track down. I thought I would post the error and > the solution here to: > > a) help other people out if they run into the same problem > b) see if anyone can tell me what is really going on behind the > scenes and if there is a way for boost python to detect it > > I was getting an assertion in boost::python::converter::registery::insert > > python: boost/libs/python/build/../src/converter/registry.cpp:162: > void boost::python::converter::registry::insert(PyObject* (*)(const > void*), boost::python::type_info): Assertion `slot == 0' failed. > > I tracked it down to having two calls to > boost::python::register_ptr_to_python< boost::shared_ptr< MyClass > > > . As long as there is only one call like this in the module for a > single class things are fine. The second call causes a problem. > > So can anyone that knows the details of boost.python internals explain > what is happening here? > > My guess (and it is only a guess) is that the registration of a > to_python conversion function is detecting that it has already been > set and asserting. As far as I can tell from my understanding of the source code, this is right. > If this is true, could the assertion be changed to > something a little more descriptive like: > > assert((slot == 0) && "Attempted to register a to_python conversion > function when one is already registered"); Sounds good. But also, would it be possible to detect if the same to_python converter is get registered, and in such a case simply do nothing and thus report no error? -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "Il n'existe ni caprices du sort, ni bizarreries, ni accidents. Il n'y a que des choses que les humains ne comprennent pas. [...] Les humains ne peuvent exister si tout ce qui est d?plaisant est ?cart? au lieu d'?tre compris." - Cygne Royal, dans _Message des hommes vrais au monde mutant_ (de Marlo Morgan) From ns at fluent.com Sat May 20 00:45:51 2006 From: ns at fluent.com (Nigel Stewart) Date: Fri, 19 May 2006 17:45:51 -0500 Subject: [C++-sig] std::vector compatible wrapper for PyArrayObject? Message-ID: <446E4A9F.3060203@fluent.com> I posted the following question over on the boost lists, and David Abrahams suggested I bring it here: >> > We're looking to share some heavy-weight numerical data in >> > a mixed language C++/Python environment. >> > >> > boost::python::numeric::array provides a C++ binding >> > for the Python numeric array. However, we'd prefer to >> > have an STL compatible (std::vector compatible) interface to >> > the data, rather than python-ising our C++. >> > >> > The underlying runtime issue is to store one copy of the >> > contiguous 1D data in a way that both C++ and Python can >> > read and write, that will follow the Python memory >> > management scheme. >> > >> > Has anyone come across a std::vector compatible wrapper >> > for PyArrayObject? Any thoughts? Regards, Nigel Stewart From rwgk at yahoo.com Sat May 20 08:24:31 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 19 May 2006 23:24:31 -0700 (PDT) Subject: [C++-sig] Strange boost python error message (and solution) In-Reply-To: Message-ID: <20060520062431.48849.qmail@web31505.mail.mud.yahoo.com> --- Fran?ois Duranleau wrote: > > assert((slot == 0) && "Attempted to register a to_python conversion > > function when one is already registered"); > > Sounds good. But also, would it be possible to detect if the same > to_python converter is get registered, and in such a case simply do > nothing and thus report no error? If you compile with -DNDEBUG that's almost what happens. The assert is disabled by the -DNDEBUG and a Python warning is generated via PyErr_Warn(). I believe the warning is essential. For example, if you use two third-party packages and each has its own, potentially incompatible std::vector wrapper, the warning will make the conflict obvious. Without the warning it will be very had to track down the resulting problems. Since we have the warning, I think the assert is more confusing than helpful. David, what do you think about removing it altogether? __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From mwyatt at wi.rr.com Sat May 20 17:48:49 2006 From: mwyatt at wi.rr.com (Mike Wyatt) Date: Sat, 20 May 2006 10:48:49 -0500 Subject: [C++-sig] C++ float[4][4] in Python Message-ID: <446F3A61.3070800@wi.rr.com> I'm almost finished with my C++ Matrix class that I'm using as an extension module in Python (using Boost.Python). I store the matrix' values in a float[4][4] array, which I need to make available to my PyOpenGL calls (glLoadMatrix and glMultMatrix, specifically): public class Matrix { public: /* methods */ private: float m[4][4]; // 4x4 matrix array } BOOST_PYTHON_MODULE(matrix) { class_< Matrix >("Matrix") // other defs .def_readonly("m", &Matrix::m) ; } My problem is that attempting to use my public array results in the following error: TypeError: No to_python (by-value) converter found for C++ type: float [4][4] I couldn't find a way around that error, so I modified my C++ class to return a tuple using Boost.Python's "make_tuple" function: pyTuple = make_tuple( make_tuple(m[0][0], m[0][1], m[0][2], m[0][3]), make_tuple(m[1][0], m[1][1], m[1][2], m[1][3]), make_tuple(m[2][0], m[2][1], m[2][2], m[2][3]), make_tuple(m[3][0], m[3][1], m[3][2], m[3][3]) ); This works fine, but I think that I can improve performance by not allocating five tuples everytime the matrix changes. *I see two solutions to my problem: * 1) Find a way for Python to understand a float[4][4]. 2) Instead of allocating five tuples everytime the matrix changes, can I create my tuples in the class constructor, then simply set the values when necessary? The following code doesn't work, but should illustrate what I want to do: tuple Matrix::ToTuple() { pyTuple[0][0] = m[0][0]; pyTuple[0][1] = m[0][1]; pyTuple[0][2] = m[0][2]; pyTuple[0][3] = m[0][3]; pyTuple[1][0] = m[1][0]; pyTuple[1][1] = m[1][1]; pyTuple[1][2] = m[1][2]; pyTuple[1][3] = m[1][3]; pyTuple[2][0] = m[2][0]; pyTuple[2][1] = m[2][1]; pyTuple[2][2] = m[2][2]; pyTuple[2][3] = m[2][3]; pyTuple[3][0] = m[3][0]; pyTuple[3][1] = m[3][1]; pyTuple[3][2] = m[3][2]; pyTuple[3][3] = m[3][3]; return pyTuple; } The above code compiles fine, but throws the following error when I run the ToTuple() method in Python: TypeError: object does not support item assignment Any thoughts? -------------- next part -------------- An HTML attachment was scrubbed... URL: From duranlef at iro.umontreal.ca Sat May 20 19:42:45 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Sat, 20 May 2006 13:42:45 -0400 (EDT) Subject: [C++-sig] Strange boost python error message (and solution) In-Reply-To: <20060520062431.48849.qmail@web31505.mail.mud.yahoo.com> References: <20060520062431.48849.qmail@web31505.mail.mud.yahoo.com> Message-ID: On Fri, 19 May 2006, Ralf W. Grosse-Kunstleve wrote: > --- Fran?ois Duranleau wrote: >>> assert((slot == 0) && "Attempted to register a to_python conversion >>> function when one is already registered"); >> >> Sounds good. But also, would it be possible to detect if the same >> to_python converter is geting registered, and in such a case simply do >> nothing and thus report no error? > > If you compile with -DNDEBUG that's almost what happens. The assert is disabled > by the -DNDEBUG and a Python warning is generated via PyErr_Warn(). I believe > the warning is essential. For example, if you use two third-party packages and > each has its own, potentially incompatible std::vector wrapper, the warning > will make the conflict obvious. Without the warning it will be very had to > track down the resulting problems. Good, but what I actually meant is this: if I'm not mistaken, to_python_function_t is a function pointer type. Thus, wouldn't it be possible to do the following (highlighted with //****...): //from libs/python/src/converter/registry.cpp void insert(to_python_function_t f, type_info source_t) { # ifdef BOOST_PYTHON_TRACE_REGISTRY std::cout << "inserting to_python " << source_t << "\n"; # endif to_python_function_t& slot = get(source_t)->m_to_python; // assert(slot == 0); // we have a problem otherwise //************************************************************* if (slot == f) // already registered with the same function, do // nothing? { return; } //************************************************************* if (slot != 0) { std::string msg = ( std::string("to-Python converter for ") + source_t.name() + " already registered; second conversion method ignored." ); if ( ::PyErr_Warn( NULL, const_cast(msg.c_str()) ) ) { throw_error_already_set(); } } slot = f; } -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "Do you want to use a machine, or do you want the machine to use you?" - Doohan, in _Cowboy Bebop_ From rwgk at yahoo.com Sun May 21 07:44:10 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 20 May 2006 22:44:10 -0700 (PDT) Subject: [C++-sig] Strange boost python error message (and solution) In-Reply-To: Message-ID: <20060521054410.55594.qmail@web31504.mail.mud.yahoo.com> --- Fran???ois Duranleau wrote: > if (slot == f) // already registered with the same function, do > // nothing? > { > return; > } Did you actually try this out? -- We would have to establish that the address comparison across shared library boundaries works reliably on all platforms. Why do you find it difficult to avoid the warning or assertion? My solution to the problem is to explicitly import the module with the desired converter when I need it. Python's import logic automatically avoids multiple execution of the init function, and therefore multiple registration. To me this seems a little safer/organized/obvious/maintainable than a "let's see what happens" approach. I believe simply removing the assert(slot != 0) is the best approach; this way the informative warning wll shows up under all circumstances. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From duranlef at iro.umontreal.ca Sun May 21 16:47:42 2006 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Sun, 21 May 2006 10:47:42 -0400 (EDT) Subject: [C++-sig] Strange boost python error message (and solution) In-Reply-To: <20060521054410.55594.qmail@web31504.mail.mud.yahoo.com> References: <20060521054410.55594.qmail@web31504.mail.mud.yahoo.com> Message-ID: On Sat, 20 May 2006, Ralf W. Grosse-Kunstleve wrote: > --- Fran???ois Duranleau wrote: >> if (slot == f) // already registered with the same function, do >> // nothing? >> { >> return; >> } > > Did you actually try this out? -- We would have to establish that the address > comparison across shared library boundaries works reliably on all platforms. No, I didn't, and I actually didn't think about the library issue. > Why do you find it difficult to avoid the warning or assertion? > > My solution to the problem is to explicitly import the module with the desired > converter when I need it. Python's import logic automatically avoids multiple > execution of the init function, and therefore multiple registration. To me this > seems a little safer/organized/obvious/maintainable than a "let's see what > happens" approach. > > I believe simply removing the assert(slot != 0) is the best approach; this way > the informative warning wll shows up under all circumstances. I agree. I was just wondering if we could simply remove the warning for one situation, but then again, I forgot about the library thing. So, I stand on your side. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "Voyager, c'est essayer de revenir avec quelques pr?jug?s en moins." - Jean-Daniel Lafond From hans_meine at gmx.net Mon May 22 11:15:13 2006 From: hans_meine at gmx.net (Hans Meine) Date: Mon, 22 May 2006 11:15:13 +0200 Subject: [C++-sig] C++ float[4][4] in Python In-Reply-To: <446F3A61.3070800@wi.rr.com> References: <446F3A61.3070800@wi.rr.com> Message-ID: <200605221115.13702.hans_meine@gmx.net> On Saturday 20 May 2006 17:48, Mike Wyatt wrote: > float[4][4] array, which I need to make available to my PyOpenGL calls > (glLoadMatrix and glMultMatrix, specifically): > > [snip] > > *I see two solutions to my problem: > * > 1) Find a way for Python to understand a float[4][4]. This will not work with PyOpenGL AFAICS. > 2) Instead of allocating five tuples everytime the matrix changes, can I > create my tuples in the class constructor, then simply set the values > when necessary? No, because Python tuples are immutable by definition. (Actually, there is a hackish way to do so IIRC, but that's not the way to go, and PyOpenGL would still have to unpack the tuples.) You will get best performance by exporting your own functions calling glMultMatrix with the data from your matrix directly. It's perfectly fine to mix PyOpenGL with your own OpenGL calls (since OpenGL maintains just some big state machines). You just have to link to the library and that's it. Ciao, / / .o. /--/ ..o / / ANS ooo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From yamokosk at ufl.edu Mon May 22 16:45:58 2006 From: yamokosk at ufl.edu (J.D. Yamokoski) Date: Mon, 22 May 2006 10:45:58 -0400 Subject: [C++-sig] help passing image data Message-ID: <4471CEA6.3090005@ufl.edu> I am writing a simple test application to teach myself the ins and outs of embedding Python in a C++ program. But I am currrently stuck trying to pass non-standard data across the C/Python interface. Plus I may be complicating matters by trying to do all this embedding in MFC, but thats what I know for GUI programming. Here are the details: Using boost.python, I have created a module of the CImg (http://cimg.sourceforge.net/) library - a very light module as it only supports a handful of functions. I know python extensions for image manipulation already exist but this was to practice with boost - plus my main app already uses CImg. My test app is a SDI MFC program. In the document, I have one member variable - a CImg object. Image data stored in this object is displayed in the main window of the app. Now for the python. The app has a popup window where I can type in text which is then passed to the interpreter. For instance (please excuse any blatant python errors - treat this as pseudo python code): # Import my CImg extension and the set/get function from the main app import CImg import MyAppInterface # Get the image from the app. Function should return a CImg object DocImg = MyAppInterface.GetCurrentImage() # Call some CImg function DocImg.blur() # Return the data to the app for displaying MyAppInterface.SetCurrentImage( DocImg ) To create the application interface functions, I have the following code in C: static PyObject* get_current_image(PyObject *self, PyObject *args) { if( !PyArg_ParseTuple(args, "") ) return NULL; CImg img = gDocument->getCurrentImage(); return Py_BuildValue("o", &img); }; static PyObject* set_current_image(PyObject *self, PyObject *args) { PyObject *obj = NULL; if( !PyArg_ParseTuple(args, "o", &obj) ) return NULL; CImg img( (CImg)*obj ); Py_DECREF(obj); obj = NULL; gDocument->setCurrentImage( img ); Py_INCREF(Py_None); return Py_None; }; static PyMethodDef ImageMethods[] = { {"GetCurrentImage", get_current_image, METH_VARARGS, "Get the current image in the workspace."}, {"SetCurrentImage", set_current_image, METH_VARARGS, "Set the current image in the workspace."}, {NULL, NULL, 0, NULL} }; I have not tried to compile the above code because I am sure its wrong on many levels. But I wanted to see if I was heading in the right direction with this. Or is there a much more efficient way of doing this? (gDocument is a global pointer to the app's document - I know, bad practice. I would like to avoid this, but I don't know how else to give C functions access to data in an MFC class). Thanks for reading all this if you have made it this far! J.D. Yamokoski From ndbecker2 at gmail.com Mon May 22 18:56:49 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Mon, 22 May 2006 12:56:49 -0400 Subject: [C++-sig] add_property with policy? Message-ID: I'd like to use add_property with a reference data member. In the following, "getA" will work fine. But, I'd like to make this work with attribute access syntax: python code: b = B() an_A = b.a Anyway to make this work? The add_property below won't compile: #include #include #include #include #include struct A {}; struct B { A& a; }; A& getA (B const& b) { return b.a; } using namespace boost::python; BOOST_PYTHON_MODULE (test1) { class_ ("B") .def ("getA", &getA, return_internal_reference<>()) << this is OK .add_property ("A", &getA) << this is NOT OK ; } /usr/local/src/boost.cvs/boost/python/detail/invoke.hpp:75: error: no match for call to '(const boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning) (A&)' From roman.yakovenko at gmail.com Mon May 22 20:07:43 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 22 May 2006 21:07:43 +0300 Subject: [C++-sig] add_property with policy? In-Reply-To: References: Message-ID: <7465b6170605221107p49b52204n42dd819a1f3c9f98@mail.gmail.com> On 5/22/06, Neal Becker wrote: > I'd like to use add_property with a reference data member. > > In the following, "getA" will work fine. But, I'd like to make this work > with attribute access syntax: > > python code: > b = B() > an_A = b.a > > Anyway to make this work? The add_property below won't compile: > > #include > #include > #include > #include > #include > > struct A {}; > > struct B { > A& a; > }; > > A& getA (B const& b) { > return b.a; > } > > using namespace boost::python; > > BOOST_PYTHON_MODULE (test1) { > class_ ("B") > .def ("getA", &getA, return_internal_reference<>()) << this is OK > .add_property ("A", &getA) << this is NOT OK > ; > } > > /usr/local/src/boost.cvs/boost/python/detail/invoke.hpp:75: error: no match > for call to '(const > boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning) > (A&)' You should use boost::python::make_function. class_("B") .add_property( "a", make_function( &::getA, return_internal_reference<> ) ); This should work. Consult make_function documentation: http://boost.org/libs/python/doc/v2/make_function.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Mon May 22 20:34:11 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 22 May 2006 21:34:11 +0300 Subject: [C++-sig] help passing image data In-Reply-To: <4471CEA6.3090005@ufl.edu> References: <4471CEA6.3090005@ufl.edu> Message-ID: <7465b6170605221134l91781aawa145fbd4c88c487f@mail.gmail.com> On 5/22/06, J.D. Yamokoski wrote: > I am writing a simple test application to teach myself the ins and outs > of embedding Python in a C++ program. But I am currrently stuck trying > to pass non-standard data across the C/Python interface. Plus I may be > complicating matters by trying to do all this embedding in MFC, but > thats what I know for GUI programming. Here are the details: > > Using boost.python, I have created a module of the CImg > (http://cimg.sourceforge.net/) library - a very light module as it only > supports a handful of functions. I know python extensions for image > manipulation already exist but this was to practice with boost - plus my > main app already uses CImg. May I suggest you EasyBMP? It is much better library to start with. I even created full Python bindings for this library: http://language-binding.net/pyplusplus/examples/easybmp/easybmp.html > My test app is a SDI MFC program. In the document, I have one member > variable - a CImg object. Image data stored in this object is displayed > in the main window of the app. > > Now for the python. The app has a popup window where I can type in text > which is then passed to the interpreter. For instance (please excuse any > blatant python errors - treat this as pseudo python code): > > # Import my CImg extension and the set/get function from the main app > import CImg > import MyAppInterface > > # Get the image from the app. Function should return a CImg object > DocImg = MyAppInterface.GetCurrentImage() > > # Call some CImg function > DocImg.blur() > > # Return the data to the app for displaying > MyAppInterface.SetCurrentImage( DocImg ) > > > To create the application interface functions, I have the following code > in C: > > static PyObject* > get_current_image(PyObject *self, PyObject *args) > { > if( !PyArg_ParseTuple(args, "") ) return NULL; > > CImg img = gDocument->getCurrentImage(); > > return Py_BuildValue("o", &img); > }; > > static PyObject* > set_current_image(PyObject *self, PyObject *args) > { > PyObject *obj = NULL; > if( !PyArg_ParseTuple(args, "o", &obj) ) return NULL; > > CImg img( (CImg)*obj ); > Py_DECREF(obj); obj = NULL; > > gDocument->setCurrentImage( img ); > > Py_INCREF(Py_None); > return Py_None; > }; > > static PyMethodDef ImageMethods[] = { > {"GetCurrentImage", get_current_image, METH_VARARGS, > "Get the current image in the workspace."}, > {"SetCurrentImage", set_current_image, METH_VARARGS, > "Set the current image in the workspace."}, > {NULL, NULL, 0, NULL} > }; > > I have not tried to compile the above code because I am sure its wrong > on many levels. But I wanted to see if I was heading in the right > direction with this. Or is there a much more efficient way of doing > this? Where do you use boost.python library? Did you read tutorials? http://www.boost.org/libs/python/doc/tutorial/doc/html/index.html Also, I think you can start from something that is simpler then CImg library: for example try to create bindings for simple struct or even int. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From Naceur.Meskini at sophia.inria.fr Tue May 23 11:43:33 2006 From: Naceur.Meskini at sophia.inria.fr (Naceur Meskini) Date: Tue, 23 May 2006 11:43:33 +0200 Subject: [C++-sig] adding the docstring to the .addproperty() function?! In-Reply-To: <4471CEA6.3090005@ufl.edu> References: <4471CEA6.3090005@ufl.edu> Message-ID: <4472D945.6000205@sophia.inria.fr> Hi everybody, Is it normal that when I add the docstring to the .addproperty() function , I get many errors of compilation? here is an example of my code: const char * seeds_doc = "seeds doc"; class_< Delaunay_mesher_2 >("Delaunay_mesher_2", init< const Delaunay_mesher_2& >()) .def("try_one_step_refine_mesh", &Delaunay_mesher_2::try_one_step_refine_mesh) .add_property("seeds",&py_seeds, seeds_doc) <--------------------- ; Thank you for your help. ------------------------- Naceur INRIA. From ndbecker2 at gmail.com Tue May 23 14:56:57 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Tue, 23 May 2006 08:56:57 -0400 Subject: [C++-sig] simulation using c++ components and Python Message-ID: I'm writing a little document describing some work I'm doing. It describes a design for rapid prototyping by assembling c++ components controlled by Python. Perhaps it might be interesting to you, here is a start: http://nbecker.dyndns.org:8080/design.pdf From yamokosk at ufl.edu Tue May 23 18:03:27 2006 From: yamokosk at ufl.edu (J.D. Yamokoski) Date: Tue, 23 May 2006 12:03:27 -0400 Subject: [C++-sig] help passing image data In-Reply-To: <7465b6170605221134l91781aawa145fbd4c88c487f@mail.gmail.com> References: <4471CEA6.3090005@ufl.edu> <7465b6170605221134l91781aawa145fbd4c88c487f@mail.gmail.com> Message-ID: <4473324F.4080004@ufl.edu> Roman Yakovenko wrote: > On 5/22/06, J.D. Yamokoski wrote: >> ... > > Where do you use boost.python library? Did you read tutorials? > http://www.boost.org/libs/python/doc/tutorial/doc/html/index.html > > Also, I think you can start from something that is simpler then CImg library: > for example try to create bindings for simple struct or even int. > I used boost.python solely for the creation of the CImg extension. I wasn't using its support for doing the embedding. I thought by creating the CImg extension I was giving Python the ability to understand a CImg object. Are there any examples of passing a struct? All the examples I have seen are just too simple - passing ints, chars, floats, etc. J.D. From roman.yakovenko at gmail.com Tue May 23 19:38:32 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 23 May 2006 20:38:32 +0300 Subject: [C++-sig] help passing image data In-Reply-To: <4473324F.4080004@ufl.edu> References: <4471CEA6.3090005@ufl.edu> <7465b6170605221134l91781aawa145fbd4c88c487f@mail.gmail.com> <4473324F.4080004@ufl.edu> Message-ID: <7465b6170605231038h7cad3278ha379e22a9ea4c32@mail.gmail.com> On 5/23/06, J.D. Yamokoski wrote: > Roman Yakovenko wrote: > > On 5/22/06, J.D. Yamokoski wrote: > >> ... > > > > Where do you use boost.python library? Did you read tutorials? > > http://www.boost.org/libs/python/doc/tutorial/doc/html/index.html > > > > Also, I think you can start from something that is simpler then CImg library: > > for example try to create bindings for simple struct or even int. > > > > I used boost.python solely for the creation of the CImg extension. I > wasn't using its support for doing the embedding. I thought by creating > the CImg extension I was giving Python the ability to understand a CImg > object. > > Are there any examples of passing a struct? All the examples I have seen > are just too simple - passing ints, chars, floats, etc. I did not used boost.python for embeding. You may take a look on boost::python::object. ptr member function will return pointer to PyObject. You should register your classes, then you can construct boost::python::object using it's constructor. After this you have access to PyObject. I could be wrong. > J.D. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From seefeld at sympatico.ca Tue May 23 22:25:43 2006 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 23 May 2006 16:25:43 -0400 Subject: [C++-sig] help passing image data In-Reply-To: <4471CEA6.3090005@ufl.edu> References: <4471CEA6.3090005@ufl.edu> Message-ID: <44736FC7.20705@sympatico.ca> J.D. Yamokoski wrote: > I am writing a simple test application to teach myself the ins and outs > of embedding Python in a C++ program. But I am currrently stuck trying > to pass non-standard data across the C/Python interface. Plus I may be > complicating matters by trying to do all this embedding in MFC, but > thats what I know for GUI programming. Here are the details: Have you looked at the libs/python/test/exec.cpp tests in the boost source package ? I think it demonstrates how to do what you want. Here is (roughly) what you need to do: * Create bindings for your C++ data types, i.e. using the class_<> machinery. * Inject the new types, as well as any global objects you want to access from within python into a python dictionary that will be the script's environment. * Execute your python script. > Using boost.python, I have created a module of the CImg > (http://cimg.sourceforge.net/) library - a very light module as it only > supports a handful of functions. I know python extensions for image > manipulation already exist but this was to practice with boost - plus my > main app already uses CImg. > > My test app is a SDI MFC program. In the document, I have one member > variable - a CImg object. Image data stored in this object is displayed > in the main window of the app. > > Now for the python. The app has a popup window where I can type in text > which is then passed to the interpreter. For instance (please excuse any > blatant python errors - treat this as pseudo python code): > > # Import my CImg extension and the set/get function from the main app > import CImg > import MyAppInterface > > # Get the image from the app. Function should return a CImg object > DocImg = MyAppInterface.GetCurrentImage() > > # Call some CImg function > DocImg.blur() > > # Return the data to the app for displaying > MyAppInterface.SetCurrentImage( DocImg ) FWIW, the GetCurrentImage() call above may return a handle to an existing image, instead of returning a copy. In that case you would modify it in-place, and thus there wouldn't be any need to call SetCurrentImage(). > > > To create the application interface functions, I have the following code > in C: > > static PyObject* > get_current_image(PyObject *self, PyObject *args) > { > if( !PyArg_ParseTuple(args, "") ) return NULL; > > CImg img = gDocument->getCurrentImage(); > > return Py_BuildValue("o", &img); > }; This isn't needed, if you use python::class_ > to export your Cimg<> type to python. Please have a look into the above test / demo code. It is very compact and should do all you need. HTH, Stefan From yamokosk at ufl.edu Wed May 24 00:18:37 2006 From: yamokosk at ufl.edu (J.D. Yamokoski) Date: Tue, 23 May 2006 18:18:37 -0400 Subject: [C++-sig] help passing image data In-Reply-To: <44736FC7.20705@sympatico.ca> References: <4471CEA6.3090005@ufl.edu> <44736FC7.20705@sympatico.ca> Message-ID: <44738A3D.5040004@ufl.edu> Alright, I thank everyone for their suggestions so far. Following earlier advice, I am trying a little easier embedding project - just trying to make a simple (not CImg) object available in a python environment. The problem is that the program crashes when started. First here is the code I have so far - much has been copied from various things I have found on the web (I can include a zip of the VS workspace if anyone is really interested): First the ultra basic class I am trying to share with python: -- Begin Values.h class Values { public: Values(void); ~Values(void); float GetA(); float GetB(); void SetA(float A); void SetB(float B); protected: float a; float b; }; -- End Values.h Then my wrapping of this class using boost, -- Begin ValuesModule.h #include using namespace boost::python; #include "Values.h" object value_class = class_< Values >("Values") .def( "get_a", &Values::GetA ) .def( "get_b", &Values::GetB ) .def( "set_a", &Values::SetA ) .def( "set_b", &Values::SetB ); extern object value_obj = value_class(); BOOST_PYTHON_MODULE(Values) { value_class; } -- End ValuesModule.h To keep this simple I won't get into the rest of the code, partly because the program is crashing when it creates the global value_obj. The call stack pointer stops at the creation of this object and I get an "Access violation reading..." some memory address. My thoughts so far were to create this global value_obj. Later right before a call to PyRun_String, I add this object to the global dictionary by, object main_module (( handle<>( borrowed( PyImport_AddModule("__main__") ) ) )); object main_namespace = main_module.attr("__dict__"); // Insert the app's global value_obj into the python dictionary if ( PyDict_SetItem( main_namespace.ptr() , PyString_FromString("valueobj") , value_obj.ptr() ) == -1 ) { throw python_exception( "Could not add value_obj to the dictionary!" ); } But I am stuck simply creating the object for right now. Any suggestions? From ngoodspeed at solidworks.com Wed May 24 00:29:45 2006 From: ngoodspeed at solidworks.com (Nat Goodspeed) Date: Tue, 23 May 2006 18:29:45 -0400 Subject: [C++-sig] help passing image data Message-ID: > -----Original Message----- > From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On > Behalf Of J.D. Yamokoski > Sent: Tuesday, May 23, 2006 6:19 PM > To: Development of Python/C++ integration > Subject: Re: [C++-sig] help passing image data > > object value_class = class_< Values >("Values") > .def( "get_a", &Values::GetA ) > .def( "get_b", &Values::GetB ) > .def( "set_a", &Values::SetA ) > .def( "set_b", &Values::SetB ); > > extern object value_obj = value_class(); > > BOOST_PYTHON_MODULE(Values) > { > value_class; > } [Nat] Try moving the class_() call inside your BOOST_PYTHON_MODULE body? > BOOST_PYTHON_MODULE(Values) > { > class_< Values >("Values") > .def( "get_a", &Values::GetA ) > .def( "get_b", &Values::GetB ) > .def( "set_a", &Values::SetA ) > .def( "set_b", &Values::SetB ); > } From rwgk at yahoo.com Wed May 24 06:48:05 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 23 May 2006 21:48:05 -0700 (PDT) Subject: [C++-sig] C++ float[4][4] in Python In-Reply-To: <200605221115.13702.hans_meine@gmx.net> Message-ID: <20060524044805.88685.qmail@web31502.mail.mud.yahoo.com> --- Hans Meine wrote: > On Saturday 20 May 2006 17:48, Mike Wyatt wrote: > > float[4][4] array, which I need to make available to my PyOpenGL calls > > (glLoadMatrix and glMultMatrix, specifically): > > > > [snip] > > > > *I see two solutions to my problem: > > * > > 1) Find a way for Python to understand a float[4][4]. > This will not work with PyOpenGL AFAICS. > > > 2) Instead of allocating five tuples everytime the matrix changes, can I > > create my tuples in the class constructor, then simply set the values > > when necessary? > No, because Python tuples are immutable by definition. (Actually, there is a > > hackish way to do so IIRC, but that's not the way to go, and PyOpenGL would > still have to unpack the tuples.) > > You will get best performance by exporting your own functions calling > glMultMatrix with the data from your matrix directly. It's perfectly fine to > > mix PyOpenGL with your own OpenGL calls (since OpenGL maintains just some big > > state machines). You just have to link to the library and that's it. FWIW: That's exactly what I did about a year ago: http://cci.lbl.gov/gltbx/ I didn't have much time to work on this, but the CVS is a bit more advanced including utilities to compile in Unicode BDF fonts. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From rwgk at yahoo.com Wed May 24 06:54:16 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 23 May 2006 21:54:16 -0700 (PDT) Subject: [C++-sig] adding the docstring to the .addproperty() function?! In-Reply-To: <4472D945.6000205@sophia.inria.fr> Message-ID: <20060524045416.64465.qmail@web31514.mail.mud.yahoo.com> --- Naceur Meskini wrote: > Hi everybody, > > Is it normal that when I add the docstring to the .addproperty() > function , I get many errors of compilation? > here is an example of my code: > const char * seeds_doc = "seeds doc"; > class_< Delaunay_mesher_2 >("Delaunay_mesher_2", init< const > Delaunay_mesher_2& >()) > .def("try_one_step_refine_mesh", > &Delaunay_mesher_2::try_one_step_refine_mesh) > > .add_property("seeds",&py_seeds, > seeds_doc) <--------------------- > ; Docstring support for add_property was added 2005/01/22 by Jonathan Brandmeyer. See boost/libs/python/test/properties.cpp in the CVS. Could it be that you are using a very old boost version? __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From roman.yakovenko at gmail.com Wed May 24 12:06:39 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 24 May 2006 13:06:39 +0300 Subject: [C++-sig] call policies help needed Message-ID: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> Hi. Please consider next case: class A{ ... }; struct B{ B( A& a ) : a( a ) {} A& a; }; In order to export class B, I have to create access function for member variable a. A& get_a( B& b ){ return b.a }; BOOST_PYTHON_MODULE(module){ class_< A > ...; class_< B >( "B", bp::init< A& >( )[with_custodian_and_ward<1,2>()] ) .add_property( "a", make_funtion( &get_a, ???????? ) ); } I don't know what call policies pyplusplus, code generator, should give for make_function by default. Why? Because there are different use case: 1. Python code: a = module.A() b = module.B( a ) In this case life time of "a" is already managed by boost.python, so the return value policy for make_function could be "return_existing_object". I think, that in this case it is safe to use it.( Am I wrong ? ) 2. Python code: a = module.get_the_a_object() # returns reference to existing object a, that was created # from C++, life time of this object is not managed # by boost.python b = module.B( a ) In this case it is unsafe to use "return_existing_object". The safer alternatives are: 1. to use "copy_[non]_const_reference", will not work for all classes, also this is not an expected behaviour: b.a.s = 2 will not take effect, because b.a will return copy of a 2. to use "return_internal_reference". Here I make small assumption, that developer has some guaranties: object "a" will not be destroyed, if there is at least one "b" object. Obviously this guarantee exists in C++ code, but C++ code does not have garbage collector. In Python, object "b", could leave longer then object "a". So I am not sure about this option too. 3. "return_existing_object" 4. I am sure, I missed something. Thoughts? Thanks for help. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From dave at boost-consulting.com Wed May 24 13:30:41 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 24 May 2006 07:30:41 -0400 Subject: [C++-sig] Strange boost python error message (and solution) References: <20060520062431.48849.qmail@web31505.mail.mud.yahoo.com> Message-ID: Fran?ois Duranleau writes: > Good, but what I actually meant is this: if I'm not mistaken, > to_python_function_t is a function pointer type. Thus, wouldn't it be > possible to do the following (highlighted with //****...): > > //from libs/python/src/converter/registry.cpp > > void insert(to_python_function_t f, type_info source_t) > { > # ifdef BOOST_PYTHON_TRACE_REGISTRY > std::cout << "inserting to_python " << source_t << "\n"; > # endif > to_python_function_t& slot = get(source_t)->m_to_python; > > // assert(slot == 0); // we have a problem otherwise > > //************************************************************* > if (slot == f) // already registered with the same function, do > // nothing? > { > return; > } > //************************************************************* > > if (slot != 0) > { > std::string msg = ( > std::string("to-Python converter for ") > + source_t.name() > + " already registered; second conversion method ignored." > ); > > if ( ::PyErr_Warn( NULL, const_cast(msg.c_str()) ) ) > { > throw_error_already_set(); > } > } > slot = f; > } That's a very nice solution, consistent with other parts of Boost.Python. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed May 24 13:38:14 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 24 May 2006 07:38:14 -0400 Subject: [C++-sig] held_ptr and polymorphism References: Message-ID: "Garrick Chin" writes: > I compiled the \python\test\polymorphism2.cpp with and without > HELD_BY_AUTO_PTR defined to toggle holding the C++ defined Python > objects with and without std::auto_ptr into two separate modules: > > polymorphism2_ext > polymorphism2_auto_ptr_ext > > I ran the following test: > > class ADerived(A): > def f(self): > return "ADerived::f()" > > call_f(ADerived()) > > with > > two different imports: "from polymoprhism2_ext import" and "from > polymoprhism2_auto_ptr_ext import" > > With the non-auto_ptr module, call_f() correctly prints > "ADerived::f()". _With_ the auto_ptr module, call_f() incorrectly > prints "A::f()". Is this a bug? How does one store particular C++ > defined Python objects in a smart pointer without losing polymorphic > behavior? What is your platform and compiler? http://engineering.meta-comm.com/boost-regression/1_33_1/developer/python_release.html shows clearly that both tests were passing on all the combinations we tested. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed May 24 13:52:29 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 24 May 2006 07:52:29 -0400 Subject: [C++-sig] call policies help needed References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> Message-ID: "Roman Yakovenko" writes: > Hi. Please consider next case: > > class A{ ... }; > > struct B{ > B( A& a ) > : a( a ) > {} > > A& a; > }; > > In order to export class B, I have to create access function for > member variable a. > > A& get_a( B& b ){ return b.a }; > > BOOST_PYTHON_MODULE(module){ > class_< A > ...; > class_< B >( "B", bp::init< A& >( )[with_custodian_and_ward<1,2>()] ) > .add_property( "a", make_funtion( &get_a, ???????? ) ); > } > > I don't know what call policies pyplusplus, code generator, should > give for make_function > by default. Why? Because there are different use case: > > 1. Python code: > a = module.A() > b = module.B( a ) > In this case life time of "a" is already managed by boost.python, > so the return value > policy for make_function could be "return_existing_object". I > think, that in this case > it is safe to use it.( Am I wrong ? ) It's safe until someone does >>> del a then b is dangling. > 2. Python code: > a = module.get_the_a_object() # returns reference to existing > object a, that was created > # from C++, life time > of this object is not managed > # by boost.python > b = module.B( a ) > In this case it is unsafe to use "return_existing_object". It's exactly as safe as in the previous case. > The safer alternatives are: > > 1. to use "copy_[non]_const_reference", That's safe from crashes. > will not work for all classes, also > this is not an expected behaviour: > b.a.s = 2 > will not take effect, because b.a will return copy of a Yes, that's the tradeoff. > 2. to use "return_internal_reference". Here I make small > assumption, that developer > has some guaranties: object "a" will not be destroyed, if > there is at least one "b" > object. No, it guarantees that the B Python object will not be destroyed as long as there is at least one A Python object that has been retrieved via >>> b.a > Obviously this guarantee exists in C++ code, but C++ code > does not have garbage collector. In Python, object "b", > could leave longer then object "a". So I am not sure about > this option too. > > 3. "return_existing_object" > > 4. I am sure, I missed something. In principle the C++ code has unsafety built into it, since a B object can always outlive an A object. There's no safe choice with expected behavior that you can derive merely by looking at C++ declarations; you need to analyze the semantics of the C++ code, which might lead you to discover that there's no way to get both safety and expected behavior for this interface. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed May 24 13:56:59 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 24 May 2006 07:56:59 -0400 Subject: [C++-sig] Polymorphism and Dangling Reference exception References: Message-ID: "Garrick Chin" writes: > ReferenceError: Attempt to return dangling reference to object of > type: class std::basic_string,class > std::allocator > > > I do not understand why this would be thrown. Me neither. What is your compiler and platform, please? -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed May 24 14:09:33 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 24 May 2006 08:09:33 -0400 Subject: [C++-sig] Polymorphism and Dangling Reference exception References: Message-ID: David Abrahams writes: > "Garrick Chin" writes: > >> ReferenceError: Attempt to return dangling reference to object of >> type: class std::basic_string,class >> std::allocator > >> >> I do not understand why this would be thrown. > > Me neither. What is your compiler and platform, please? FWIW, the enclosed works for me: -------------- next part -------------- A non-text attachment was scrubbed... Name: quack.py Type: text/x-python Size: 342 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: quack.cpp Type: text/x-cpp Size: 782 bytes Desc: not available URL: -------------- next part -------------- -- Dave Abrahams Boost Consulting www.boost-consulting.com From roman.yakovenko at gmail.com Wed May 24 14:24:08 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 24 May 2006 15:24:08 +0300 Subject: [C++-sig] call policies help needed In-Reply-To: References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> Message-ID: <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> On 5/24/06, David Abrahams wrote: > In principle the C++ code has unsafety built into it, since a B object > can always outlive an A object. There's no safe choice with expected > behavior that you can derive merely by looking at C++ declarations; > you need to analyze the semantics of the C++ code, which might lead > you to discover that there's no way to get both safety and expected > behavior for this interface. Thanks. I understood this. I think I will implement next behaviour: 1. If "a" could be return by value, then pyplusplus will expose member variable "a", using get/set functions Thus, I provide some form of safeness + developer will be less surprised. 2. In any other case, the user will be forced to set call policies. Comment will contain link to this thread :-). -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From dave at boost-consulting.com Wed May 24 15:20:46 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 24 May 2006 09:20:46 -0400 Subject: [C++-sig] call policies help needed References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> Message-ID: "Roman Yakovenko" writes: > On 5/24/06, David Abrahams wrote: >> In principle the C++ code has unsafety built into it, since a B object >> can always outlive an A object. There's no safe choice with expected >> behavior that you can derive merely by looking at C++ declarations; >> you need to analyze the semantics of the C++ code, which might lead >> you to discover that there's no way to get both safety and expected >> behavior for this interface. > > Thanks. I understood this. I think I will implement next behaviour: > > 1. If "a" could be return by value, You mean if it has a public copy ctor? > then pyplusplus will expose member variable "a", using get/set > functions Meaning what, precisely? >>> b.get_a() >>> b.set_a() ?? -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Wed May 24 18:12:55 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 24 May 2006 09:12:55 -0700 (PDT) Subject: [C++-sig] Strange boost python error message (and solution) In-Reply-To: Message-ID: <20060524161255.27592.qmail@web31509.mail.mud.yahoo.com> --- David Abrahams wrote: > > possible to do the following (highlighted with //****...): > > ... > > //************************************************************* > > > if (slot == f) // already registered with the same function, do > > > // nothing? > > > { > > > return; > > > } > > > //************************************************************* > ... > That's a very nice solution, consistent with other parts of Boost.Python. >From boost/python/converter/to_python_function_type.hpp: typedef PyObject* (*to_python_function_t)(void const*); I am still worried about the function pointer comparison. It seems unlikely to me that the double-registration originates from a single extension; that would be very easy to avoid. If the same to_python converter is defined in two different extensions, are we sure that the address comparison is meaningful? I am thinking the machine code for the function exists independently in each extension, i.e. has two different addresses. Does the dynamic loader eliminate the duplication on all platforms? Is the behavior the same with, e.g. RTLD_LOCAL and RTLD_GLOBAL? __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From roman.yakovenko at gmail.com Wed May 24 19:07:07 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 24 May 2006 20:07:07 +0300 Subject: [C++-sig] call policies help needed In-Reply-To: References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> Message-ID: <7465b6170605241007s1c2ff305rd595cb6493fbe660@mail.gmail.com> On 5/24/06, David Abrahams wrote: > "Roman Yakovenko" writes: > > > On 5/24/06, David Abrahams wrote: > >> In principle the C++ code has unsafety built into it, since a B object > >> can always outlive an A object. There's no safe choice with expected > >> behavior that you can derive merely by looking at C++ declarations; > >> you need to analyze the semantics of the C++ code, which might lead > >> you to discover that there's no way to get both safety and expected > >> behavior for this interface. > > > > Thanks. I understood this. I think I will implement next behaviour: > > > > 1. If "a" could be return by value, > > You mean if it has a public copy ctor? Yes, but this is not enough, class should not be abstract. Should have public destructor. > > then pyplusplus will expose member variable "a", using get/set > > functions > > Meaning what, precisely? > > >>> b.get_a() > >>> b.set_a() > Yes. > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From yamokosk at ufl.edu Wed May 24 21:03:21 2006 From: yamokosk at ufl.edu (J.D. Yamokoski) Date: Wed, 24 May 2006 15:03:21 -0400 Subject: [C++-sig] help passing image data In-Reply-To: References: Message-ID: <4474ADF9.3030005@ufl.edu> > > [Nat] Try moving the class_() call inside your BOOST_PYTHON_MODULE body? > > >>BOOST_PYTHON_MODULE(Values) >>{ >> class_< Values >("Values") >> .def( "get_a", &Values::GetA ) >> .def( "get_b", &Values::GetB ) >> .def( "set_a", &Values::SetA ) >> .def( "set_b", &Values::SetB ); >>} > Ok I have done that and gotten rid of creating a global boost::python object of type Values. I have also modified my code to copy what I found here: http://mail.python.org/pipermail/c++-sig/2002-December/002833.html However, now I am running into a runtime problem. Instead of posting all the code here, I have included the important files with the email. Essentially, I have a class which wraps much of the code that was posted in the above link email. And I have only made slight modifications to it to fit my needs. The code seems to crash at PyImport_ImportModule(): handle<> CPythonDLL::importModule(std::string module_name) { PyObject *module_ptr = PyImport_ImportModule(const_cast(module_name.c_str())); if( module_ptr == NULL) { python_exception exc = getExceptionDetail(); throw(exc); } return handle<>(module_ptr); } That is bothersome, but then I have a try block wrapped around the calling of importModule(): // Import the module, storing the pointer in a handle<> try { module = importModule(scriptName); } catch (...) { python_exception exc = getExceptionDetail(); throw(exc); } The exception is caught and getExceptionDetail() is called. But then within that function, the code throws another exception at PyErr_Occured(): python_exception CPythonDLL::getExceptionDetail() { std::string errmsg(""); int nIsInit = Py_IsInitialized(); if (!nIsInit) { errmsg = "Python not initialized!"; return python_exception( errmsg ); } // Extra paranoia... if (!PyErr_Occurred()) { errmsg = "Not a python error!"; return python_exception( errmsg ); } PyObject* exc_type; PyObject* exc_value; PyObject* exc_traceback; PyObject* pystring; PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); // Rest let out for brevity } I don't know if it helps explain anything, but in the directory that my "myscript.py" file is stored, a "myscript.pyc" file is created everytime I run the program. I assume this has something to do with PyImport_ImportModule(). -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ValuesModule.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: PythonDLL.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: PythonDLL.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: myscript.py URL: From ns at fluent.com Wed May 24 22:34:20 2006 From: ns at fluent.com (Nigel Stewart) Date: Wed, 24 May 2006 15:34:20 -0500 Subject: [C++-sig] std::vector compatible wrapper for PyArrayObject? In-Reply-To: <446E4A9F.3060203@fluent.com> References: <446E4A9F.3060203@fluent.com> Message-ID: <4474C34C.4010205@fluent.com> >>>> Has anyone come across a std::vector compatible wrapper >>>> for PyArrayObject? Any thoughts? Alright then, does it sound like a totally insane thing to do? Does it sound generally useful? Cheers, Nigel From roman.yakovenko at gmail.com Wed May 24 22:40:40 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 24 May 2006 23:40:40 +0300 Subject: [C++-sig] call policies help needed In-Reply-To: <7465b6170605241007s1c2ff305rd595cb6493fbe660@mail.gmail.com> References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> <7465b6170605241007s1c2ff305rd595cb6493fbe660@mail.gmail.com> Message-ID: <7465b6170605241340m12c320a5maac19f497a3f8ae@mail.gmail.com> Hi. I implemented solution to the problem within pyplusplus. Example: for next code struct A {}; struct B { B( A& a_ ): a( a_ ){} A& a; }; pyplusplus will generate next code: #include "boost/python.hpp" #include "1.h" namespace bp = boost::python; struct B_wrapper : B, bp::wrapper< B > { B_wrapper(B const & arg ) : B( arg ) , bp::wrapper< B >() {} B_wrapper(::A & a_ ) : B( a_ ) , bp::wrapper< B >() {} static ::A & get_a( B& inst ) { return inst.a; } static void set_a( B& inst, ::A & new_value ){ inst.a = new_value; } }; BOOST_PYTHON_MODULE(pyplusplus){ if( true ){ typedef bp::class_< B_wrapper > B_exposer_t; B_exposer_t B_exposer = B_exposer_t( "B", bp::init< A & >(( bp::arg("a_") )) ); bp::scope B_scope( B_exposer ); B_exposer.def( "get_a" , (::A & (*)( ::B & ))(&B_wrapper::get_a) , bp::return_value_policy< bp::copy_non_const_reference, bp::default_call_policies >() ); B_exposer.def( "set_a" , (void (*)( ::B &,::A & ))(&B_wrapper::set_a) , bp::default_call_policies() ); } bp::implicitly_convertible< A &, B >(); bp::class_< A >( "A" ); } User can change call policies for "get_a" and "set_a" functions. It is not very difficult to change pyplusplus, so it will expose variable "a" using "add_property" functionality, but before doing this I prefer to get feadbacks from users. Thanks -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From rwgk at yahoo.com Thu May 25 00:22:07 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 24 May 2006 15:22:07 -0700 (PDT) Subject: [C++-sig] help passing image data In-Reply-To: <4474ADF9.3030005@ufl.edu> Message-ID: <20060524222207.62217.qmail@web31502.mail.mud.yahoo.com> void CPythonDLL::finalize() { Py_Finalize(); } > CPythonDLL::~CPythonDLL(void) > { > int nIsInit = Py_IsInitialized(); > > if (nIsInit) Py_Finalize(); > } Boost.Python doesn't support Py_Finalize(). You have to comment this out. (I am not familiar with embedding and didn't look closely at your message, but this stood out to me as a real problem.) __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From ndbecker2 at gmail.com Thu May 25 03:50:07 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 24 May 2006 21:50:07 -0400 Subject: [C++-sig] call policies help needed References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> <7465b6170605241007s1c2ff305rd595cb6493fbe660@mail.gmail.com> <7465b6170605241340m12c320a5maac19f497a3f8ae@mail.gmail.com> Message-ID: Is there something wrong with this, which looks simpler to my (naive) eyes?: struct A {}; struct B { B (A& _a) : a (_a) {} A& a; }; static A& getA (B& b) { return b.a; } BOOST_PYTHON_MODULE(demod4) { class_ ("A"); class_ ("B", init() [with_custodian_and_ward<1,2>()]) .def ("getA", &::getA, return_internal_reference<>()) ; } From roman.yakovenko at gmail.com Thu May 25 05:40:22 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 25 May 2006 06:40:22 +0300 Subject: [C++-sig] call policies help needed In-Reply-To: References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> <7465b6170605241007s1c2ff305rd595cb6493fbe660@mail.gmail.com> <7465b6170605241340m12c320a5maac19f497a3f8ae@mail.gmail.com> Message-ID: <7465b6170605242040x46a5b2b8ta792757ae3d80e77@mail.gmail.com> On 5/25/06, Neal Becker wrote: > Is there something wrong with this, which looks simpler to my (naive) eyes?: > > struct A {}; > > struct B { > B (A& _a) : a (_a) {} > A& a; > }; > > static A& getA (B& b) { > return b.a; > } getA is defined under global scope. If you add another class struct C { C (A& _a) : a (_a) {} A& a; }; Then you will have to distinct between getA for B and C classes. Defining those functions within relevant class wrapper eliminates the problem. > BOOST_PYTHON_MODULE(demod4) > { > class_ ("A"); > class_ ("B", init() > [with_custodian_and_ward<1,2>()]) > .def ("getA", &::getA, return_internal_reference<>()) Member variable "a" is not really internal reference. Class "B" does not manage it's life time. http://boost.org/libs/python/doc/v2/return_internal_reference.html > ; > } > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From s_sourceforge at nedprod.com Thu May 25 14:05:14 2006 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 25 May 2006 13:05:14 +0100 Subject: [C++-sig] Strange boost python error message (and solution) In-Reply-To: <20060524161255.27592.qmail@web31509.mail.mud.yahoo.com> References: Message-ID: <4475AB8A.19203.5139E2@s_sourceforge.nedprod.com> On 24 May 2006 at 9:12, Ralf W. Grosse-Kunstleve wrote: > I am still worried about the function pointer comparison. It seems unlikely to > me that the double-registration originates from a single extension; that would > be very easy to avoid. If the same to_python converter is defined in two > different extensions, are we sure that the address comparison is meaningful? I > am thinking the machine code for the function exists independently in each > extension, i.e. has two different addresses. Does the dynamic loader eliminate > the duplication on all platforms? Is the behavior the same with, e.g. > RTLD_LOCAL and RTLD_GLOBAL? It's worse than that. If you resolve a symbol and store its address, when another shared object is loaded which also has that symbol then its address magically changes with RTLD_GLOBAL. With RTLD_LOCAL, the symbol depends on what code is asking for resolution. In one shared object you will get a different value than another. In this case you would have multiple copies of the BPL object in memory at once which probably breaks lots of other things anyway. If I were you, I would compare pointers as a quick case scenario. If different, you'll need to do a string comparison. This sucks, but anything else isn't correct. Cheers, Niall From ndbecker2 at gmail.com Thu May 25 15:03:12 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 25 May 2006 09:03:12 -0400 Subject: [C++-sig] call policies help needed References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> <7465b6170605241007s1c2ff305rd595cb6493fbe660@mail.gmail.com> <7465b6170605241340m12c320a5maac19f497a3f8ae@mail.gmail.com> <7465b6170605242040x46a5b2b8ta792757ae3d80e77@mail.gmail.com> Message-ID: Roman Yakovenko wrote: > On 5/25/06, Neal Becker wrote: >> Is there something wrong with this, which looks simpler to my (naive) >> eyes?: >> >> struct A {}; >> >> struct B { >> B (A& _a) : a (_a) {} >> A& a; >> }; >> >> static A& getA (B& b) { >> return b.a; >> } > [...] >> BOOST_PYTHON_MODULE(demod4) >> { >> class_ ("A"); >> class_ ("B", init() >> [with_custodian_and_ward<1,2>()]) >> .def ("getA", &::getA, return_internal_reference<>()) > > Member variable "a" is not really internal reference. Class "B" does not > manage it's life time. > I'm confused. I thought it worked like this: In python, create an a=A(). Then create a b=B(a). Using custodian_and_ward, 'a' will not be deleted as long as 'b' is alive. Then c=getA() using return_internal_reference will ensure that 'b' is not deleted as long as python holds 'c'. Is this not correct? From yamokosk at ufl.edu Thu May 25 17:08:56 2006 From: yamokosk at ufl.edu (J.D. Yamokoski) Date: Thu, 25 May 2006 11:08:56 -0400 (EDT) Subject: [C++-sig] help passing image data Message-ID: <474838057.262061148569736371.JavaMail.osg@osgjas04.cns.ufl.edu> Are there any other C/API calls that are not compatible with Boost? And what is the proper way to shut down the interpreter or reset it using Boost? I will comment this out and see if it has an effect.. I am not guessing it will since finalize was not being called when I ran into the problems I was having. On Wed May 24 18:22:07 EDT 2006, "Ralf W. Grosse-Kunstleve" wrote: > void CPythonDLL::finalize() > { > Py_Finalize(); > } > > CPythonDLL::~CPythonDLL(void) >> { >> int nIsInit = Py_IsInitialized(); >> >> if (nIsInit) Py_Finalize(); >> } > > Boost.Python doesn't support Py_Finalize(). You have to comment > this out. > (I am not familiar with embedding and didn't look closely at your > message, but > this stood out to me as a real problem.) > > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam protection around > http://mail.yahoo.com > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > From rwgk at yahoo.com Thu May 25 18:10:56 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 25 May 2006 09:10:56 -0700 (PDT) Subject: [C++-sig] help passing image data In-Reply-To: <474838057.262061148569736371.JavaMail.osg@osgjas04.cns.ufl.edu> Message-ID: <20060525161056.41410.qmail@web31503.mail.mud.yahoo.com> --- "J.D. Yamokoski" wrote: > Are there any other C/API calls that are not compatible with > Boost? I don't think so. > And what is the proper way to shut down the interpreter or reset > it using Boost? It is not supported. This is because the groups funding Boost.Python V2 development had no interest in embedding. Actually, how serious is this limitation in practice? If you simply start the interpreter when your main is called and then reuse it all the time, what is lost compared to shutting down and restarting the interpreter multiple times? __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From yamokosk at ufl.edu Thu May 25 19:16:54 2006 From: yamokosk at ufl.edu (J.D. Yamokoski) Date: Thu, 25 May 2006 13:16:54 -0400 (EDT) Subject: [C++-sig] help passing image data Message-ID: <1733391377.268081148577414567.JavaMail.osg@osgjas04.cns.ufl.edu> Understood. I guess using Py_Finalize was a lazy way for me to sort of reset the Python interpreter. I just wanted to make sure that variables created inside a script don't build in the global dictionary and maybe cause strange runtime errors over the course of running the program. I am sure I could just make sure to clean out anything new created in the dictionary or something like that. So then does Boost support multiple Python threads created in C? On Thu May 25 12:10:56 EDT 2006, "Ralf W. Grosse-Kunstleve" wrote: > --- "J.D. Yamokoski" wrote: >> Are there any other C/API calls that are not compatible with >> Boost? > > I don't think so. > >> And what is the proper way to shut down the interpreter or reset >> it using Boost? > > It is not supported. This is because the groups funding > Boost.Python V2 > development had no interest in embedding. > Actually, how serious is this limitation in practice? If you > simply start the > interpreter when your main is called and then reuse it all the > time, what is > lost compared to shutting down and restarting the interpreter > multiple times? > > > __________________________________________________ > Do You Yahoo!? > Tired of spam? Yahoo! Mail has the best spam protection around > http://mail.yahoo.com > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > From roman.yakovenko at gmail.com Thu May 25 19:24:28 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 25 May 2006 20:24:28 +0300 Subject: [C++-sig] call policies help needed In-Reply-To: References: <7465b6170605240306t79c7ac9dl3087ecf9526767@mail.gmail.com> <7465b6170605240524h70586c53v6da390ee0c360637@mail.gmail.com> <7465b6170605241007s1c2ff305rd595cb6493fbe660@mail.gmail.com> <7465b6170605241340m12c320a5maac19f497a3f8ae@mail.gmail.com> <7465b6170605242040x46a5b2b8ta792757ae3d80e77@mail.gmail.com> Message-ID: <7465b6170605251024x1efdaa99la95af83525fb92b5@mail.gmail.com> On 5/25/06, Neal Becker wrote: > > I'm confused. I thought it worked like this: > > In python, create an a=A(). Then create a b=B(a). Using > custodian_and_ward, 'a' will not be deleted as long as 'b' is alive. Then > c=getA() using return_internal_reference will ensure that 'b' is not > deleted as long as python holds 'c'. Is this not correct? Please, read my first post and the answer of David Abrahams. "a" could be created from C++ and not from Python. In this case boost.python library does not manage life time of object "a". I think, that pyplusplus should generate "safe" code, and only after this efficient. Also, you can customize the return value policy -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From rwgk at yahoo.com Thu May 25 20:53:03 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 25 May 2006 11:53:03 -0700 (PDT) Subject: [C++-sig] help passing image data In-Reply-To: <1733391377.268081148577414567.JavaMail.osg@osgjas04.cns.ufl.edu> Message-ID: <20060525185303.63344.qmail@web31513.mail.mud.yahoo.com> --- "J.D. Yamokoski" wrote: > So then does Boost support multiple Python threads created in C? Sounds like a question for Niall Douglas. You may want to mine the archive of this mailing list for messages from Niall. I'd look for tnfox, thread, interpreter lock. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From s_sourceforge at nedprod.com Thu May 25 21:57:05 2006 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 25 May 2006 20:57:05 +0100 Subject: [C++-sig] help passing image data In-Reply-To: <20060525185303.63344.qmail@web31513.mail.mud.yahoo.com> References: <1733391377.268081148577414567.JavaMail.osg@osgjas04.cns.ufl.edu> Message-ID: <44761A21.27014.20138C4@s_sourceforge.nedprod.com> On 25 May 2006 at 11:53, Ralf W. Grosse-Kunstleve wrote: > --- "J.D. Yamokoski" wrote: > > So then does Boost support multiple Python threads created in C? > > Sounds like a question for Niall Douglas. You may want to mine the archive of > this mailing list for messages from Niall. I'd look for tnfox, thread, > interpreter lock. Yep, you've beaten me to it. The python bindings are currently in a lamentable state, I just haven't had the time to work on them. If you regress back SVN to the pyste based solution you'll get something which works. Cheers, Niall From nonexistent.ftp at gmail.com Sun May 28 06:56:13 2006 From: nonexistent.ftp at gmail.com (Garrick Chin) Date: Sun, 28 May 2006 00:56:13 -0400 Subject: [C++-sig] Polymorphism and Dangling Reference exception In-Reply-To: References: Message-ID: On 5/24/06, David Abrahams wrote: > David Abrahams writes: > > > "Garrick Chin" writes: > > > >> ReferenceError: Attempt to return dangling reference to object of > >> type: class std::basic_string,class > >> std::allocator > > >> > >> I do not understand why this would be thrown. > > > > Me neither. What is your compiler and platform, please? > > FWIW, the enclosed works for me: > > > > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > > > Hmm... I wiped my test project and created a new one from scratch and now the test is working correctly oddly enough. I don't know why it wasn't working before, but it seems to have been a fluke, possibly something to do with messed up project settings. For what it's worth, I was using Visual Studio 8 on 32-bit Windows XP. From nonexistent.ftp at gmail.com Sun May 28 17:34:20 2006 From: nonexistent.ftp at gmail.com (Garrick Chin) Date: Sun, 28 May 2006 11:34:20 -0400 Subject: [C++-sig] held_ptr and polymorphism In-Reply-To: References: Message-ID: On 5/24/06, David Abrahams wrote: > "Garrick Chin" writes: > > > I compiled the \python\test\polymorphism2.cpp with and without > > HELD_BY_AUTO_PTR defined to toggle holding the C++ defined Python > > objects with and without std::auto_ptr into two separate modules: > > > > polymorphism2_ext > > polymorphism2_auto_ptr_ext > > > > I ran the following test: > > > > class ADerived(A): > > def f(self): > > return "ADerived::f()" > > > > call_f(ADerived()) > > > > with > > > > two different imports: "from polymoprhism2_ext import" and "from > > polymoprhism2_auto_ptr_ext import" > > > > With the non-auto_ptr module, call_f() correctly prints > > "ADerived::f()". _With_ the auto_ptr module, call_f() incorrectly > > prints "A::f()". Is this a bug? How does one store particular C++ > > defined Python objects in a smart pointer without losing polymorphic > > behavior? > > What is your platform and compiler? > http://engineering.meta-comm.com/boost-regression/1_33_1/developer/python_release.html > shows clearly that both tests were passing on all the combinations we > tested. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > I wiped my test project and created a new one from scratch to retest and the tests work correctly now, held and not held by auto_ptr. The previous project settings may have been messed up somehow, I'm not sure. Anyway, it works fine now. Sorry for the false alarm! From nonexistent.ftp at gmail.com Mon May 29 23:03:54 2006 From: nonexistent.ftp at gmail.com (Garrick Chin) Date: Mon, 29 May 2006 17:03:54 -0400 Subject: [C++-sig] Passing C++ objects to Python by reference Message-ID: The below class is defined in C++ and exposed in Python: class A { public: A() :value("unchanged") { } void setValue(std::string newValue) { value = newValue; } std::string value; }; The following method is defined in Python: def changeA(a): a.setValue("changed") When changeA() is passed an object created in Python: a1 = A() changeA(a1) print a1.value #prints "changed" the passed in object gets changed, but when the equivalent is done in C++: A a2; object changeA = dictionary["changeA"]; changeA(a2) std::cout << a2 << "\n"; //prints "unchanged" it appears that the C++ object is passed to Python by value instead of reference. Is there a way to specify passing by reference instead of value to boost::python? From seefeld at sympatico.ca Mon May 29 23:09:34 2006 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 29 May 2006 17:09:34 -0400 Subject: [C++-sig] Passing C++ objects to Python by reference In-Reply-To: References: Message-ID: <447B630E.8040506@sympatico.ca> Garrick Chin wrote: > it appears that the C++ object is passed to Python by value instead of > reference. Is there a way to specify passing by reference instead of > value to boost::python? Yes, see http://boost.org/libs/python/doc/v2/ptr.html#ptr-spec HTH, Stefan From nonexistent.ftp at gmail.com Mon May 29 23:20:48 2006 From: nonexistent.ftp at gmail.com (Garrick Chin) Date: Mon, 29 May 2006 17:20:48 -0400 Subject: [C++-sig] Passing C++ objects to Python by reference In-Reply-To: <447B630E.8040506@sympatico.ca> References: <447B630E.8040506@sympatico.ca> Message-ID: On 5/29/06, Stefan Seefeld wrote: > Garrick Chin wrote: > > > it appears that the C++ object is passed to Python by value instead of > > reference. Is there a way to specify passing by reference instead of > > value to boost::python? > > Yes, see http://boost.org/libs/python/doc/v2/ptr.html#ptr-spec > > HTH, > Stefan > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > Ah. That works very well, thank you! From tiger_332003 at yahoo.com Wed May 31 21:43:20 2006 From: tiger_332003 at yahoo.com (Mrinmay) Date: Wed, 31 May 2006 12:43:20 -0700 Subject: [C++-sig] Redirecting PyErr_Print Message-ID: <000601c684ea$93c43180$e200a8c0@client30> I want to build a application that scan the mail message and file attachment ,can u send me a demo Application in vc++. I will be grateful to u. Mailed:- mrinmaybiswas at rediffmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Wed May 31 09:23:50 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 31 May 2006 10:23:50 +0300 Subject: [C++-sig] Redirecting PyErr_Print In-Reply-To: <000601c684ea$93c43180$e200a8c0@client30> References: <000601c684ea$93c43180$e200a8c0@client30> Message-ID: <7465b6170605310023p1692c6b2ufd1965fca1668cc2@mail.gmail.com> On 5/31/06, Mrinmay wrote: > I want to build a application that scan the mail message and file > attachment ,can u send me a demo Yes > Application in vc++. > > > > I will be grateful to u. Please read this: http://www.catb.org/~esr/faqs/smart-questions.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/