From gerhans at gmail.com Wed Mar 1 21:37:55 2006 From: gerhans at gmail.com (G Hansford) Date: Wed, 1 Mar 2006 12:37:55 -0800 Subject: [C++-sig] Delayed load of pythonXX.dll Message-ID: I'm trying to determine if it's possible to delay the loading of the Python DLL on Windows. I would like my application to disable scripting support (but still run) if Python24.dll is missing. The Delay Loaded DLLs option in Visual C++ 7.1 seemed like it would solve my problem, but when I added python24.dll, I get the following link error: fatal error LNK1194: cannot delay-load 'python24.dll' due to import of data symbol '__imp___Py_NoneStruct' Having searched a bit on the topic, I found specific discussion of this problem in the context of using SWIG, but I can't find anything on it with respect to boost.python. I am statically linking the boost_python.lib and everything works properly when I don't try to force the delay load. Does anyone have any insight on this? Thanks for your time... From s_sourceforge at nedprod.com Thu Mar 2 15:28:30 2006 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Thu, 02 Mar 2006 14:28:30 -0000 Subject: [C++-sig] Delayed load of pythonXX.dll In-Reply-To: Message-ID: <4407010E.27814.5EABB7@s_sourceforge.nedprod.com> On 1 Mar 2006 at 12:37, G Hansford wrote: > I'm trying to determine if it's possible to delay the loading of the Python > DLL on Windows. I would like my application to disable scripting support > (but still run) if Python24.dll is missing. The Delay Loaded DLLs option in > Visual C++ 7.1 seemed like it would solve my problem, but when I added > python24.dll, I get the following link error: > fatal error LNK1194: cannot delay-load 'python24.dll' due to import of data > symbol '__imp___Py_NoneStruct' > > > Having searched a bit on the topic, I found specific discussion of this > problem in the context of using SWIG, but I can't find anything on it with > respect to boost.python. I am statically linking the boost_python.lib and > everything works properly when I don't try to force the delay load. Does > anyone have any insight on this? Think about it - if your program uses a variable stored in python24.dll, then your delay loaded DLL would just be immediately loaded on program run. And that's pointless. Cheers, Niall From seefeld at sympatico.ca Thu Mar 2 15:35:43 2006 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 02 Mar 2006 09:35:43 -0500 Subject: [C++-sig] Delayed load of pythonXX.dll In-Reply-To: References: Message-ID: <440702BF.9080805@sympatico.ca> G Hansford wrote: > I'm trying to determine if it's possible to delay the loading of the Python > DLL on Windows. I would like my application to disable scripting support > (but still run) if Python24.dll is missing. The Delay Loaded DLLs option in > Visual C++ 7.1 seemed like it would solve my problem, but when I added > python24.dll, I get the following link error: > fatal error LNK1194: cannot delay-load 'python24.dll' due to import of data > symbol '__imp___Py_NoneStruct' If you want to disable scripting support you probably want to delay-load not only the python runtime, but boost.python, too. Your problem stems from statically linking with boost.python, which depends on the python runtime library, forcing you to provide that at program startup. Regards, Stefan From gerhans at gmail.com Thu Mar 2 19:59:18 2006 From: gerhans at gmail.com (G Hansford) Date: Thu, 2 Mar 2006 10:59:18 -0800 Subject: [C++-sig] Delayed load of pythonXX.dll References: <440702BF.9080805@sympatico.ca> Message-ID: > If you want to disable scripting support you probably want to delay-load > not only the python runtime, but boost.python, too. Your problem stems > from statically linking with boost.python, which depends on the python > runtime library, forcing you to provide that at program startup. That seems like the thing to do - I imagine what I will do is just move all of my scripting code out to a separate DLL altogether. I was just hoping to avoid having any external dependencies (minus python itself), but I suppose this is a reasonable concession. Apparently there is a way to avoid this problem if you're using SWIG, but at this point I would still rather use boost.python. Thanks for your help... From amohr at pixar.com Tue Mar 7 02:54:55 2006 From: amohr at pixar.com (Alex Mohr) Date: Mon, 06 Mar 2006 17:54:55 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. Message-ID: <440CE7EF.8000401@pixar.com> Hi folks, I have a python callable object in C++ (call it 'f') and a tuple and dict of arguments (call them 't' and 'd'). In python, I could call f like this: f(*t, **d) Is there a convenient boost python way to call the python object f like this from C++? Thanks, Alex From plessing at ems-wuensche.com Tue Mar 7 08:27:54 2006 From: plessing at ems-wuensche.com (Markus Plessing) Date: Tue, 07 Mar 2006 08:27:54 +0100 Subject: [C++-sig] Calling python from c++ with tuple and dict args. In-Reply-To: <440CE7EF.8000401@pixar.com> References: <440CE7EF.8000401@pixar.com> Message-ID: > Hi folks, Hi Alex, > [...] > Is there a convenient boost python way to call the python object f like > this from C++? This may help. If not take a look at [1] ------------------------------------------------------------------------ PyObject* PyObject_CallObject (PyObject *callable_object, PyObject *args) Return value: New reference. Call a callable Python object callable_object, with arguments given by the tuple args. If no arguments are needed, then args may be NULL. Returns the result of the call on success, or NULL on failure. This is the equivalent of the Python expression "apply(callable_object, args)" or "callable_object(*args)". ------------------------------------------------------------------------- > Thanks, > > Alex Kind regards, Markus [1] http://docs.python.org/api/object.html#l2h-241 -- -------------------------------------------------------- EMS Dr. Thomas Wuensche Sonnenhang 3 85304 Ilmmuenster, Germany Phone: +49-8441-490260 Fax: +49-8441-81860 email: plessing at ems-wuensche.com Web http://www.ems-wuensche.com (.de) -------------------------------------------------------- From amohr at pixar.com Tue Mar 7 18:48:37 2006 From: amohr at pixar.com (Alex Mohr) Date: Tue, 07 Mar 2006 09:48:37 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. In-Reply-To: References: <440CE7EF.8000401@pixar.com> Message-ID: <440DC775.9090901@pixar.com> Thanks Markus, I was planning to use PyObject_Call which takes a tuple and a dict if I couldn't find a nice boost python way to do it. It seems like it would be possible to do something like this: bp::object::operator()(bp::unpacked_tuple const &args, bp::unpacked_dict const &kw) { // call as self(*args, **kw) } And then define unary * operators for tuple and dict so that *tuple would produce an unpacked_tuple and **dict would produce an unpacked_dict. Alex Markus Plessing wrote: >>Hi folks, > > > Hi Alex, > > >>[...] >>Is there a convenient boost python way to call the python object f like >>this from C++? > > > This may help. If not take a look at [1] > > ------------------------------------------------------------------------ > PyObject* PyObject_CallObject > (PyObject *callable_object, PyObject *args) > > Return value: New reference. > > Call a callable Python object callable_object, with arguments given > by the tuple args. If no arguments are needed, then args may be NULL. > Returns the result of the call on success, or NULL on failure. This is > the equivalent of the Python expression "apply(callable_object, args)" > or "callable_object(*args)". > ------------------------------------------------------------------------- > > >>Thanks, >> >>Alex > > > Kind regards, > > Markus > > [1] http://docs.python.org/api/object.html#l2h-241 > From dave at boost-consulting.com Tue Mar 7 20:26:15 2006 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Mar 2006 11:26:15 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> Message-ID: Alex Mohr writes: > Thanks Markus, > > I was planning to use PyObject_Call which takes a tuple and a dict if I > couldn't find a nice boost python way to do it. > > It seems like it would be possible to do something like this: > > bp::object::operator()(bp::unpacked_tuple const &args, > bp::unpacked_dict const &kw) { > // call as self(*args, **kw) > } > > And then define unary * operators for tuple and dict so that *tuple > would produce an unpacked_tuple and **dict would produce an unpacked_dict. > > Alex That's ******* E V I L ***** !!! and I love it! Post a patch including tests and I'll check it in. -- Dave Abrahams Boost Consulting www.boost-consulting.com From ngoodspeed at solidworks.com Tue Mar 7 20:34:38 2006 From: ngoodspeed at solidworks.com (Nat Goodspeed) Date: Tue, 7 Mar 2006 14:34:38 -0500 Subject: [C++-sig] Calling python from c++ with tuple and dict args. Message-ID: > -----Original Message----- > From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On > Behalf Of David Abrahams > Sent: Tuesday, March 07, 2006 2:26 PM > To: c++-sig at python.org > Subject: Re: [C++-sig] Calling python from c++ with tuple and dict args. > > > It seems like it would be possible to do something like this: > > > > bp::object::operator()(bp::unpacked_tuple const &args, > > bp::unpacked_dict const &kw) { > > // call as self(*args, **kw) > > } > > > > And then define unary * operators for tuple and dict so that *tuple > > would produce an unpacked_tuple and **dict would produce an > unpacked_dict. [Nat] I find myself wondering what *dict should produce -- an error? From amohr at pixar.com Tue Mar 7 20:55:00 2006 From: amohr at pixar.com (Alex Mohr) Date: Tue, 07 Mar 2006 11:55:00 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. In-Reply-To: References: Message-ID: <440DE514.1060309@pixar.com> > [Nat] I find myself wondering what *dict should produce -- an error? It's a good question. I think it should be an error, but I'm not sure how it should manifest itself. *dict needs to produce a valid object (so we can invoke * on it), but that object will have an API that will likely not really work anywhere other than where it is meant to, and we can provide overloads for the places where we expect it might accidentally be used. For instance: bp::object::operator()(unpacked_tuple const &, /* result of *dict */ intermediate_unpacked_dict const &) { // compile-time-error } Incidentally, the same general idea is true about unpacked_tuple and unpacked_dict -- we need to try to make sure that they only make sense in only the case of the specific operator() on object. Alex From amohr at pixar.com Tue Mar 7 20:55:58 2006 From: amohr at pixar.com (Alex Mohr) Date: Tue, 07 Mar 2006 11:55:58 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. In-Reply-To: References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> Message-ID: <440DE54E.2010308@pixar.com> > That's ******* E V I L ***** !!! > > and I love it! Post a patch including tests and I'll check it in. Cool -- I'll try to do it in my spare time. :) Alex From dave at boost-consulting.com Tue Mar 7 20:59:01 2006 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Mar 2006 11:59:01 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. References: Message-ID: "Nat Goodspeed" writes: >> -----Original Message----- >> From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] > On >> Behalf Of David Abrahams >> Sent: Tuesday, March 07, 2006 2:26 PM >> To: c++-sig at python.org >> Subject: Re: [C++-sig] Calling python from c++ with tuple and dict > args. >> >> > It seems like it would be possible to do something like this: >> > >> > bp::object::operator()(bp::unpacked_tuple const &args, >> > bp::unpacked_dict const &kw) { >> > // call as self(*args, **kw) >> > } >> > >> > And then define unary * operators for tuple and dict so that *tuple >> > would produce an unpacked_tuple and **dict would produce an >> unpacked_dict. > > [Nat] I find myself wondering what *dict should produce -- an error? Clearly not. You can't get to **dict without *dict. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Mar 7 21:00:42 2006 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 07 Mar 2006 12:00:42 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> Message-ID: David Abrahams writes: > Alex Mohr writes: > >> Thanks Markus, >> >> I was planning to use PyObject_Call which takes a tuple and a dict if I >> couldn't find a nice boost python way to do it. >> >> It seems like it would be possible to do something like this: >> >> bp::object::operator()(bp::unpacked_tuple const &args, >> bp::unpacked_dict const &kw) { >> // call as self(*args, **kw) >> } >> >> And then define unary * operators for tuple and dict so that *tuple >> would produce an unpacked_tuple and **dict would produce an unpacked_dict. >> >> Alex > > That's ******* E V I L ***** !!! > > and I love it! Post a patch including tests and I'll check it in. Huh, it looks like we should really extend all the overloads on object so you can do: o(1, 2, 3, *t, **d) That might be a touch more complex. -- Dave Abrahams Boost Consulting www.boost-consulting.com From amohr at pixar.com Tue Mar 7 22:29:03 2006 From: amohr at pixar.com (Alex Mohr) Date: Tue, 07 Mar 2006 13:29:03 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. In-Reply-To: References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> Message-ID: <440DFB1F.3020401@pixar.com> > Huh, it looks like we should really extend all the overloads on object > so you can do: > > o(1, 2, 3, *t, **d) > > That might be a touch more complex. You're right. Looks like we need to support: o(A1..N) o(A1..N, unpacked_tuple_args) o(A1..N, unpacked_tuple_args, unpacked_dict_args) My intuition says that we can just add the extra two along with each instance of operator(). So in object_core.hpp it'd be: object operator()() const; object operator()(unpacked_tuple const &) const; object operator()(unpacked_tuple const &, unpacked_dict const &) const; And then in the iterated object_call.hpp, we'd add the two other versions (tuple and tuple + dict) to provide the multi-leading arg versions (stuff along these lines): template typename detail::dependent::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(1, N, A, const &a), unpacked_tuple const &args, unpacked_dict const &kw) const Then we would modify bp::call<> similarly to accept trailing unpacked tuples and dicts, and call through to python with the combined arguments. Anything seem out-of-line here? If not, I'm willing to try it. Seems plausible. Alex From rmf25 at cornell.edu Tue Mar 7 17:07:17 2006 From: rmf25 at cornell.edu (Rafael M. Frongillo) Date: Tue, 07 Mar 2006 11:07:17 -0500 Subject: [C++-sig] import problems with Boost.Python on Cygwin Message-ID: <5.2.1.1.2.20060307110431.02daa3e8@postoffice6.mail.cornell.edu> Hi, I have been trying for some time now to install Boost.Python for Cygwin 1.5.19 and Python 2.4.1. I followed the instructions given on http://www.boost.org/libs/python/doc/building.html and http://www.boost.org/more/getting_started.html . As no bjam executable was posted on sourceforge for Cygwin (that I could see), I built it from source successfully. I then jammed Boost, and then Boost.Python. After a seemingly successful compilation, I tried making the example hello.cpp in the libs\python\example\tutorial directory. The hello.dll was jammed successfully, but when I ran python in a directory containing both boost_python.dll and hello.dll, I got an error: bash-3.00$ python Python 2.4.1 (#1, May 27 2005, 18:02:40) [GCC 3.3.3 (cygwin special)] on cygwin Type "help", "copyright", "credits" or "license" for more information. >>> import hello Traceback (most recent call last): File "", line 1, in ? ImportError: No such file or directory After trying various other things, I also got python to crash after the import statement. I reluctantly tried SWIG instead when I got these errors, but I had similar problems (with SWIG, the examples worked, but the application I was trying to expose to python crashed python upon import). I would much prefer to use Boost.Python, however. Does anyone know what could be going on here? I'd be interested to hear of similar experiences on Cygwin. Thanks very much, Rafael From aathan_pythoncpp_1542 at cloakmail.com Wed Mar 8 07:05:10 2006 From: aathan_pythoncpp_1542 at cloakmail.com (Andrew Athan) Date: Wed, 08 Mar 2006 01:05:10 -0500 Subject: [C++-sig] How to load a statically linked boost python module into embedded Python Message-ID: <440E7416.9000509@cloakmail.com> Perhaps this should be in the manual or FAQ? I've created a simple boost python wrapper for a C++ class, the code is below. This .o is linked into an application in which I have an embedded python interpreter. How do I expose the TradeObjects module to the python code? I believe the answer is: Invoke initTradeObjects() after Py_Initialize(); Correct? A. #include #include "TradeObjects.h" using namespace boost::python; BOOST_PYTHON_MODULE(TradeObjects) { class_("SymbolRef",init()) .def("strValue", &TTTO::SymbolRef::strValue) ; } From aathan_R_1542 at memeplex.com Wed Mar 8 07:29:42 2006 From: aathan_R_1542 at memeplex.com (Andrew Athan) Date: Wed, 08 Mar 2006 01:29:42 -0500 Subject: [C++-sig] Regarding thread compatibility of boost python Message-ID: <440E79D6.2080700@memeplex.com> Could someone please elaborate on what is and is not safe to do with respect to threads and boost python? My specific situation involves an embedded python interpreter within a C++ app that uses multiple NPTL threads. The Python module which is initially called creates a number of threads within Python code. Following initialization, calls tend to originate from C++ into Python, and I can guarantee that these are serialized so that no more than one thread is calling into Python at once. However, Python may call back out to C++, and when doing so I need to ensure thread safety of the C++ code. However, such "backout" calls (to coin a new term) never result in an intermediate callback into Python. I.e., C++->Python->C++ is possible, but not C++->Python->C++->Python. And, such "backout" calls are not long running. Here are what I believe are the correct answers: * I assume that thread safety of the C++ code, when invoked from within Python, is really a matter of the C++ code itself. Python threads map to NPTL threads, correct? So, it's possible that my C++ code will be invoked from a different thread than the one used to call into Python. Therefore, I should appropriately protect the C++ code using NPTL mutexes. * Calls into Python should be wrapped with PyGILState_Ensure() and PyGILState_Release() * "backout" calls don't have to be protected, really, since they are not long running, it's probably safe not to wrap them in Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS Despite the constraints I have described above, which seem (unless someone corrects me) to relax the thread safety requirements, I am looking into using the boost python patches in the Tn FOX library. Can anyone characterize these? There is not much included in the sources by way of documentation. I have not yet looked into the actual Tn FOX documentation package. Thanks, A. From s_sourceforge at nedprod.com Wed Mar 8 13:19:00 2006 From: s_sourceforge at nedprod.com (Niall Douglas) Date: Wed, 08 Mar 2006 12:19:00 -0000 Subject: [C++-sig] Regarding thread compatibility of boost python In-Reply-To: <440E79D6.2080700@memeplex.com> Message-ID: <440ECBB4.1759.83764@s_sourceforge.nedprod.com> On 8 Mar 2006 at 1:29, Andrew Athan wrote: > Despite the constraints I have described above, which seem (unless > someone corrects me) to relax the thread safety requirements, I am > looking into using the boost python patches in the Tn FOX library. Can > anyone characterize these? There is not much included in the sources by > way of documentation. I have not yet looked into the actual Tn FOX > documentation package. I would pull BoostPatches.zip from the Python directory inside TnFOX from SVN. I'd then diff the files to see what I did to patch things. Some of the patching is merging in TnFOX features eg; exception handling. But much of it is the threading stuff. Of course, TnFOX has its own threading system so if you don't want to use TnFOX, you'll need to replace all that with your own. I should add that TnFOX can be built as a non-GUI library and thus just as a reasonably small portability library. You may find it easier to simply link against TnFOX generated via this method. I should add that the python bindings currently don't respect the non- GUI build just yet (it's coming). The TnFOX python bindings include a full copy of Boost.Python. Cheers, Niall From dave at boost-consulting.com Wed Mar 8 13:51:04 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 08 Mar 2006 04:51:04 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> <440DFB1F.3020401@pixar.com> Message-ID: Alex Mohr writes: >> Huh, it looks like we should really extend all the overloads on object >> so you can do: >> >> o(1, 2, 3, *t, **d) >> >> That might be a touch more complex. > > You're right. Looks like we need to support: > o(A1..N) > o(A1..N, unpacked_tuple_args) > o(A1..N, unpacked_tuple_args, unpacked_dict_args) not o(A1..N, unpacked_dict_args) as well? > My intuition says that we can just add the extra two along with each > instance of operator(). So in object_core.hpp it'd be: > > object operator()() const; > object operator()(unpacked_tuple const &) const; > object operator()(unpacked_tuple const &, unpacked_dict const &) const; That won't work with the old broken compilers (vc6/7), I think, which -- at least for now -- are still supported. But I think it's pretty easy to do something inside boost/python/call.hpp to make it recognize the unpacked tuple and dict arguments and treat them specially. > And then in the iterated object_call.hpp, we'd add the two other > versions (tuple and tuple + dict) to provide the multi-leading arg > versions (stuff along these lines): > > template > typename detail::dependent::type > operator()(BOOST_PP_ENUM_BINARY_PARAMS(1, N, A, const &a), > unpacked_tuple const &args, unpacked_dict const &kw) const > > Then we would modify bp::call<> similarly to accept trailing unpacked > tuples and dicts, and call through to python with the combined arguments. If you just modify boost::python::call<> you don't need to touch anything else. -- Dave Abrahams Boost Consulting www.boost-consulting.com From amohr at pixar.com Wed Mar 8 18:47:13 2006 From: amohr at pixar.com (Alex Mohr) Date: Wed, 08 Mar 2006 09:47:13 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. In-Reply-To: References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> <440DFB1F.3020401@pixar.com> Message-ID: <440F18A1.3060301@pixar.com> > not > > o(A1..N, unpacked_dict_args) > > as well? Yes -- that too, and that's what I've implemented. > That won't work with the old broken compilers (vc6/7), I think, which > -- at least for now -- are still supported. But I think it's pretty > easy to do something inside boost/python/call.hpp to make it recognize > the unpacked tuple and dict arguments and treat them specially. Interesting. The only environments I have readily available are gcc 4+ on linux and vc-8_0 on Windows and the obvious thing seems to work on those. So I'll likely need some help with supporting the older compilers. Or -- is there an existing pattern somewhere that I can look at? > If you just modify boost::python::call<> you don't need to touch > anything else. That's true -- I'll do that. There is the question of whether unpacked_tuple and unpacked_dict should count against MAX_ARITY though. That is, is MAX_ARITY the max number of explicit positional args, or is MAX_ARITY the max number of c++ args? What is the preferred way of generating a patch to post to the list? Thanks, Alex From ndbecker2 at gmail.com Wed Mar 8 18:52:23 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 08 Mar 2006 12:52:23 -0500 Subject: [C++-sig] Calling python from c++ with tuple and dict args. References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> <440DFB1F.3020401@pixar.com> <440F18A1.3060301@pixar.com> Message-ID: Alex Mohr wrote: >> not >> >> o(A1..N, unpacked_dict_args) >> >> as well? > > Yes -- that too, and that's what I've implemented. > >> That won't work with the old broken compilers (vc6/7), I think, which >> -- at least for now -- are still supported. But I think it's pretty >> easy to do something inside boost/python/call.hpp to make it recognize >> the unpacked tuple and dict arguments and treat them specially. > > Interesting. The only environments I have readily available are gcc 4+ > on linux and vc-8_0 on Windows and the obvious thing seems to work on > those. So I'll likely need some help with supporting the older > compilers. Or -- is there an existing pattern somewhere that I can look > at? > >> If you just modify boost::python::call<> you don't need to touch >> anything else. > > That's true -- I'll do that. There is the question of whether > unpacked_tuple and unpacked_dict should count against MAX_ARITY though. > That is, is MAX_ARITY the max number of explicit positional args, or > is MAX_ARITY the max number of c++ args? > > What is the preferred way of generating a patch to post to the list? > Diff? :) From amohr at pixar.com Wed Mar 8 19:28:02 2006 From: amohr at pixar.com (Alex Mohr) Date: Wed, 08 Mar 2006 10:28:02 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. In-Reply-To: References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> <440DFB1F.3020401@pixar.com> <440F18A1.3060301@pixar.com> Message-ID: <440F2232.6030100@pixar.com> > Diff? :) Heh, yeah, certainly -- I was wondering if there was a more formalized set of steps, including particular diff args, preferred packaging and compression, handling added files, etc. Alex From koen_van_herck at yahoo.com Wed Mar 8 20:26:30 2006 From: koen_van_herck at yahoo.com (Koen Van Herck) Date: Wed, 8 Mar 2006 11:26:30 -0800 (PST) Subject: [C++-sig] import problems with Boost.Python on Cygwin In-Reply-To: <5.2.1.1.2.20060307110431.02daa3e8@postoffice6.mail.cornell.edu> Message-ID: <20060308192630.86793.qmail@web30012.mail.mud.yahoo.com> I've got a Boost.Python project working fine on cygwin 1.5.18, python 2.4.1 (cygwin binary install), gcc 3.4.4. When I recently ran the cygwin setup.exe it automatically upgraded cygwin to 1.5.19, and now my project still compiles fine but when I import my module in Python's interactive shell, python silently returns to the shell prompt. No error, just exits. I rebuilt Boost.Python from source, but no difference. I reverted cygwin to 1.5.18, and it works fine again. Regards, Koen. From dave at boost-consulting.com Wed Mar 8 20:58:03 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 08 Mar 2006 11:58:03 -0800 Subject: [C++-sig] Calling python from c++ with tuple and dict args. References: <440CE7EF.8000401@pixar.com> <440DC775.9090901@pixar.com> <440DFB1F.3020401@pixar.com> <440F18A1.3060301@pixar.com> Message-ID: Alex Mohr writes: >> not >> >> o(A1..N, unpacked_dict_args) >> >> as well? > > Yes -- that too, and that's what I've implemented. > >> That won't work with the old broken compilers (vc6/7), I think, which >> -- at least for now -- are still supported. But I think it's pretty >> easy to do something inside boost/python/call.hpp to make it recognize >> the unpacked tuple and dict arguments and treat them specially. > > Interesting. The only environments I have readily available are gcc 4+ > on linux and vc-8_0 on Windows and the obvious thing seems to work on > those. So I'll likely need some help with supporting the older > compilers. Or -- is there an existing pattern somewhere that I can look at? Just don't rely on partial ordering or partial specialization. Detect the special types inside of each call<> overload using type traits and handle them appropriately using some kind of metaprogramming. >> If you just modify boost::python::call<> you don't need to touch >> anything else. > > That's true -- I'll do that. There is the question of whether > unpacked_tuple and unpacked_dict should count against MAX_ARITY though. > That is, is MAX_ARITY the max number of explicit positional args, or > is MAX_ARITY the max number of c++ args? Make it the latter; it will be simpler. > What is the preferred way of generating a patch to post to the list? _enclose_ (rather than paste) a unified diff into a post. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Mar 8 20:59:08 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 08 Mar 2006 11:59:08 -0800 Subject: [C++-sig] import problems with Boost.Python on Cygwin References: <5.2.1.1.2.20060307110431.02daa3e8@postoffice6.mail.cornell.edu> <20060308192630.86793.qmail@web30012.mail.mud.yahoo.com> Message-ID: Koen Van Herck writes: > I've got a Boost.Python project working fine on cygwin 1.5.18, python 2.4.1 > (cygwin binary install), gcc 3.4.4. When I recently ran the cygwin setup.exe > it automatically upgraded cygwin to 1.5.19, and now my project still > compiles fine but when I import my module in Python's interactive shell, > python silently returns to the shell prompt. No error, just exits. I rebuilt > Boost.Python from source, but no difference. > I reverted cygwin to 1.5.18, and it works fine again. You probably need to rebuild your libboost_python and all related extension modules. -- Dave Abrahams Boost Consulting www.boost-consulting.com From koen_van_herck at yahoo.com Wed Mar 8 21:48:26 2006 From: koen_van_herck at yahoo.com (Koen Van Herck) Date: Wed, 8 Mar 2006 21:48:26 +0100 Subject: [C++-sig] import problems with Boost.Python on Cygwin In-Reply-To: Message-ID: Yes, I did rebuild everything (libboost_python, my extension module, and every library that it uses) from source. I did not rebuild Python. I used the binary Python install from cygwin, which I did not update. Could that be the problem? Regards, Koen. -----Original Message----- From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org]On Behalf Of David Abrahams Sent: woensdag 8 maart 2006 20:59 To: c++-sig at python.org Subject: Re: [C++-sig] import problems with Boost.Python on Cygwin Koen Van Herck writes: > I've got a Boost.Python project working fine on cygwin 1.5.18, python 2.4.1 > (cygwin binary install), gcc 3.4.4. When I recently ran the cygwin setup.exe > it automatically upgraded cygwin to 1.5.19, and now my project still > compiles fine but when I import my module in Python's interactive shell, > python silently returns to the shell prompt. No error, just exits. I rebuilt > Boost.Python from source, but no difference. > I reverted cygwin to 1.5.18, and it works fine again. You probably need to rebuild your libboost_python and all related extension modules. -- 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 From dave at boost-consulting.com Thu Mar 9 00:18:50 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 08 Mar 2006 15:18:50 -0800 Subject: [C++-sig] import problems with Boost.Python on Cygwin References: Message-ID: "Koen Van Herck" writes: > Yes, I did rebuild everything (libboost_python, my extension module, and > every library that it uses) from source. > I did not rebuild Python. I used the binary Python install from cygwin, > which I did not update. Could that be the problem? Conceivably, but it seems unlikely. I have no immediate ideas. I suggest GDB'ing your Python, which might require creating a debug build. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rmf25 at cornell.edu Thu Mar 9 06:48:02 2006 From: rmf25 at cornell.edu (Rafael M. Frongillo) Date: Thu, 09 Mar 2006 00:48:02 -0500 Subject: [C++-sig] import problems with Boost.Python on Cygwin Message-ID: <5.2.1.1.2.20060309004249.02e56e40@postoffice6.mail.cornell.edu> >I've got a Boost.Python project working fine on cygwin 1.5.18, python 2.4.1 >(cygwin binary install), gcc 3.4.4. When I recently ran the cygwin setup.exe >it automatically upgraded cygwin to 1.5.19, and now my project still >compiles fine but when I import my module in Python's interactive shell, >python silently returns to the shell prompt. No error, just exits. I rebuilt >Boost.Python from source, but no difference. >I reverted cygwin to 1.5.18, and it works fine again. > >Regards, >Koen. When python crashed, it did so silently just as you described. Since I also used the setup program to upgrade cygwin, I will try reverting cygwin to 1.5.18 and see what happens... thanks for your response. Rafael -------------- next part -------------- An HTML attachment was scrubbed... URL: From abhi at qualcomm.com Thu Mar 9 22:55:01 2006 From: abhi at qualcomm.com (Abhi) Date: Thu, 09 Mar 2006 13:55:01 -0800 Subject: [C++-sig] Newbie Question about wrapping a function with int *, int & , etc... Message-ID: <5FAA11166E69576AEFF3AFAD@[10.30.7.179]> I need to wrap the following class in python someclass.h class BasicTypesTest { // Pointer, Reference and const types // int* argument, int return int ptrIntArg_intRet(int* x); // int& argument, int return int refIntArg_intRet(int& x); // const int argument, int return int intConstArg_intRet(const int x); // const int* argument, int return int ptrIntConstArg_intRet(const int* x); // const int& argument, int return int refIntConstArg_intRet(const int& x); }; myboostpythonwrapper.cpp BOOST_PYTHON_MODULE (BoostPythonTest) { class_("BasicTypesTest") .def( init<>()) .def( "ptrIntArg_intRet", &BasicTypesTest::ptrIntArg_intRet ) .def( "refIntArg_intRet", &BasicTypesTest::refIntArg_intRet ) .def( "intConstArg_intRet", &BasicTypesTest::intConstArg_intRet ) .def( "ptrIntConstArg_intRet", &BasicTypesTest::ptrIntConstArg_intRet ) .def( "refIntConstArg_intRet", &BasicTypesTest::refIntConstArg_intRet ) ; } This does not work. For example if I try to do: import BoostPythonTest # Get the class b = BoostPythonTest.BasicTypesTest() x = 5; y = 5; # Call methods print "Calling C++ ptrIntArg_intRet" print "Argument x =", x b.ptrIntArg_intRet(x) <------------Error print "Argument x =", x print "---" Similarly for other methods. Is there an easy way to do this? thanks - Abhi From kelly.burkhart at gmail.com Fri Mar 10 04:23:05 2006 From: kelly.burkhart at gmail.com (Kelly Burkhart) Date: Thu, 9 Mar 2006 21:23:05 -0600 Subject: [C++-sig] Can a module reference a class exposed in another module? Message-ID: Greetings, Given two Boost Python modules, can one contain a funtion which accepts as a parameter an instance of a class defined in the other? For instance, if module A exposes class X, could I create a module B that can convert the python representation of C back to it's c++ representation: import A import B x = A.X() B.myfun( x ) Thanks, -Kelly -------------- next part -------------- An HTML attachment was scrubbed... URL: From webmaster at webko.com.au Fri Mar 10 01:00:47 2006 From: webmaster at webko.com.au (Webko) Date: Fri, 10 Mar 2006 11:00:47 +1100 Subject: [C++-sig] IT Directory Link Exchange - PR5 Links Message-ID: <291c47d5546236f61c8e5c0b31604785@www.webko.com.au> An HTML attachment was scrubbed... URL: From rwgk at yahoo.com Fri Mar 10 07:42:23 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 9 Mar 2006 22:42:23 -0800 (PST) Subject: [C++-sig] Can a module reference a class exposed in another module? In-Reply-To: Message-ID: <20060310064224.65355.qmail@web31507.mail.mud.yahoo.com> --- Kelly Burkhart wrote: > Given two Boost Python modules, can one contain a funtion which accepts as a > parameter an instance of a class defined in the other? For instance, if > module A exposes class X, could I create a module B that can convert the > python representation of C back to it's c++ representation: > > import A > import B > > x = A.X() > B.myfun( x ) Yes, this works. The Python-C++ converters are stored in a central registry. You just have to ensure the module defining a conversion is imported before the converters are used (as you do above). This feature is called cross-module support. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From kelly at kkcsm.net Fri Mar 10 16:35:13 2006 From: kelly at kkcsm.net (Kelly Burkhart) Date: Fri, 10 Mar 2006 09:35:13 -0600 Subject: [C++-sig] Casting from Base to Derived Message-ID: Greetings (and thanks for help on my last question!) Given the following C++: class Base {...}; class D1 : public Base {...}; class D2 : public Base {...}; struct Foo { std::auto_ptr func(); // may return a D1 or D2 }; ... BOOST_PYTHON_MODULE(mod) { class_("Base", no_init); class_() ...; class_() ...; } How can I expose Foo so that Foo::func() returns a D1 or D2 rather than a Base? What is the appropriate alternative to the C++ dynamic_cast? Thanks, -K -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Fri Mar 10 17:44:54 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 10 Mar 2006 20:44:54 +0400 Subject: [C++-sig] Newbie Question about wrapping a function with int *, int & , etc... In-Reply-To: <5FAA11166E69576AEFF3AFAD@10.30.7.179> References: <5FAA11166E69576AEFF3AFAD@10.30.7.179> Message-ID: <7465b6170603100844o7d6cbd2o682b4a34c1c1de59@mail.gmail.com> On 3/10/06, Abhi wrote: > I need to wrap the following class in python > > someclass.h > > class BasicTypesTest > { > // Pointer, Reference and const types > > // int* argument, int return > int ptrIntArg_intRet(int* x); > > // int& argument, int return > int refIntArg_intRet(int& x); > > // const int argument, int return > int intConstArg_intRet(const int x); > > // const int* argument, int return > int ptrIntConstArg_intRet(const int* x); > > // const int& argument, int return > int refIntConstArg_intRet(const int& x); > > }; > > > myboostpythonwrapper.cpp > > BOOST_PYTHON_MODULE (BoostPythonTest) > { > > class_("BasicTypesTest") > .def( init<>()) > > .def( "ptrIntArg_intRet", &BasicTypesTest::ptrIntArg_intRet ) > .def( "refIntArg_intRet", &BasicTypesTest::refIntArg_intRet ) > .def( "intConstArg_intRet", &BasicTypesTest::intConstArg_intRet ) > .def( "ptrIntConstArg_intRet", &BasicTypesTest::ptrIntConstArg_intRet ) > .def( "refIntConstArg_intRet", &BasicTypesTest::refIntConstArg_intRet ) > ; > } > > > This does not work. > For example if I try to do: > > import BoostPythonTest > > # Get the class > b = BoostPythonTest.BasicTypesTest() > > x = 5; > y = 5; > > # Call methods > print "Calling C++ ptrIntArg_intRet" > print "Argument x =", x > b.ptrIntArg_intRet(x) <------------Error > print "Argument x =", x > print "---" > > > Similarly for other methods. > > Is there an easy way to do this? Yes and no. Yes, because it very easy to write wrapper for such functions. Something like this: boost::python::tuple refIntArg_intRet(BasicTypesTest& self, int x){ int x_ref = x; int result = self.refIntArg_intRet( ref_x ); return boost::python::tuple( result, x ); } def( "refIntArg_intRet", &::refIntArg_intRet ) So, as you can see you can expose such functions. This was easy, right? So why "no"? Because there is no code generator that supports this feature. I plan to add to pyplusplus such feature. You are welcome to contribute: test cases or code. > thanks > - Abhi Hope, I helped. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From christophe.gratin at adcis.net Fri Mar 10 19:25:40 2006 From: christophe.gratin at adcis.net (Christophe Gratin) Date: Fri, 10 Mar 2006 19:25:40 +0100 Subject: [C++-sig] X_wrap(PyObject* self, int v) FAQ example won't compile Message-ID: <4411C4A4.60306@adcis.net> I tried the following code from the boost python FAQ, (http://www.boost.org/libs/python/doc/v2/faq.html) but it doesn't compile (MS Visual C++ 2005). The error message is dumped below. class X { public: X(int) {}; virtual ~X(){}; }; struct X_wrap : X { X_wrap(PyObject* self, int v) : self(self), X(v) {} PyObject* self; }; BOOST_PYTHON_MODULE(Test) { { class_("X", init()); } } [....]\boost\boost\python\object\value_holder.hpp(160) : error C2664: 'X_wrap::X_wrap(PyObject *,int)' : cannot convert parameter 2 from 'const X' to 'int' No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called [....]\boost\boost\python\object\make_instance.hpp(68) : see reference to function template instantiation 'boost::python::objects::value_holder_back_reference::value_holder_back_reference>(PyObject *,A0)' being compiled with [ Value=X, Held=X_wrap, T=const X, A0=boost::reference_wrapper ] [....]\boost\boost\python\object\make_instance.hpp(67) : while compiling class template member function 'boost::python::objects::value_holder_back_reference *boost::python::objects::make_instance::construct(void *,PyObject *,boost::reference_wrapper)' with [ Value=X, Held=X_wrap, T=X, Holder=boost::python::objects::value_holder_back_reference ] [....]\boost\boost\python\object\class_wrapper.hpp(26) : see reference to class template instantiation 'boost::python::objects::make_instance' being compiled with [ T=X, Holder=boost::python::objects::value_holder_back_reference ] [....]\boost\boost\python\object\class_wrapper.hpp(25) : while compiling class template member function 'PyObject *boost::python::objects::class_cref_wrapper::convert(const Src &)' with [ Src=X, MakeInstance=boost::python::objects::make_instance> ] [....]\boost\boost\python\object\class_metadata.hpp(260) : see reference to class template instantiation 'boost::python::objects::class_cref_wrapper' being compiled with [ Src=X, MakeInstance=boost::python::objects::make_instance> ] [....]\boost\boost\python\object\class_metadata.hpp(229) : see reference to function template instantiation 'void boost::python::objects::class_metadata::maybe_register_class_to_python(T2 *,boost::mpl::false_)' being compiled with [ T=X, X1=X_wrap, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified, T2=X ] [....]\boost\boost\python\object\class_metadata.hpp(219) : see reference to function template instantiation 'void boost::python::objects::class_metadata::register_aux2>(T2 *,Callback)' being compiled with [ T=X, X1=X_wrap, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified, T2=X, Callback=boost::integral_constant ] [....]\boost\boost\python\object\class_metadata.hpp(217) : while compiling class template member function 'void boost::python::objects::class_metadata::register_aux(void *)' with [ T=X, X1=X_wrap, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] [....]\boost\boost\python\class.hpp(174) : see reference to class template instantiation 'boost::python::objects::class_metadata' being compiled with [ T=X, X1=X_wrap, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] [....]\boost\boost\python\class.hpp(205) : see reference to class template instantiation 'boost::python::class_::id_vector' being compiled with [ W=X, X1=X_wrap ] [....]\pythonTest.cpp(244) : see reference to function template instantiation 'boost::python::class_::class_>(const char *,const boost::python::init_base &)' being compiled with [ W=X, X1=X_wrap, T0=int, DerivedT=boost::python::init ] From ndbecker2 at gmail.com Fri Mar 10 21:03:51 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Fri, 10 Mar 2006 15:03:51 -0500 Subject: [C++-sig] help with numpy Message-ID: I'm trying to use numpy, but stuck. I think I need to register a converter, but don't know how. Here's a test: #include #include #include #include namespace bp=boost::python; static bp::object Test () { intp dims[1]; dims[0] = 2; return *(PyArrayObject*)PyArray_SimpleNew (1, dims, PyArray_INT); } BOOST_PYTHON_MODULE (test) { import_array(); bp::def ("Test", &Test); } This one doesn't even compile - can't convert error: conversion from 'PyArrayObject' to non-scalar type 'boost::python::api::object' requested If I try static bp::PyArrayObject Test()... Then at runtime I get: TypeError: No to_python (by-value) converter found for C++ type: PyArrayObject I want to convice the type system that PyArrayObject is the same as; type(numpy.zeros(2)) From rwgk at yahoo.com Sat Mar 11 12:43:23 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 11 Mar 2006 03:43:23 -0800 (PST) Subject: [C++-sig] shared_ptr trouble Message-ID: <20060311114323.94268.qmail@web31508.mail.mud.yahoo.com> I'm having terrible trouble understanding how Boost.Python interacts with shared_ptr. I'm trying to implement a small tree node class with parent-child relationships via weak_ptr: class node : boost::noncopyable { private: node() {} boost::weak_ptr parent_; public: std::string id; // ... }; To be used eventually like this: node1 = node.create(id="a") node2 = node.create(id="b", parent=node1) node1 has no parent, node2 should use node1 as the parent. The equivalent C++ code is: std::string exercise_child_parent_id() { boost::shared_ptr node1 = node::create("a"); boost::shared_ptr node2 = node::create("b", node1); return node2->get_parent_id(); } A minimal, self-contained example is attached. The test is simply: from boost_adaptbx_tree_ext import node, exercise_child_parent_id def exercise(): print "C++:", exercise_child_parent_id() node1 = node.create(id="a") node2 = node.create(id="b", parent=node1) print "Python:", node2.get_parent_id() if (__name__ == "__main__"): exercise() Output: C++: a Python: no parent The C++ code produces the desired result, but the Python version fails. By adding print statements to this function of the node class static boost::shared_ptr create( std::string const& id, boost::shared_ptr const& parent) { boost::shared_ptr result(new node); result->id = id; result->parent_ = parent; return result; } I found out that result->parent_->id is in fact "a" right before the return, but back in Python the parent is lost. Since node is noncopyable I cannot figure out how this can be, and what I need to do to fix the problem. I'd be grateful for advice! This is with Python 2.4, gcc 3.4 under Fedora Core 3 x86_64, using the Boost CVS from yesterday. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: tree_ext.cpp URL: From paustin at eos.ubc.ca Sun Mar 12 21:26:09 2006 From: paustin at eos.ubc.ca (Philip Austin) Date: Sun, 12 Mar 2006 12:26:09 -0800 Subject: [C++-sig] help with numpy In-Reply-To: References: Message-ID: <17428.33761.1572.176144@owl.eos.ubc.ca> Neal Becker writes: > I'm trying to use numpy, but stuck. I think I need to register a converter, > but don't know how. Here's a test: There's a ready made converter that comes with http://www.boost.org/libs/python/doc/v2/numeric.html Some helper functions and examples are posted at http://www.eos.ubc.ca/research/clouds/num_util.html I'm still about a month away from posting a numpy-ready version but my and large they work as is with numeric::array::set_module_and_type("Numeric", "ArrayType"); changed to: numeric::array::set_module_and_type("numpy", "ArrayType"); Here's a stripped example that works for me with boost_1_31_1 #include #include //Create a numarray referencing Python sequence object using namespace boost::python; numeric::array makeNum(object x){ if (!PySequence_Check(x.ptr())){ PyErr_SetString(PyExc_ValueError, "expected a sequence"); throw_error_already_set(); } object obj(handle<> (PyArray_ContiguousFromObject(x.ptr(),PyArray_NOTYPE,0,0))); return extract(obj); } BOOST_PYTHON_MODULE(simpletest) { using namespace boost::python; import_array(); numeric::array::set_module_and_type("numpy", "ArrayType"); def("makeNum", makeNum); } _______________ import simpletest myArray=simpletest.makeNum([0,1,2,3]) print type(myArray),myArray _______________ ~ phil at gull% python simpletest.py [0 1 2 3] Regards, Phil From paustin at eos.ubc.ca Sun Mar 12 22:04:44 2006 From: paustin at eos.ubc.ca (Philip Austin) Date: Sun, 12 Mar 2006 13:04:44 -0800 Subject: [C++-sig] [boost] Adding numpy support to boost::python In-Reply-To: References: Message-ID: <17428.36076.623380.979211@owl.eos.ubc.ca> Neal Becker writes: > Has anyone tried yet adding numpy support to boost::python? Is the only > requirement to add "numpy" to load function, or are there more extensive > API changes from numarray to numpy? The only real problem I've encountered is handling the new type object. e.g.: >>> check(y.typecode()); in boost_1_33_1/libs/python/test/numpy.py will fail because the character id returned by y.typecode() has been replaced by a new dtype object: In [19]:import numpy as np In [20]:npArray=np.zeros(5) In [21]:print npArray.typecode() --------------------------------------------------------------------------- exceptions.AttributeError Traceback (most recent call last) /nfs/kite/users/phil/ AttributeError: 'numpy.ndarray' object has no attribute 'typecode' In [22]:print npArray.dtype ' Message-ID: "Ralf W. Grosse-Kunstleve" writes: Cc:'ing Peter Dimov in case he has any brilliant ideas. Peter, I'll forward you Ralf's complete posting under separate cover. > I'm having terrible trouble understanding how Boost.Python interacts with > shared_ptr. I'm trying to implement a small tree node class with parent-child > relationships via weak_ptr: > > class node : boost::noncopyable > { > private: > node() {} > > boost::weak_ptr parent_; > > public: > std::string id; > > // ... > }; > > To be used eventually like this: > > node1 = node.create(id="a") > node2 = node.create(id="b", parent=node1) > > node1 has no parent, node2 should use node1 as the parent. The equivalent C++ > code is: > > std::string > exercise_child_parent_id() > { > boost::shared_ptr node1 = node::create("a"); > boost::shared_ptr node2 = node::create("b", node1); > return node2->get_parent_id(); > } > > A minimal, self-contained example is attached. The test is simply: > > from boost_adaptbx_tree_ext import node, exercise_child_parent_id Here's the problem: > def exercise(): > print "C++:", exercise_child_parent_id() > node1 = node.create(id="a") > node2 = node.create(id="b", parent=node1) right here, node1 gets converted to a shared_ptr. Even though nodes are held by shared_ptr, Boost.Python does not extract the held_type instance from its Python wrapper. Instead, it creates a new shared_ptr (with a whole new "control block" containing a use_count, weak_count and deleter) whose deleter manages a reference count on the owning Python object. That's the magic that allows Boost.Python to recover the original Python object when such a shared_ptr is converted back to Python. Unfortunately, it's also what causes your problem. The weak_ptr stored in your node is related to the control block of the new shared_ptr and _not_ to the one stored inside your Python object. When the Python create( ... ) method returns, that shared_ptr goes away. Since it was the last non-weak reference to that control block, the weak_ptr thinks the object is gone... > print "Python:", node2.get_parent_id() > > if (__name__ == "__main__"): > exercise() > > Output: > > C++: a > Python: no parent > > The C++ code produces the desired result, but the Python version fails. By > adding print statements to this function of the node class > > static > boost::shared_ptr > create( > std::string const& id, > boost::shared_ptr const& parent) You can force Boost.Python to grab the shared_ptr stored in the Python object by removing "const" from the line above. That signals that a shared_ptr lvalue is needed and no shared_ptr conjured up on the fly by the conversion machinery will suffice (this is essentially the rule temporaries don't bind to non-const references, as implemented by Boost.Python). On the other hand, when you convert that weak_ptr back into a shared_ptr, and convert _that_ back to Python, you won't see the original Python object, but an identical one whose held shared_ptr refers to the same C++ object. This is a knotty problem and I'm not sure there's a good answer. > { > boost::shared_ptr result(new node); > result->id = id; > result->parent_ = parent; > return result; > } > > I found out that result->parent_->id is in fact "a" right before the return, > but back in Python the parent is lost. Since node is noncopyable I cannot > figure out how this can be, and what I need to do to fix the problem. I'd be > grateful for advice! -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Mon Mar 13 07:40:21 2006 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 12 Mar 2006 22:40:21 -0800 Subject: [C++-sig] X_wrap(PyObject* self, int v) FAQ example won't compile References: <4411C4A4.60306@adcis.net> Message-ID: Christophe Gratin writes: > I tried the following code from the boost python FAQ, > (http://www.boost.org/libs/python/doc/v2/faq.html) but it doesn't > compile (MS Visual C++ 2005). > The error message is dumped below. > > class X { public: X(int) {}; virtual ~X(){}; }; > > struct X_wrap : X > { > X_wrap(PyObject* self, int v) : self(self), X(v) {} > PyObject* self; > }; > > BOOST_PYTHON_MODULE(Test) > { > { > class_("X", init()); > } > } The error comes from trying to expose the copy ctor for X and not finding an appropriate X_wrap ctor containing a PyObject* as its first argument. You can fix it by adding boost::noncopyable to the template argument list for class_ class_("X", init()); Sorry for the hassle. FAQ updated. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Tue Mar 14 08:30:19 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 13 Mar 2006 23:30:19 -0800 (PST) Subject: [C++-sig] shared_ptr trouble In-Reply-To: Message-ID: <20060314073019.11273.qmail@web31507.mail.mud.yahoo.com> --- David Abrahams wrote: > > def exercise(): > > print "C++:", exercise_child_parent_id() > > node1 = node.create(id="a") > > node2 = node.create(id="b", parent=node1) > > right here, node1 gets converted to a shared_ptr. Even though > nodes are held by shared_ptr, Boost.Python does not extract the > held_type instance from its Python wrapper. Instead, it creates a > new shared_ptr (with a whole new "control block" containing a > use_count, weak_count and deleter) whose deleter manages a reference > count on the owning Python object. Thanks a lot for the explanation! This makes everything clear. After thinking about the original node::create() interface a little I decided it wasn't the right approach. Instead I implemented the prototype code which is attached for the records (and critcism). Essentially, the fact that the node members are managed by a shared_ptr is completely hidden: class node { protected: struct members : boost::noncopyable { boost::weak_ptr parent_data; std::string name; std::vector children; // ... }; boost::shared_ptr data_; public: node( node const& parent, std::string name); node parent() const; void set_parent(node const& new_parent); // ... }; To Boost.Python there is nothing special about this class: class_("node", no_init) .def(init( (arg_("parent"), arg_("name")))) .def("parent", &node::parent) .def("set_parent", &node::set_parent, (arg_("new_parent"))) ; This does everything the way I expect. The Python and C++ interfaces are exactly identical. The only problem I see with my tiny prototype are potential reference cycles, but it is not an issue in my actual application because parents and children always have different types. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: tree_ext.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: tst_tree.py URL: From amohr at pixar.com Tue Mar 14 19:54:56 2006 From: amohr at pixar.com (Alex Mohr) Date: Tue, 14 Mar 2006 10:54:56 -0800 Subject: [C++-sig] shared_ptr trouble In-Reply-To: References: <20060311114323.94268.qmail@web31508.mail.mud.yahoo.com> Message-ID: <44171180.5070208@pixar.com> > Instead, it creates a > new shared_ptr (with a whole new "control block" containing a > use_count, weak_count and deleter) whose deleter manages a reference > count on the owning Python object. That's the magic that allows > Boost.Python to recover the original Python object when such a > shared_ptr is converted back to Python. I've been meaning to post regarding this and my effort to make custom smart pointers work as well as shared_ptr does with c++ <-> python polymorphism. This "object identity" problem is the biggest issue. You can sort of make it work with custom smart pointers by registering from_ and to_python conversions that store and lookup a handle to the associated python object. It doesn't completely work, because class_<> registers a to_python conversion for you. I'd love to have a generic mechanism where users could customize the object identity mapping. Perhaps something similar to get_pointer (set/get_object)? Ideally we could use this to remove some of the special-case shared_ptr code, and just provide a default implementation for shared_ptr. If this seems like a good idea, I'd be willing to work on this when I'm finished with the (*args, **kw) stuff. Something like this may be useful to help solve Ralf's problem. Actually, if one is willing to have an "invasive" handle to the python object stored in the c++ object, I think it's definitely solvable. Alex From rmf25 at cornell.edu Tue Mar 14 21:58:27 2006 From: rmf25 at cornell.edu (Rafael M. Frongillo) Date: Tue, 14 Mar 2006 15:58:27 -0500 Subject: [C++-sig] import problems with Boost.Python on Cygwin Message-ID: <5.2.1.1.2.20060314155623.0338dea0@postoffice6.mail.cornell.edu> > >I've got a Boost.Python project working fine on cygwin 1.5.18, python 2.4.1 > >(cygwin binary install), gcc 3.4.4. When I recently ran the cygwin setup.exe > >it automatically upgraded cygwin to 1.5.19, and now my project still > >compiles fine but when I import my module in Python's interactive shell, > >python silently returns to the shell prompt. No error, just exits. I rebuilt > >Boost.Python from source, but no difference. > >I reverted cygwin to 1.5.18, and it works fine again. > > > >Regards, > >Koen. > >When python crashed, it did so silently just as you described. Since I >also used the setup program to upgrade cygwin, I will try reverting cygwin >to 1.5.18 and see what happens... thanks for your response. > >Rafael It worked like a charm. Thanks, Koen, for saving my project! Rafael From abhi at qualcomm.com Fri Mar 17 23:46:14 2006 From: abhi at qualcomm.com (Abhi) Date: Fri, 17 Mar 2006 14:46:14 -0800 Subject: [C++-sig] Newbie Question about wrapping a function with int *, int & , etc... In-Reply-To: <7465b6170603100844o7d6cbd2o682b4a34c1c1de59@mail.gmail.com> References: <5FAA11166E69576AEFF3AFAD@10.30.7.179> <7465b6170603100844o7d6cbd2o682b4a34c1c1de59@mail.gmail.com> Message-ID: Dear Roman, Thanks for the wrapper code. It works great. > This was easy, right? So why "no"? Because there is no code generator that > supports this feature. I plan to add to pyplusplus such feature. You are > welcome to contribute: test cases or code. We are looking at py++. I will keep you posted. - Abhi --On Friday, March 10, 2006 8:44 PM +0400 Roman Yakovenko wrote: > On 3/10/06, Abhi wrote: >> I need to wrap the following class in python >> >> someclass.h >> >> class BasicTypesTest >> { >> // Pointer, Reference and const types >> >> // int* argument, int return >> int ptrIntArg_intRet(int* x); >> >> // int& argument, int return >> int refIntArg_intRet(int& x); >> >> // const int argument, int return >> int intConstArg_intRet(const int x); >> >> // const int* argument, int return >> int ptrIntConstArg_intRet(const int* x); >> >> // const int& argument, int return >> int refIntConstArg_intRet(const int& x); >> >> }; >> >> >> myboostpythonwrapper.cpp >> >> BOOST_PYTHON_MODULE (BoostPythonTest) >> { >> >> class_("BasicTypesTest") >> .def( init<>()) >> >> .def( "ptrIntArg_intRet", &BasicTypesTest::ptrIntArg_intRet ) >> .def( "refIntArg_intRet", &BasicTypesTest::refIntArg_intRet ) >> .def( "intConstArg_intRet", &BasicTypesTest::intConstArg_intRet ) >> .def( "ptrIntConstArg_intRet", >> &BasicTypesTest::ptrIntConstArg_intRet ) .def( >> "refIntConstArg_intRet", &BasicTypesTest::refIntConstArg_intRet ) ; >> } >> >> >> This does not work. >> For example if I try to do: >> >> import BoostPythonTest >> >> # Get the class >> b = BoostPythonTest.BasicTypesTest() >> >> x = 5; >> y = 5; >> >> # Call methods >> print "Calling C++ ptrIntArg_intRet" >> print "Argument x =", x >> b.ptrIntArg_intRet(x) <------------Error >> print "Argument x =", x >> print "---" >> >> >> Similarly for other methods. >> >> Is there an easy way to do this? > > Yes and no. Yes, because it very easy to write wrapper for such functions. > Something like this: > > boost::python::tuple refIntArg_intRet(BasicTypesTest& self, int x){ > int x_ref = x; > int result = self.refIntArg_intRet( ref_x ); > return boost::python::tuple( result, x ); > } > > def( "refIntArg_intRet", &::refIntArg_intRet ) > So, as you can see you can expose such functions. > > This was easy, right? So why "no"? Because there is no code generator that > supports this feature. I plan to add to pyplusplus such feature. You are > welcome to contribute: test cases or code. > >> thanks >> - Abhi > > Hope, I helped. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ From roman.yakovenko at gmail.com Sat Mar 18 07:22:24 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 18 Mar 2006 08:22:24 +0200 Subject: [C++-sig] Newbie Question about wrapping a function with int *, int & , etc... In-Reply-To: References: <5FAA11166E69576AEFF3AFAD@10.30.7.179> <7465b6170603100844o7d6cbd2o682b4a34c1c1de59@mail.gmail.com> Message-ID: <7465b6170603172222x21f0c8dam79aa37d3ff8e9b70@mail.gmail.com> On 3/18/06, Abhi wrote: > Dear Roman, > Thanks for the wrapper code. It works great. > > > This was easy, right? So why "no"? Because there is no code generator that > > supports this feature. I plan to add to pyplusplus such feature. You are > > welcome to contribute: test cases or code. > > We are looking at py++. I will keep you posted. Take a look on CVS. Now it is usable. Matthias and Allen did great job. Now it has very simple interface. > - Abhi -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From etienne.lachance at polymtl.ca Sat Mar 18 15:22:06 2006 From: etienne.lachance at polymtl.ca (Etienne Lachance) Date: Sat, 18 Mar 2006 09:22:06 -0500 Subject: [C++-sig] Questions when using std::vector. Message-ID: <1142691726.441c178e67d82@www.imp.polymtl.ca> Hi All, I have some problems using the vector_indexing_suite. The first one, I can't add elements to a container in python. The second one, I can't pass a container to a function in python. I look in the FAQ and in the mailing list archives, but I did not find my answers... Here is my code: void foo(std::vector& array) { for(std::size_t i=0;i >("std_vector_double") .def( vector_indexing_suite< std::vector >() ) ; } First problem: >>> vec = std_vector_double >>> vec.append(1.0) Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method Boost.Python.function object must be called with std_vector_double instance as first argument (got float instance instead) Second problem: >>> vec = std_vector_double >>> foo(vec) Traceback (most recent call last): File "", line 1, in ? Boost.Python.ArgumentError: Python argument types in pyGA.genome.foo(Boost.Python.class) did not match C++ signature: foo(std::vector > {lvalue}) Thanks in advance for the help. Etienne From rwgk at yahoo.com Sat Mar 18 15:42:30 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 18 Mar 2006 06:42:30 -0800 (PST) Subject: [C++-sig] Questions when using std::vector. In-Reply-To: <1142691726.441c178e67d82@www.imp.polymtl.ca> Message-ID: <20060318144230.8295.qmail@web31508.mail.mud.yahoo.com> --- Etienne Lachance wrote: > Here is my code: > > void foo(std::vector& array) > { > for(std::size_t i=0;i array[i] *= 2; > } > } > > BOOST_PYTHON_MODULE(genome) > { > class_ >("std_vector_double") > .def( vector_indexing_suite< std::vector >() ) Did you forget the .def for foo? > ; > } > > First problem: > > >>> vec = std_vector_double Here you forgot the (), i.e. this will most likely fix your problem: vec = std_vector_double() > >>> vec.append(1.0) > Traceback (most recent call last): > File "", line 1, in ? > TypeError: unbound method Boost.Python.function object must be called with > std_vector_double instance as first argument (got float instance instead) Note that this message tells you exactly what is wrong. In general the Boost.Python error messages are quite helpful. > Second problem: > > >>> vec = std_vector_double > >>> foo(vec) > Traceback (most recent call last): > File "", line 1, in ? > Boost.Python.ArgumentError: Python argument types in > pyGA.genome.foo(Boost.Python.class) > did not match C++ signature: > foo(std::vector > {lvalue}) Same here, you are passing a reference to a class, what you need is an instance of the class. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From ro4tub at gmail.com Sun Mar 19 12:12:10 2006 From: ro4tub at gmail.com (Raul) Date: Sun, 19 Mar 2006 19:12:10 +0800 Subject: [C++-sig] python call C++'s unicode functions? Message-ID: <9a77767b0603190312l5bcb8b23wa0a8fbf7e457e437@mail.gmail.com> void Foo(LPCWSTR str) { MessageBoxW(NULL,str,L"Info",MB_OK); } BOOST_PYTHON_MODULE(dxui) { def("Foo",Foo); } and i want to call the C++ function 'Foo' in the python scripts like that: #Python Scripts def Bar(): Foo(u"Hello World"); and then i call the Python Function 'Bar' in the C++ source file. but i don't know how to conver the python 'unicode' type to LPCWSTR (the same as const unsigned short *). -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Sun Mar 19 12:36:20 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 19 Mar 2006 13:36:20 +0200 Subject: [C++-sig] python call C++'s unicode functions? In-Reply-To: <9a77767b0603190312l5bcb8b23wa0a8fbf7e457e437@mail.gmail.com> References: <9a77767b0603190312l5bcb8b23wa0a8fbf7e457e437@mail.gmail.com> Message-ID: <7465b6170603190336i47af0960l3be744124845a027@mail.gmail.com> On 3/19/06, Raul wrote: > > void Foo(LPCWSTR str) > { > MessageBoxW(NULL,str,L"Info",MB_OK); > } > > BOOST_PYTHON_MODULE(dxui) > { > def("Foo",Foo); > } > > and i want to call the C++ function 'Foo' in the python scripts like that: > #Python Scripts > def Bar(): > Foo(u"Hello World"); > > and then i call the Python Function 'Bar' in the C++ source file. > > but i don't know how to conver the python 'unicode' type to LPCWSTR (the > same as > const unsigned short *). I see that you are already wrapping an other function. So may be you can use std::wstring? In this case it will work as is. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From ro4tub at gmail.com Sun Mar 19 13:51:15 2006 From: ro4tub at gmail.com (Raul) Date: Sun, 19 Mar 2006 20:51:15 +0800 Subject: [C++-sig] about std::wstring Message-ID: <9a77767b0603190451h5ddfc866nd987530fc462bf80@mail.gmail.com> Boost Version: 1.33.1 Compiler: VC7.1 OS: windows2000 sp4 when i write a c++ function: void Foo(std::wstring str) { wcout<,class std::allocator >) but in the 'initialize_builtin_converters'(builtin_converters.cpp) function,i called. # ifndef BOOST_NO_STD_WSTRING // Register by-value converters to std::string, std::wstring slot_rvalue_from_python(); # endif yeah, in my platform ,it doesn't define the macro 'BOOST_NO_STD_WSTRING', so what's wrong with it? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Mon Mar 20 20:35:10 2006 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 20 Mar 2006 11:35:10 -0800 Subject: [C++-sig] shared_ptr trouble References: <20060311114323.94268.qmail@web31508.mail.mud.yahoo.com> <44171180.5070208@pixar.com> Message-ID: Alex Mohr writes: >> Instead, it creates a >> new shared_ptr (with a whole new "control block" containing a >> use_count, weak_count and deleter) whose deleter manages a reference >> count on the owning Python object. That's the magic that allows >> Boost.Python to recover the original Python object when such a >> shared_ptr is converted back to Python. > > I've been meaning to post regarding this and my effort to make custom > smart pointers work as well as shared_ptr does with c++ <-> python > polymorphism. > > This "object identity" problem is the biggest issue. You can sort of > make it work with custom smart pointers by registering from_ and > to_python conversions that store and lookup a handle to the associated > python object. It doesn't completely work, because class_<> registers a > to_python conversion for you. > > I'd love to have a generic mechanism where users could customize the > object identity mapping. Perhaps something similar to get_pointer > (set/get_object)? Ideally we could use this to remove some of the > special-case shared_ptr code, and just provide a default implementation > for shared_ptr. That part can never work. One (desirable) feature of the shared_ptr handling code is that once converted from Python, the shared_ptr maintains a reference count on the /Python/ object, so it will never be destroyed as long as the shared_ptr exists, and you don't even need to use a special HeldType when wrapping those objects. You can't do that with every other smart pointer. > If this seems like a good idea, I'd be willing to work on this when I'm > finished with the (*args, **kw) stuff. > > Something like this may be useful to help solve Ralf's problem. > Actually, if one is willing to have an "invasive" handle to the python > object stored in the c++ object, I think it's definitely solvable. I don't know what you have in mind. -- Dave Abrahams Boost Consulting www.boost-consulting.com From amohr at pixar.com Mon Mar 20 22:14:25 2006 From: amohr at pixar.com (Alex Mohr) Date: Mon, 20 Mar 2006 13:14:25 -0800 Subject: [C++-sig] shared_ptr trouble In-Reply-To: References: <20060311114323.94268.qmail@web31508.mail.mud.yahoo.com> <44171180.5070208@pixar.com> Message-ID: <441F1B31.3030902@pixar.com> > That part can never work. One (desirable) feature of the shared_ptr > handling code is that once converted from Python, the shared_ptr > maintains a reference count on the /Python/ object, so it will never > be destroyed as long as the shared_ptr exists, and you don't even need > to use a special HeldType when wrapping those objects. You can't do > that with every other smart pointer. I understand that. But in my case I cannot use shared_ptr. We have our own custom smart pointers that use an intrusive mechanism. Something like: class MyObject : public SmartPtrBase {}; typedef SmartPtr MyObjectPtr; bp::class_("MyObject"); If you do this, object identity is not maintained -- a new python object is created each time a MyObjectPtr is returned to python. I want to make SmartPtrBase be able to keep a reference to 'self'. I want to have boost::python use it to maintain the c++ <-> python object identity once a MyObject has been converted from_python. If there was some way that I could tell boost::python how to store and look up a reference to self directly in my c++ object, that would be great. > I don't know what you have in mind. I haven't fully investigated things, but perhaps something specializable/overloadable that lets users customize storage and retrieval of a reference to self. Here's a guess: template<> struct self_association { static void store(MyObject *cpp, bp::handle<> const &self) { cpp->self_ = self; } static bp::handle<> retrieve(MyObject const *cpp) { return cpp->self_; } }; Perhaps there's no way to fully generalize this and remove the shared_ptr special-case stuff but regardless I'd love to have some way to make object identity work with custom smart pointer held types. That's been the most frustrating thing for us in adopting boost::python. Alex From jkankiewicz at advpubtech.com Tue Mar 21 00:37:36 2006 From: jkankiewicz at advpubtech.com (Jason Kankiewicz) Date: Mon, 20 Mar 2006 15:37:36 -0800 Subject: [C++-sig] about std::wstring In-Reply-To: <9a77767b0603190451h5ddfc866nd987530fc462bf80@mail.gmail.com> References: <9a77767b0603190451h5ddfc866nd987530fc462bf80@mail.gmail.com> Message-ID: Raul wrote: > Boost Version: 1.33.1 > Compiler: VC7.1 > OS: windows2000 sp4 > > when i write a c++ function: > void Foo(std::wstring str) > { > wcout< } > > Foo(u"hello world") > > the following is the error: > > Boost.Python.ArgumentError: Python argument types in > Foo(unicode) > did not match C++ signature: > Foo(class std::basic_string std::char_traits short>,class std::allocator >) Try setting the compiler option "/Zc:wchar_t" which will cause it to treat wchar_t as a distinct type instead of as an unsigned short. From Christophe.Gratin at adcis.net Tue Mar 21 17:54:30 2006 From: Christophe.Gratin at adcis.net (Chris) Date: Tue, 21 Mar 2006 17:54:30 +0100 Subject: [C++-sig] Problems with custom smart pointers and multiple inheritance Message-ID: I am trying to interface some of our classes, multiply inheriting from abstract classes, and for which we use our own smart pointer template. So far I've managed to write the code listed below, but I am facing the following problems: * my class member functions receive their parameter through smart pointers to base classes and not through standard C++ references, but only the PassARef(..) function call succeeds. PassAPointer causes the following runtime error: print c1.PassAPointer(c1) # fails Boost.Python.ArgumentError: Python argument types in MyBaseA.PassAPointer(MyClass, MyClass) did not match C++ signature: PassAPointer(class MyNamespace::MyBaseA {lvalue}, class MyNamespace::MyPointer) * I need to know the PyObject wrapping my C++ class instance, but the "class syntax #2" invoking the constructor taking a PyObject as parameter works even worse. * The Python object returned by 'GetBaseA()' is not the same as the calling Python object although they are actually referencing the same C++ class instance. Is there any way to avoid this ? (this is not the biggest of my problems though) Chris. ------- namespace MyNamespace { class MyBaseA { public: virtual std::string PassARef(MyBaseA& value) = 0; virtual std::string PassAPointer(MyPointer value) = 0; virtual MyPointer GetBaseA() = 0; }; class MyBaseB { public: virtual std::string PassBRef(MyBaseB& value) = 0; }; class MyClass: public MyBaseA, public MyBaseB { private: PyObject* m_pyObject; public: std::string PassARef(MyBaseA& value) { return (boost::format("PassARef - %1%") % int(this)).str(); } std::string PassAPointer(MyPointer value) { return (boost::format("PassAPointer - %1%") % int(this)).str(); } MyPointer GetBaseA() { return MyPointer(this); } std::string PassBRef(MyBaseB& value) { return (boost::format("PassBRef - %1%") % int(this)).str(); } MyClass() { } MyClass(PyObject* pyObject): m_pyObject(pyObject) { } static MyPointer New() { // No way to know the 'PyObject' is this case return MyPointer(new MyClass()); } }; } namespace boost { namespace python { template struct pointee > { typedef T type; }; template inline T * get_pointer(MyNamespace::MyPointer const & p) { return p.get(); } }} using namespace MyNamespace; BOOST_PYTHON_MODULE(MyModule) { class_("MyBaseA", no_init) .def("PassARef", &MyBaseA::PassARef) .def("PassAPointer", &MyBaseA::PassAPointer) .def("GetBaseA", &MyBaseA::GetBaseA) ; class_("MyBaseB", no_init) .def("PassBRef", &MyBaseB::PassBRef) ; // class_ syntax #1 class_ >("MyClass", no_init) .def("__init__", make_constructor(MyClass::New)) ; // class_ syntax #2 //class_ >("MyClass", init<>()) //; register_ptr_to_python >(); register_ptr_to_python >(); register_ptr_to_python >(); } # Python test code c1 = MyModule.MyClass() print c1 print c1.PassARef(c1) print c1.PassAPointer(c1) # fails print c1.PassBRef(c1) c2 = c1.GetBaseA() print c2 # c2 is not the same Python object as c1 print c2.PassARef(c1) # but they point to the same C++ instance From amohr at pixar.com Tue Mar 21 18:55:55 2006 From: amohr at pixar.com (Alex Mohr) Date: Tue, 21 Mar 2006 09:55:55 -0800 Subject: [C++-sig] Problems with custom smart pointers and multiple inheritance In-Reply-To: References: Message-ID: <44203E2B.2030707@pixar.com> > print c1.PassAPointer(c1) # fails > Boost.Python.ArgumentError: Python argument types in > MyBaseA.PassAPointer(MyClass, MyClass) did not match C++ signature: > PassAPointer(class MyNamespace::MyBaseA {lvalue}, class > MyNamespace::MyPointer) Have you tried using MyPointer as the held types? That is: class_, boost::noncopyable> class_, boost::noncopyable> class_, boost::noncopyable, bases<...> > Then you shouldn't need register_ptr_to_python (only when you get to polymorphism and the classes you are wrapping are really wrapper). > * I need to know the PyObject wrapping my C++ class instance, but the > "class syntax #2" invoking the constructor taking a PyObject as > parameter works even worse. If you read the docs for class_ where it talks about HeldType semantics, you'll see info regarding 'has_back_reference'. That may work for you. > * The Python object returned by 'GetBaseA()' is not the same as the > calling Python object although they are actually referencing the same > C++ class instance. Is there any way to avoid this ? (this is not the > biggest of my problems though) If you use boost::shared_ptr, it sort of works. With any other smart pointer you can't really do it as far as I know. There's some ongoing discussion about this. I would like to fix it. By the way, injecting constructors via make_constructor is not going to work for you if/when you try to expose these classes as polymorphic to python. This is because make_constructor doesn't seem to cause boost::python::detail::initialize_wrapper() to be called. Seems like it maybe could/should. I've cobbled together my own make_constructor in order to work around this, so if you run into that, perhaps I can help. Alex From matt at thenashgroup.net Tue Mar 21 19:11:00 2006 From: matt at thenashgroup.net (Matt Carpenter) Date: Tue, 21 Mar 2006 10:11:00 -0800 Subject: [C++-sig] Satellite Systems Engineer in Southern California Message-ID: <20060321181120.BIMQ25099.fed1rmmtao09.cox.net@Mat> My name is Matt Carpenter and I manage a recruiting company in San Diego California. One of my most impressive clients in Southern California is looking for a Satellite Systems Engineer. The position requires and advanced understanding of satellite imaging and a proven track record of innovation. The job highlights are below and my motivation is a 12 on a scale from 1-10! I was wondering if you might know any qualified candidates you could refer to me? Please contact me or have them contact me ASAP at matt at thenashgroup.net Or reply to my e-mail. Experience should include writing plans and test procedures for large-scale engineering systems incorporating requirement analysis and high level design documentation. 6-10 years experience in large development projects; or satellite ground station projects. Experience with satellite remote sensing or imaging systems development preferred. Proven experience using formal system engineering methodologies for requirements, analysis, design, integration and testing. University degree in Applied Sciences / Engineering or Computer Science. Generic/extensible programming techniques in Python or other dynamic languages. A working knowledge of GNU Command-line tools (sed, awk, xargs, grep, .. etc). Thanks in advance, Matt Carpenter The Nash Group 619.851.2614 -------------- next part -------------- An HTML attachment was scrubbed... URL: From beau at open-source-staffing.com Tue Mar 21 23:56:51 2006 From: beau at open-source-staffing.com (Beau Gould) Date: Tue, 21 Mar 2006 17:56:51 -0500 Subject: [C++-sig] [JOB] Python/C++ Developer, Greenwich, CT | 80-160k | Relo/H1B OK Message-ID: <008b01c64d3a$be83fa00$0a02a8c0@superioss.com> Python/C++ Developer, Greenwich, CT | 80-160k | Relo/H1B OK Client will pay full relocation expenses. My Greenwich, CT client is looking for programmers fluent in Python and C++ to build and improve systems in a variety of areas, including mathematical programming, parallel computing, network servers, and user interfaces. They are a relatively small, but rapidly growing company offering opportunity for growth and creativity in a resource-rich environment. Requirements: * Strong experience in Python and C++ * Financial programming experience a plus All candidates will be considered (H1, H1B, Canadian, etc) but you must currently be residing in the USA or Canada. No oversea relocations. If you are interested in this position and are 100% ready to move to Greenwich, CT, please submit your resume, a paragraph or cover letter highlighting your C++ and Python experience and your salary requirements to beau at open-source-staffing.com Thank you, Beau J. Gould Open Source Staffing beau at open-source-staffing.com www.open-source-staffing.com Other Python and/or Zope positions posted here: http://groups.yahoo.com/group/pythonzopejobs -- No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.1.385 / Virus Database: 268.2.6/286 - Release Date: 3/20/2006 From Christophe.Gratin at adcis.net Wed Mar 22 13:59:42 2006 From: Christophe.Gratin at adcis.net (Chris) Date: Wed, 22 Mar 2006 13:59:42 +0100 Subject: [C++-sig] Problems with custom smart pointers and multiple inheritance In-Reply-To: <44203E2B.2030707@pixar.com> References: <44203E2B.2030707@pixar.com> Message-ID: Thanks for your answer > If you use boost::shared_ptr, it sort of works. With any other smart > pointer you can't really do it as far as I know. There's some ongoing > discussion about this. I would like to fix it. This could be a solution, but will it still work if I define MyPointer as a class derived from shared_ptr. That's what I am eventually trying to do, but I still can't call my PassAPointer() function. I get the following runtime error (my source code is pasted below): print c1.PassAPointer(c1) # fails Boost.Python.ArgumentError: Python argument types in MyBaseA.PassAPointer(MyClass, MyClass) did not match C++ signature: PassAPointer(class MyNamespace::MyBaseA {lvalue}, class MyNamespace::MyPointer) Note that it works perfectly if I simply "#define MyPointer shared_ptr" instead of using my derived template class. I guess there is surely something simple to add to make it work. At least I hope so. Chris. ----------- namespace MyNamespace { #ifdef USE_DERIVED template class MyPointer: public shared_ptr { public: template explicit MyPointer(Y* p): shared_ptr(p) {} template MyPointer(const shared_ptr& p): shared_ptr(p) {} MyPointer() {} }; #else #define MyPointer shared_ptr #endif class MyBaseA { public: typedef MyPointer Ptr; virtual std::string PassAPointer(MyBaseA::Ptr value) = 0; }; class MyBaseB { public: typedef MyPointer Ptr; virtual std::string PassBPointer(MyBaseB::Ptr value) = 0; }; class MyClass: public MyBaseA, public MyBaseB { public: typedef MyPointer Ptr; std::string PassAPointer(MyBaseA::Ptr value) { return (boost::format("PassAPointer - %1%") % int(this)).str(); } std::string PassBPointer(MyBaseB::Ptr value) { return (boost::format("PassBPointer - %1%") % int(this)).str(); } }; } using namespace MyNamespace; BOOST_PYTHON_MODULE(MyModule) { class_("MyBaseA", no_init) .def("PassAPointer", &MyBaseA::PassAPointer) ; class_("MyBaseB", no_init) .def("PassBPointer", &MyBaseB::PassBPointer) ; class_ >("MyClass", init<>()) ; } Python test code c1 = MyModule.MyClass() print c1.PassAPointer(c1) # fails From baas at ira.uka.de Wed Mar 22 14:29:45 2006 From: baas at ira.uka.de (Matthias Baas) Date: Wed, 22 Mar 2006 14:29:45 +0100 Subject: [C++-sig] Providing a default value for a pointer argument Message-ID: Hi, I have a question about the "arg" class which can be used to provide names for keyword arguments and their default values. Should this default value also be taken into account for arguments that are actually pointers? I have a function that takes a pointer as input whose default value in C is 0. When I wrap that function I provide the default value as arg("...")=0. I get no error when compiling such a module but the default value seems to be ignored and I must specify an argument explicitly (whereas I would have expected the default value to be None). So is this a bug or just normal behavior? Below is a sample module that shows the problem. In this example it should be possible to call ptrarg() without any arguments, but when I do this I get the following error: Boost.Python.ArgumentError: Python argument types in mod.ptrarg() did not match C++ signature: ptrarg(class Spam * s=0) Well, I do know how I can rewrite the module so that it does what I want (using thin wrappers, BOOST_PYTHON_FUNCTION_OVERLOADS, etc), I just thought I ask anyway because using "arg" would be rather convenient and maybe this is a bug in Boost.Python (as it also doesn't generate an error)... - Matthias - // Sample program: #include using namespace boost::python; class Spam { }; int ptrarg(Spam* s=0) { if (s==0) return 0; else return 1; } BOOST_PYTHON_MODULE(mod) { class_("Spam", init<>()); def("ptrarg", ptrarg, (arg("s")=0)); } From rwgk at yahoo.com Wed Mar 22 15:24:14 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 22 Mar 2006 06:24:14 -0800 (PST) Subject: [C++-sig] Providing a default value for a pointer argument In-Reply-To: Message-ID: <20060322142414.19291.qmail@web31501.mail.mud.yahoo.com> --- Matthias Baas wrote: > int ptrarg(Spam* s=0) > { > if (s==0) > return 0; > else > return 1; > } > > BOOST_PYTHON_MODULE(mod) > { > class_("Spam", init<>()); > > def("ptrarg", ptrarg, (arg("s")=0)); > } You are missing BOOST_PYTHON_FUNCTION_OVERLOADS for ptrarg: http://www.boost.org/libs/python/doc/v2/overloads.html I am not sure if the =0 works for pointers, but the overloads trick is definitely required. Cheers, Ralf __________________________________________________ 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 Mar 22 15:41:46 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 22 Mar 2006 16:41:46 +0200 Subject: [C++-sig] Providing a default value for a pointer argument In-Reply-To: <20060322142414.19291.qmail@web31501.mail.mud.yahoo.com> References: <20060322142414.19291.qmail@web31501.mail.mud.yahoo.com> Message-ID: <7465b6170603220641w6d5f140aj393c35c855fbfd40@mail.gmail.com> On 3/22/06, Ralf W. Grosse-Kunstleve wrote: > --- Matthias Baas wrote: > > int ptrarg(Spam* s=0) > > { > > if (s==0) > > return 0; > > else > > return 1; > > } > > > > BOOST_PYTHON_MODULE(mod) > > { > > class_("Spam", init<>()); > > > > def("ptrarg", ptrarg, (arg("s")=0)); > > } > > You are missing BOOST_PYTHON_FUNCTION_OVERLOADS for ptrarg: > > http://www.boost.org/libs/python/doc/v2/overloads.html > > I am not sure if the =0 works for pointers, but the overloads trick is > definitely required. What should happen if I have an other function that takes as argument an other type? int ptrarg(Spam* s=0) {...} int ptrarg(int){...} int ptrarg(int, Spam*){...} int ptrarg(Spam*, int){...} > Cheers, > Ralf Thanks -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From rwgk at yahoo.com Wed Mar 22 16:05:56 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 22 Mar 2006 07:05:56 -0800 (PST) Subject: [C++-sig] Providing a default value for a pointer argument In-Reply-To: <7465b6170603220641w6d5f140aj393c35c855fbfd40@mail.gmail.com> Message-ID: <20060322150556.19810.qmail@web31513.mail.mud.yahoo.com> --- Roman Yakovenko wrote: > int ptrarg(Spam* s=0) {...} > int ptrarg(int){...} > int ptrarg(int, Spam*){...} > int ptrarg(Spam*, int){...} You have to fiddle around with casts. It is not pretty, but does the trick. However, if it gets too complicated I prefer to use simple thin wrappers, e.g.: int ptrarg_spam_0() { return ptarg(); } int ptrarg_spam_1(Spam* s) { return ptrarg(s); } int ptrarg_int(int i) { return ptrarg(i); } int ptrarg_int_spam(int i, Spam* s) { return ptarg(i, s); } int ptrarg_int_spam(Spam* s, int i) { return ptarg(s, i); } def("ptarg", ptrarg_spam_0); def("ptarg", ptrarg_spam_1); def("ptarg", ptrarg_int); def("ptarg", ptrarg_int_spam); def("ptarg", ptrarg_spam_int); Cheers, Ralf __________________________________________________ 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 Mar 22 16:14:57 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 22 Mar 2006 17:14:57 +0200 Subject: [C++-sig] Providing a default value for a pointer argument In-Reply-To: <20060322150556.19810.qmail@web31513.mail.mud.yahoo.com> References: <7465b6170603220641w6d5f140aj393c35c855fbfd40@mail.gmail.com> <20060322150556.19810.qmail@web31513.mail.mud.yahoo.com> Message-ID: <7465b6170603220714r7e628b40r996527d3441e98e8@mail.gmail.com> On 3/22/06, Ralf W. Grosse-Kunstleve wrote: > --- Roman Yakovenko wrote: > > int ptrarg(Spam* s=0) {...} > > int ptrarg(int){...} > > int ptrarg(int, Spam*){...} > > int ptrarg(Spam*, int){...} > > You have to fiddle around with casts. It is not pretty, but does the trick. > However, if it gets too complicated I prefer to use simple thin wrappers, e.g.: > > int ptrarg_spam_0() { return ptarg(); } > int ptrarg_spam_1(Spam* s) { return ptrarg(s); } > int ptrarg_int(int i) { return ptrarg(i); } > int ptrarg_int_spam(int i, Spam* s) { return ptarg(i, s); } > int ptrarg_int_spam(Spam* s, int i) { return ptarg(s, i); } > > def("ptarg", ptrarg_spam_0); > def("ptarg", ptrarg_spam_1); > def("ptarg", ptrarg_int); > def("ptarg", ptrarg_int_spam); > def("ptarg", ptrarg_spam_int); Thanks. This is something I can understand. An other question: boost.python have optional class, that we use for constructors ( init ) . >From documentation I understand that I can not use optional for regular "def"'s, right? Except of "luck of time", is there is an other reason (==technical) for not supporting optional on "def"'s > Cheers, > Ralf Thank you -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Wed Mar 22 16:14:57 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 22 Mar 2006 17:14:57 +0200 Subject: [C++-sig] Providing a default value for a pointer argument In-Reply-To: <20060322150556.19810.qmail@web31513.mail.mud.yahoo.com> References: <7465b6170603220641w6d5f140aj393c35c855fbfd40@mail.gmail.com> <20060322150556.19810.qmail@web31513.mail.mud.yahoo.com> Message-ID: <7465b6170603220714r7e628b40r996527d3441e98e8@mail.gmail.com> On 3/22/06, Ralf W. Grosse-Kunstleve wrote: > --- Roman Yakovenko wrote: > > int ptrarg(Spam* s=0) {...} > > int ptrarg(int){...} > > int ptrarg(int, Spam*){...} > > int ptrarg(Spam*, int){...} > > You have to fiddle around with casts. It is not pretty, but does the trick. > However, if it gets too complicated I prefer to use simple thin wrappers, e.g.: > > int ptrarg_spam_0() { return ptarg(); } > int ptrarg_spam_1(Spam* s) { return ptrarg(s); } > int ptrarg_int(int i) { return ptrarg(i); } > int ptrarg_int_spam(int i, Spam* s) { return ptarg(i, s); } > int ptrarg_int_spam(Spam* s, int i) { return ptarg(s, i); } > > def("ptarg", ptrarg_spam_0); > def("ptarg", ptrarg_spam_1); > def("ptarg", ptrarg_int); > def("ptarg", ptrarg_int_spam); > def("ptarg", ptrarg_spam_int); Thanks. This is something I can understand. An other question: boost.python have optional class, that we use for constructors ( init ) . >From documentation I understand that I can not use optional for regular "def"'s, right? Except of "luck of time", is there is an other reason (==technical) for not supporting optional on "def"'s > Cheers, > Ralf Thank you -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From dave at boost-consulting.com Wed Mar 22 16:16:46 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 22 Mar 2006 07:16:46 -0800 Subject: [C++-sig] Providing a default value for a pointer argument References: Message-ID: Matthias Baas writes: > Hi, > > I have a question about the "arg" class which can be used to provide > names for keyword arguments and their default values. Should this > default value also be taken into account for arguments that are actually > pointers? > I have a function that takes a pointer as input whose default value in C > is 0. When I wrap that function I provide the default value as > arg("...")=0. Try arg("...") = object() object() produces a None, and None is the canonical object that's convertible to NULL pointers. -- Dave Abrahams Boost Consulting www.boost-consulting.com From baas at ira.uka.de Wed Mar 22 18:07:57 2006 From: baas at ira.uka.de (Matthias Baas) Date: Wed, 22 Mar 2006 18:07:57 +0100 Subject: [C++-sig] Providing a default value for a pointer argument In-Reply-To: References: Message-ID: David Abrahams wrote: >> I have a function that takes a pointer as input whose default value in C >> is 0. When I wrap that function I provide the default value as >> arg("...")=0. > > Try > > arg("...") = object() > > object() produces a None, and None is the canonical object that's > convertible to NULL pointers. Ah, that makes sense and it works, too. Thanks! - Matthias - From rwgk at yahoo.com Wed Mar 22 18:16:14 2006 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 22 Mar 2006 09:16:14 -0800 (PST) Subject: [C++-sig] Providing a default value for a pointer argument In-Reply-To: <7465b6170603220714r7e628b40r996527d3441e98e8@mail.gmail.com> Message-ID: <20060322171614.46024.qmail@web31503.mail.mud.yahoo.com> --- Roman Yakovenko wrote: > Except of "luck of time", is there is an other reason (==technical) for not > supporting optional on "def"'s Interesting viewpoint. But note that you normally don't have to enumerate the function argument types when .def'ing a function. That's unavoidable only for constructors. I guess if you want to enable optional<> for functions it would have to be embedded in some kind of equivalent of init<>, maybe def("foo", signature >()) Even if this is technically possible (?) it wouldn't buy you all that much compared to a combination of type cast and BOOST_FUNCTION_OVERLOADS, and in practice there are probably not many situations where the signature<> approach is necessary/useful. Cheers, Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From amohr at pixar.com Wed Mar 22 19:10:44 2006 From: amohr at pixar.com (Alex Mohr) Date: Wed, 22 Mar 2006 10:10:44 -0800 Subject: [C++-sig] Problems with custom smart pointers and multiple inheritance In-Reply-To: References: <44203E2B.2030707@pixar.com> Message-ID: <44219324.2030704@pixar.com> Ahh yes, I forgot -- I think you also need to register your own from_python conversion. This is bascially the code I use (basically copied from boost python -- used for shared_ptr from_python conversions, I think). template