From kloeckner at RTNA.DaimlerChrysler.COM Fri Nov 1 01:28:53 2002 From: kloeckner at RTNA.DaimlerChrysler.COM (kloeckner at RTNA.DaimlerChrysler.COM) Date: Fri, 1 Nov 2002 00:28:53 GMT Subject: [C++-sig] boost.python 2 exception handling Message-ID: <200210312311.g9VNBf8k001740@sunmail.RTNA.DaimlerChrysler.COM> hi, i'm trying to install my own custom exception translator (with Boost.Python from the Boost 1.29.0 release, gcc-3.2 (GCC) 3.2.1 20021020 (Debian prerelease) and Python 2.2.2), and my tries are not working out. I'm doing it like this: ---------------------------------------------------------------- #include #include #include using namespace boost::python; using namespace std; void TranslateRTE( const runtime_error &ex ) { PyErr_SetString( PyExc_RuntimeError, ex.what() ); } BOOST_PYTHON_MODULE(mapster) { register_exception_translator( TranslateRTE ); } ---------------------------------------------------------------- and I'm getting a way lengthy response from the compiler... ---------------------------------------------------------------- kloeckner at crunch:~/mapster/cvs/edmap_ng/src$ jam ..found 851 target(s)... ..updating 2 target(s)... C++ shell/mapster.o In file included from /home/kloeckner/boost_1_29_0/boost/python.hpp:43, from shell/mapster.cpp:59: /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:184:42: warning: pasting "operator" and "+" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:185:42: warning: pasting "operator" and "-" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:186:42: warning: pasting "operator" and "*" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:187:42: warning: pasting "operator" and "/" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:188:42: warning: pasting "operator" and "%" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:189:49: warning: pasting "operator" and "<<" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:190:49: warning: pasting "operator" and ">>" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:191:42: warning: pasting "operator" and "&" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:192:42: warning: pasting "operator" and "^" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:193:40: warning: pasting "operator" and "|" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:194:39: warning: pasting "operator" and ">" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:195:40: warning: pasting "operator" and ">=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:196:39: warning: pasting "operator" and "<" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:197:40: warning: pasting "operator" and "<=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:198:40: warning: pasting "operator" and "==" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:199:40: warning: pasting "operator" and "!=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:271:38: warning: pasting "operator" and "+=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:272:38: warning: pasting "operator" and "-=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:273:38: warning: pasting "operator" and "*=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:274:38: warning: pasting "operator" and "/=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:275:38: warning: pasting "operator" and "%=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:276:42: warning: pasting "operator" and "<<=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:277:42: warning: pasting "operator" and ">>=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:278:38: warning: pasting "operator" and "&=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:279:38: warning: pasting "operator" and "^=" does not give a valid preprocessing token /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:280:37: warning: pasting "operator" and "|=" does not give a valid preprocessing token In file included from shell/mapster.cpp:59: /home/kloeckner/boost_1_29_0/boost/python.hpp:62:8: warning: extra tokens at end of #endif directive /home/kloeckner/boost_1_29_0/boost/bind.hpp: In member function `R boost::_bi::list3::operator()(boost::_bi::type, F, A&) const [with R = bool, F = boost::python::detail::translate_exception, A = boost::_bi::list2 >&>, A1 = boost::arg<1>, A2 = boost::arg<2>, A3 = boost::_bi::value]': /home/kloeckner/boost_1_29_0/boost/function/function_template.hpp:44: instantiated from `boost::_bi::result_traits::type boost::_bi::bind_t::operator()(A1&, A2&) [with A1 = const boost::python::detail::exception_handler, A2 = const boost::function0 >, R = bool, F = boost::python::detail::translate_exception, L = boost::_bi::list3, boost::arg<2>, boost::_bi::value >]' /home/kloeckner/boost_1_29_0/boost/function/function_template.hpp:110: instantiated from `static R boost::detail::function::function_obj_invoker2::invoke(boost::detail::function::any_pointer, T0, T1) [with FunctionObj = boost::_bi::bind_t, boost::_bi::list3, boost::arg<2>, boost::_bi::value > >, R = bool, T0 = const boost::python::detail::exception_handler&, T1 = const boost::function0 >&]' /home/kloeckner/boost_1_29_0/boost/function/function_template.hpp:505: instantiated from `void boost::function2::assign_to(FunctionObj, boost::detail::function::function_obj_tag) [with FunctionObj = boost::_bi::bind_t, boost::_bi::list3, boost::arg<2>, boost::_bi::value > >, R = bool, T0 = const boost::python::detail::exception_handler&, T1 = const boost::function0 >&, Policy = boost::empty_function_policy, Mixin = boost::empty_function_mixin, Allocator = std::allocator]' /home/kloeckner/boost_1_29_0/boost/python/exception_translator.hpp:456: instantiated from `void boost::function2::assign_to(Functor) [with Functor = boost::_bi::bind_t, boost::_bi::list3, boost::arg<2>, boost::_bi::value > >, R = bool, T0 = const boost::python::detail::exception_handler&, T1 = const boost::function0 >&, Policy = boost::empty_function_policy, Mixin = boost::empty_function_mixin, Allocator = std::allocator]' /home/kloeckner/boost_1_29_0/boost/python/exception_translator.hpp:296: instantiated from `boost::function2::function2(Functor) [with Functor = boost::_bi::bind_t, boost::_bi::list3, boost::arg<2>, boost::_bi::value > >, R = bool, T0 = const boost::python::detail::exception_handler&, T1 = const boost::function0 >&, Policy = boost::empty_function_policy, Mixin = boost::empty_function_mixin, Allocator = std::allocator]' /home/kloeckner/boost_1_29_0/boost/python/exception_translator.hpp:18: instantiated from `void boost::python::register_exception_translator(const Translate&, boost::type*) [with ExceptionType = std::runtime_error, Translate = void ()(const std::runtime_error&)]' shell/mapster.cpp:72: instantiated from here /home/kloeckner/boost_1_29_0/boost/bind.hpp:285: no match for call to `( boost::python::detail::translate_exception) (const boost::python::detail::exception_handler&, const boost::function0 >&, void (* const&)(const std::runtime_error&))' /home/kloeckner/boost_1_29_0/boost/python/detail/translate_exception.hpp:30: candidates are: bool boost::python::detail::translate_exception::operator()(const boost::python::detail::exception_handler&, const boost::function0 >&, boost::call_traits::param_type) const [with ExceptionType = std::runtime_error, Translate = void ()(const std::runtime_error&)] g++-3.2 -c -o shell/mapster.o -g -pthread -fPIC -O -D_GNU_SOURCE -DOTL_ODBC -DOTL_ODBC_UNIX -DOTL_STL -Ishell -I. -I/usr/include/python2.2 -I. -I/home/kloeckner/boost_1_29_0 shell/mapster.cpp ..failed C++ shell/mapster.o ... ..skipped mapster.so for lack of mapster.o... ..failed updating 1 target(s)... ..skipped 1 target(s)... ---------------------------------------------------------------- Any help is appreciated. Thanks -- Andreas From dave at boost-consulting.com Sat Nov 2 03:45:17 2002 From: dave at boost-consulting.com (David Abrahams) Date: 01 Nov 2002 21:45:17 -0500 Subject: [C++-sig] boost.python coredump in debug mode..? In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E20192017743CC@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E20192017743CC@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: > > From: David Abrahams [mailto:dave at boost-consulting.com] > > > > "Bjorn Pettersen" writes: > > > > > > From: David Abrahams [mailto:dave at boost-consulting.com] > > > > > > > > "Bjorn Pettersen" writes: > > > > > > I must be dense because I still can't get it to work. I included > > > at the top of my file, > > > defined _DEBUG, and linked with either boost_python.lib or > > > boost_python_debug.lib and I'm always getting the coredump. I'm > > > sure I'm missing something obvious.... > > > > What was the test case again? > > >>> import hello > >>> x = hello.World('hi') > >>> hello.World('hi') # this call... > > >>> x.greet() # ... causes this to coredump > > with the code at > http://www.boost.org/libs/python/doc/tutorial/doc/constructors.html I don't know what you're doing wrong, but if you drop the enclosed files into $BOOST_ROOT/libs/python/user and build with bjam, the it checks out fine in both vc6 and vc7 with the current boost CVS state. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Jamfile URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.py URL: -------------- next part -------------- -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From BPettersen at NAREX.com Sat Nov 2 17:26:53 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Sat, 2 Nov 2002 09:26:53 -0700 Subject: [C++-sig] boost.python coredump in debug mode..? Message-ID: <60FB8BB7F0EFC7409B75EEEC13E20192017744AF@admin56.narex.com> > From: David Abrahams [mailto:dave at boost-consulting.com] > > "Bjorn Pettersen" writes: > > > > From: David Abrahams [mailto:dave at boost-consulting.com] > > > > > > "Bjorn Pettersen" writes: > > > > > > > > From: David Abrahams [mailto:dave at boost-consulting.com] > > > > > > > > > > "Bjorn Pettersen" writes: > > > > > > > > I must be dense because I still can't get it to work. I > > > > included > > > > at the top of my file, > > > > defined _DEBUG, and linked with either boost_python.lib or > > > > boost_python_debug.lib and I'm always getting the > > > > coredump. I'm > > > > sure I'm missing something obvious.... > > > > > > What was the test case again? > > > > >>> import hello > > >>> x = hello.World('hi') > > >>> hello.World('hi') # this call... > > > > >>> x.greet() # ... causes this to coredump > > > > with the code at > > http://www.boost.org/libs/python/doc/tutorial/doc/constructors.html > > I don't know what you're doing wrong, but if you drop the > enclosed files into $BOOST_ROOT/libs/python/user and build > with bjam, the it checks out fine in both vc6 and vc7 with > the current boost CVS state. Thanks for taking so much time in checking this out. This made it possible for me to track down the differences (I have to build my project outside of the Boost hierarchy, and anything but .dsp files would meet resistance here *sigh*). The culprit was using the default /MTd (dbg. static rt) instead of the correct /MDd (debug dll rt) -- I really should know to check this first by now . There are several other interesting, and some not so interesting, differences from a default .dll workspace: bjam additions: /Ob0 disable inlining (faulty optimizer? -- potentially important) /GR enable RTTI /Z7 enable old style debug info (?) default .dll workspace switches not in the bjam invocation: /GZ Enable runtime debug checking (at least it sounds potentially useful ) A smattering of other (theoretically) semantically unimportant switches: /W3 Warning level 3, /Gm Enable minimal rebuild, /FD PDB file, ... Is this worth filing as a documentation issue, if you think it is I'll write it up fully (would subscribing to and sending it to the Boost developers list be the right place to submit it?) While doing this, I also noticed that bjam was trying to call the wrong vcvars32.bat file, it's trying to find it in: CALL "C:\Program Files\Microsoft Visual C++\VC98\bin\VCVARS32.BAT" >nul (and dropping the error on the floor/nul). If you have the full visual studio, however, vcvars32.bat is in: c:\Program Files\Microsoft Visual Studio\VC98\bin\vcvars32.bat (got to love MS consistency :-) For Visual Studio.NET (vc7), bjam calls the correct file for Visual Studio (I don't have a standalone Visual C++, so I can't try that here...) Should I send this to the same mailing list as above? Thanks again for spending so much time on something I really should have been able to figure out myself. Gives me a warm and fuzzy feeling when I can get persistent help with something like this though. Oh, and thanks for such a great library (used to think I was a pretty good C++ programmer, even went to the ISO meeting in Dublin for my last job, but I'll definitely have to take a second look before I understand what's going on on the inside ;-) -- bjorn Bjorn Pettersen Software Architect NAREX, Inc. (http://www.narex.com) 303.526.4000 ext. 312 303.526.5130 fax From dave at boost-consulting.com Sun Nov 3 15:51:48 2002 From: dave at boost-consulting.com (David Abrahams) Date: 03 Nov 2002 09:51:48 -0500 Subject: [C++-sig] boost.python coredump in debug mode..? In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E20192017744AF@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E20192017744AF@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: > There are several > other interesting, and some not so interesting, differences from a > default .dll workspace: > > bjam additions: > /Ob0 disable inlining (faulty optimizer? -- potentially important) This is just the way we do our debug builds. If you build a release version inlining will be fully enabled. > /GR enable RTTI > /Z7 enable old style debug info (?) You can choose Program Database debug info by adding database to your BUILD variable. > default .dll workspace switches not in the bjam invocation: > /GZ Enable runtime debug checking (at least it sounds potentially > useful ) Not sure whether this would work or not, but you can always try adding -GZ to the BUILD, to see what happens. > A smattering of other (theoretically) semantically unimportant > switches: > /W3 Warning level 3, /Gm Enable minimal rebuild, /FD PDB file, ... The incremental stuff is notoriously buggy... > Is this worth filing as a documentation issue, if you think it is > I'll write it up fully (would subscribing to and sending it to the > Boost developers list be the right place to submit it?) Why don't you submit a documentation patch to this list? > While doing this, I also noticed that bjam was trying to call the wrong > vcvars32.bat file, it's trying to find it in: > > CALL "C:\Program Files\Microsoft Visual C++\VC98\bin\VCVARS32.BAT" > >nul > > (and dropping the error on the floor/nul). If you have the full visual > studio, however, vcvars32.bat is in: > > c:\Program Files\Microsoft Visual Studio\VC98\bin\vcvars32.bat > > (got to love MS consistency :-) For Visual Studio.NET (vc7), bjam calls > the correct file for Visual Studio (I don't have a standalone Visual > C++, so I can't try that here...) > > Should I send this to the same mailing list as above? No, the jamboost list: jamboost at yahoogroups.com. > Thanks again for spending so much time on something I really should > have been able to figure out myself. Gives me a warm and fuzzy > feeling when I can get persistent help with something like this > though. > > Oh, and thanks for such a great library (used to think I was a > pretty good C++ programmer, even went to the ISO meeting in Dublin > for my last job, but I'll definitely have to take a second look > before I understand what's going on on the inside ;-) That might be my fault ;-) I need to make the implementation documentation available. I'm working on it... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Sun Nov 3 18:24:06 2002 From: dave at boost-consulting.com (David Abrahams) Date: 03 Nov 2002 12:24:06 -0500 Subject: [C++-sig] boost.python 2 exception handling In-Reply-To: <200210312311.g9VNBf8k001740@sunmail.RTNA.DaimlerChrysler.COM> References: <200210312311.g9VNBf8k001740@sunmail.RTNA.DaimlerChrysler.COM> Message-ID: kloeckner at RTNA.DaimlerChrysler.COM writes: > hi, > > i'm trying to install my own custom exception translator (with Boost.Python from > the Boost 1.29.0 release, gcc-3.2 (GCC) 3.2.1 20021020 (Debian prerelease) and > Python 2.2.2), and my tries are not working out. > > I'm doing it like this: > > ---------------------------------------------------------------- > #include > #include > #include > > using namespace boost::python; > using namespace std; > > void TranslateRTE( const runtime_error &ex ) > { > PyErr_SetString( PyExc_RuntimeError, ex.what() ); > } > > BOOST_PYTHON_MODULE(mapster) > { > register_exception_translator( TranslateRTE ); > } > > ---------------------------------------------------------------- > and I'm getting a way lengthy response from the compiler... > ---------------------------------------------------------------- Hi Andreas, Sorry it took me so long to respond. I've been travelling and many things got pushed back... Firstly, the warnings are caused by the fact that you're not building your extension module with Boost.Build... or more specifically, that you're putting boost in your #include path with -I instead of -isystem. Well, in fairness we found that -isystem does weird things on some platforms so we had to use -I in those scenarios. You might be seeing that effect. I think the Boost.Preprocessor library also now has a fix which will prevent this warning from showing up, so you could try the latest Boost CVS instead if you like. Hmm, I see you're using the "jam" command below. I'm not sure how that can work out; Boost.Build is designed to recognize whether you're invoking it as `jam' or `bjam' and to only use our Boost.Build behavior if it was `bjam'. Secondly, I think you'll avoid the hard error if you use: register_exception_translator( &TranslateRTE ); -------------------------------------------------^ I probably ought to change things so that functions are passed by value here, so that this isn't a problem. In the meantime, that should be a sufficient workaround. > kloeckner at crunch:~/mapster/cvs/edmap_ng/src$ jam > ..found 851 target(s)... > ..updating 2 target(s)... > C++ shell/mapster.o > In file included from /home/kloeckner/boost_1_29_0/boost/python.hpp:43, > from shell/mapster.cpp:59: > /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:184:42: warning: pasting > "operator" and "+" does not give a valid preprocessing token > /home/kloeckner/boost_1_29_0/boost/python/operators.hpp:185:42: warning: pasting > "operator" and "-" does not give a valid preprocessing token > shell/mapster.cpp:72: instantiated from here > /home/kloeckner/boost_1_29_0/boost/bind.hpp:285: no match for call to `( > boost::python::detail::translate_exception std::runtime_error&)>) (const boost::python::detail::exception_handler&, > const boost::function0 boost::empty_function_mixin, std::allocator >&, void > (* const&)(const std::runtime_error&))' > /home/kloeckner/boost_1_29_0/boost/python/detail/translate_exception.hpp:30: > candidates > are: bool boost::python::detail::translate_exception Translate>::operator()(const boost::python::detail::exception_handler&, > const boost::function0 boost::empty_function_mixin, std::allocator >&, > boost::call_traits::param_type) const [with ExceptionType = > std::runtime_error, Translate = void ()(const std::runtime_error&)] > > g++-3.2 -c -o shell/mapster.o -g -pthread -fPIC -O -D_GNU_SOURCE -DOTL_ODBC > -DOTL_ODBC_UNIX -DOTL_STL -Ishell -I. -I/usr/include/python2.2 -I. > -I/home/kloeckner/boost_1_29_0 shell/mapster.cpp > > ..failed C++ shell/mapster.o ... > ..skipped mapster.so for lack of mapster.o... > ..failed updating 1 target(s)... > ..skipped 1 target(s)... > > ---------------------------------------------------------------- > Any help is appreciated. > > Thanks > -- > Andreas -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From achim.domma at syynx.de Mon Nov 4 17:18:33 2002 From: achim.domma at syynx.de (Achim Domma) Date: Mon, 4 Nov 2002 17:18:33 +0100 Subject: [C++-sig] gcc-link-action actions to long (max 10240) Message-ID: Hi, my extension module compiles fine on Windows with VC7. On Linux (RedHat 8 with gcc 3.2) I get the following error: gcc-link-action actions to long (max 10240) What should I do? I'm quite new to Linux and have setup the system just for testing compilation of my project. greetings Achim From Shayne.FLETCHER at rbos.com Mon Nov 4 17:29:06 2002 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Mon, 4 Nov 2002 16:29:06 -0000 Subject: [C++-sig] boost python v2 under SUN workshop 6 Message-ID: Hi all: Has anyone attempted to build the boost python v2 bpl.so using SUN workshop 6 or 7? Any advice appreciated. - Shayne. ******************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority ******************************************************************** From ostiguy at fnal.gov Mon Nov 4 17:47:16 2002 From: ostiguy at fnal.gov (Francois Ostiguy) Date: Mon, 4 Nov 2002 10:47:16 -0600 (CST) Subject: [C++-sig] Static Methods In-Reply-To: Message-ID: Hi- In a message on this list on July 5, Dave Abrahams said: >We don't have a way to make true static methods yet. >getDims will work fine if you access it through the class like this: > > Nums.getDims() > >but not if you access it through the instance > > n = Nums() > n.getDims() # error > >-Dave I am assuming that the above statement remains true for the newly released Boost.python v2. I am trying to wrap the a static function Ring::initNodes(). (For reference, Ring is a class that inherits virtually from other classes; I think this should be immaterial in the present context). When I import my module and try to run Ring::initValues(), here is what get >>> a = Ring() >>> Ring.initValues() Traceback (most recent call last): File "", line 1, in ? AttributeError: type object 'orbit.Ring' has no attribute 'initValues' As it should be ... however >>> Ring.initNodes() Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method Boost.Python.function object must be called with Ring instance as first argument (got nothing instead) What am I missing ? As always, help is greatly appreciated. -Francois ---------------------------------------------------------------------------- Dr. Jean-Francois OSTIGUY voice: (630) 840-2231 Beam Physics Dept MS220 FAX: (630) 840-6039 Fermi National Accelerator Laboratory email: ostiguy at fnal.gov Batavia IL 60510-0500 WWW:www-ap.fnal.gov/~ostiguy From gideon at computer.org Mon Nov 4 17:59:48 2002 From: gideon at computer.org (gideon may) Date: Mon, 04 Nov 2002 17:59:48 +0100 Subject: [C++-sig] gcc-link-action actions to long (max 10240) In-Reply-To: References: Message-ID: <781694.1036432788@localhost> --On Monday, November 04, 2002 5:18 PM +0100 Achim Domma wrote: > Hi, > > my extension module compiles fine on Windows with VC7. On Linux (RedHat 8 > with gcc 3.2) I get the following error: > > gcc-link-action actions to long (max 10240) > > What should I do? I'm quite new to Linux and have setup the system just > for testing compilation of my project. > It's a hardcoded limit in jam.h at line 462 (boost 1.29.0) . I came across the same problem and by increasing it the error disappeared. ciao, gideon From dave at boost-consulting.com Mon Nov 4 17:49:30 2002 From: dave at boost-consulting.com (David Abrahams) Date: 04 Nov 2002 11:49:30 -0500 Subject: [C++-sig] boost python v2 under SUN workshop 6 In-Reply-To: References: Message-ID: "FLETCHER, Shayne, FM" writes: > Hi all: > > Has anyone attempted to build the boost python v2 bpl.so using SUN workshop > 6 or 7? > Any advice appreciated. I recently started testing parts of boost under Sun WS 7. My experience was that the compiler's template machinery is so badly broken that there's little hope of getting Boost Python to work with it until a lot of time has been invested in workarounds for the compiler bugs. I don't expect it to work with Sun for at least another month or two, and that's if we are able to really devote time to porting boost to that compiler. In the meantime I suggest using GCC on Sun. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Mon Nov 4 18:54:58 2002 From: dave at boost-consulting.com (David Abrahams) Date: 04 Nov 2002 12:54:58 -0500 Subject: [C++-sig] gcc-link-action actions to long (max 10240) In-Reply-To: <781694.1036432788@localhost> References: <781694.1036432788@localhost> Message-ID: gideon may writes: > --On Monday, November 04, 2002 5:18 PM +0100 Achim Domma > wrote: > > > Hi, > > > > my extension module compiles fine on Windows with VC7. On Linux (RedHat 8 > > with gcc 3.2) I get the following error: > > > > gcc-link-action actions to long (max 10240) > > > > What should I do? I'm quite new to Linux and have setup the system just > > for testing compilation of my project. > > > > It's a hardcoded limit in jam.h at line 462 (boost 1.29.0) . I came > across the same problem and by increasing it the error disappeared. Gideon's idea of modifying jam.h and rebuilding bjam could work for you. Another approach is to break your extension module into libraries: lib part1 : a.cpp b.cpp c.cpp ; lib part2 : d.cpp e.cpp f.cpp ; extension ext : part1 part2 ../build/boost_python ; However I think this points out a fundamental (but correctible) flaw in bjam, though: Linux shells do in fact have a command-line length limit (though it is larger), and if you increase MAXLINE, static libraries will be built all-at-once instead of using smaller piecemeal actions... which I assume is undesirable. It seems to me that we ought to warn for actions longer than MAXLINE, or that MAXLINE should be set per-target so that we can break up piecemeal actions but avoid stopping the action for targets which must be built all-at-once. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From kloeckner at RTNA.DaimlerChrysler.COM Mon Nov 4 19:52:41 2002 From: kloeckner at RTNA.DaimlerChrysler.COM (Andreas Kloeckner) Date: Mon, 4 Nov 2002 10:52:41 -0800 Subject: [C++-sig] boost.python 2 exception handling In-Reply-To: References: <200210312311.g9VNBf8k001740@sunmail.RTNA.DaimlerChrysler.COM> Message-ID: <20021104185241.GA2319@ixion.net> Hi Dave, On Sun, Nov 03, 2002 at 12:24:06PM -0500, David Abrahams wrote: > Sorry it took me so long to respond. I've been travelling and many things > got pushed back... That's perfectly fine... I'm just glad I got help! > Firstly, the warnings are caused by the fact that you're not building > your extension module with Boost.Build... or more specifically, that > you're putting boost in your #include path with -I instead of > -isystem. Well, in fairness we found that -isystem does weird things > on some platforms so we had to use -I in those scenarios. You might be > seeing that effect. I think the Boost.Preprocessor library also now > has a fix which will prevent this warning from showing up, so you > could try the latest Boost CVS instead if you like. I'm not too concerned about the warnings, but thanks for the hint :) > Hmm, I see you're using the "jam" command below. I'm not > sure how that can work out; Boost.Build is designed to recognize > whether you're invoking it as `jam' or `bjam' and to only use our > Boost.Build behavior if it was `bjam'. I'm using a custom Jamfile - for various reasons beyond the scope of this email. I might be missing some finer points of the build process, but for right now, it does the job(tm). :) > Secondly, I think you'll avoid the hard error if you use: > > register_exception_translator( &TranslateRTE ); > -------------------------------------------------^ That actually worked. If you have the time, it would be great if you could explain the difference between passing a function with or without the ampersand. As far as C++ was concerned, so far I thought the two were perfectly equivalent...? Thank you for your really great library and the great support :) Andreas From dave at boost-consulting.com Mon Nov 4 20:14:43 2002 From: dave at boost-consulting.com (David Abrahams) Date: 04 Nov 2002 14:14:43 -0500 Subject: [C++-sig] boost.python 2 exception handling In-Reply-To: <20021104185241.GA2319@ixion.net> References: <200210312311.g9VNBf8k001740@sunmail.RTNA.DaimlerChrysler.COM> <20021104185241.GA2319@ixion.net> Message-ID: Andreas Kloeckner writes: > Hi Dave, [dave] > > Hmm, I see you're using the "jam" command below. I'm not > > sure how that can work out; Boost.Build is designed to recognize > > whether you're invoking it as `jam' or `bjam' and to only use our > > Boost.Build behavior if it was `bjam'. > > I'm using a custom Jamfile - for various reasons beyond the scope of > this email. I might be missing some finer points of the build process, > but for right now, it does the job(tm). :) Good luck with that ;-) > > Secondly, I think you'll avoid the hard error if you use: > > > > register_exception_translator( &TranslateRTE ); > > -------------------------------------------------^ > > That actually worked. If you have the time, it would be great if you > could explain the difference between passing a function with or without > the ampersand. As far as C++ was concerned, so far I thought the two > were perfectly equivalent...? No, without the ampersand you have a function reference which strangely "decays" to a function pointer in the right contexts. The problem with passing without the ampersand to functions taking T const& is that T is not deduced as a function pointer type, but as a function type... so you have to reconstitute the pointer or reference by writing T& or T* in order to do anything with it. > Thank you for your really great library and the great support :) You're welcome! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From ostiguy at fnal.gov Mon Nov 4 21:05:45 2002 From: ostiguy at fnal.gov (Francois Ostiguy) Date: Mon, 4 Nov 2002 14:05:45 -0600 (CST) Subject: [C++-sig] Static Methods - correction Message-ID: There was a mix-up in my previous message. Once again, I have been trying, without success, to expose a static member of a class (Ring::initNodes()). The python output is as follows: Python 2.2.2 (#1, Oct 28 2002, 17:04:52) [GCC 3.1.1] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> from orbit import * >>> a = Ring() >>> a >>> a.initNodes() Traceback (most recent call last): File "", line 1, in ? TypeError: bad argument type for built-in operation >>> Ring.initNodes() Traceback (most recent call last): File "", line 1, in ? TypeError: unbound method Boost.Python.function object must be called with Ring instance as first argument (got nothing instead) Ring::initNodes() is declared as a static member of the c++ class Ring. I understand, based on Dave's comments that a.initNodes() will not work. I do not understand why the second form Ring.initNodes() fails. Is there a simple way to expose static member functions ? Your help is greatly appreciated. -Francois ---------------------------------------------------------------------------- Dr. Jean-Francois OSTIGUY voice: (630) 840-2231 Beam Physics Dept MS220 FAX: (630) 840-6039 Fermi National Accelerator Laboratory email: ostiguy at fnal.gov Batavia IL 60510-0500 WWW:www-ap.fnal.gov/~ostiguy From dave at boost-consulting.com Mon Nov 4 21:11:53 2002 From: dave at boost-consulting.com (David Abrahams) Date: 04 Nov 2002 15:11:53 -0500 Subject: [C++-sig] Static Methods In-Reply-To: References: Message-ID: Francois Ostiguy writes: > Hi- > > In a message on this list on July 5, Dave Abrahams said: > > >We don't have a way to make true static methods yet. > >getDims will work fine if you access it through the class like this: > > > > Nums.getDims() > > > >but not if you access it through the instance > > > > n = Nums() > > n.getDims() # error > > > >-Dave > > I am assuming that the above statement remains true for the newly > released Boost.python v2. Yes. > I am trying to wrap the a static function Ring::initNodes(). (For > reference, Ring is a class that inherits virtually from other > classes; I think this should be immaterial in the present context). Yes. > When I import my module and try to run Ring::initValues(), here is what > get > > >>> a = Ring() > >>> Ring.initValues() > Traceback (most recent call last): > File "", line 1, in ? > AttributeError: type object 'orbit.Ring' has no attribute 'initValues' > > As it should be ... however > > >>> Ring.initNodes() > Traceback (most recent call last): > File "", line 1, in ? > TypeError: unbound method Boost.Python.function object must be called with > Ring instance as first argument (got nothing instead) > > What am I missing ? Nothing. You can make a static method from Python as follows: import hello # add a regular function to the World class as a static method hello.World.foo = staticmethod(hello.foo) x = hello.World('hi') print x.greet() print hello.World.foo() print x.foo() There's no reason we couldn't do this from C++; the biggest challenge is deciding on an interface. For example, do we add a set of 3 overloads for class_<>::def_static(...) ? Or, should we add an additional overload to class_<>::def(...) which takes 4 parameters, one of which may be `static_' ? Or should the interface be something else? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From oliver.malham at savageparsnip.com Tue Nov 5 00:09:33 2002 From: oliver.malham at savageparsnip.com (Oliver Malham) Date: 04 Nov 2002 23:09:33 +0000 Subject: [C++-sig] Problems getting to grips with Boost v2.0 Message-ID: <1036451380.559.66.camel@scarlet> Hiya, First off, let me congratulate everyone who has contributed to Boost.Python on producing such an excellent library. (And I'm sorry if this question is a bit long winded ;-) I'm currently working on a game engine that will use Python as the ingame scripting language that controls everything. A key part of this functionality is building the scenegraph for the current level. This takes the form of a tree of objects which are created by a factory object, and passed about as object pointers (the factory class manages the object's lifetime). Building a basic scenegraph in C++ works fine; however building the same scenegraph through the python interface doesn't seem to setup the scenegraph properly (the scenegraph object complains about being empty). I'm not sure where I've gone wrong, and would appreciate it if you could point me in the right direction. Here's the code involved: BOOST_PYTHON_MODULE(KeiPy) { // Scene object manages scenegraph, user IO, AI, etc. class_("Scene") .def("activate", &Scene::activate) .def("sleep", &Scene::sleep) .def("cleanup", &Scene::cleanup) .def_readonly("scenegraph", &Scene::scenegraph) // Member class ; // Scenegraph handles all drawable objects class_("SceneGraph") .def("setStart", &SceneGraph::setStart) //Takes SceneGraphNode pointer ; // Base scenegraph node object class_("SceneGraphNode") .def("type", &SceneGraphNode::type) ; // Very simple object just clears the screen to blue class_ >("BlueScreen") .def("type", &BlueScreen::type) ; // Factory creates and owns all dynamically built objects class_("Factory") .def("newScene", &Factory::newScene, return_internal_reference<>()) .def("newBlueScreen", &Factory::newBlueScreen, return_internal_reference<>()) ; }; And the Python code that builds the scenegraph: from KeiPy import * factory = Factory() scene = factory.newScene() bluescreen = factory.newBlueScreen() scene.scenegraph.setStart(bluescreen) When this enters the game's main loop, I get messages from the constructors for the scene, scenegraph and bluescreen objects. From my debug messages it looks like the bluescreen object is being assigned to a different scenegraph object than the one constructed, which has me just a bit confused. Thanks for any advice you can give me, and I hope I'm not being stupid and wasting your time ;-) Cheers, Oliver Malham Software Engineer Savage Parsnip Games http://savageparsnip.com From Shayne.FLETCHER at rbos.com Tue Nov 5 15:02:00 2002 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Tue, 5 Nov 2002 14:02:00 -0000 Subject: [C++-sig] bpl on sun errors Message-ID: Dear All: I have been trying to compile the v2 boost_python shared library on Solaris using Sun Workshop 6 (__SUNPRO_CC=0x530) and 7 (__SUNPRO_CC=0x540). I can report that with a little massaging (right or wrong), most of the source files compile. The following problem though has stopped me in my tracks: "object/enum.cpp" produces "object/enum.cpp", line 141: Error: Overloading ambiguity between "boost::python::handle<_typeobject>::handle>(boost::python::detail::borrowed<_typeobject>*)" and "boost::python::handle<_typeobject>::handle(const boost::python::handle<_typeobject>&)". "object/enum.cpp", line 141: Error: Cannot use boost::python::detail::borrowed<_typeobject>* to initialize boost::python::handle<_typeobject>. "object/enum.cpp", line 142: Error: Overloading ambiguity between "boost::python::handle<_typeobject>::handle>(boost::python::detail::borrowed<_typeobject>*)" and "boost::python::handle<_typeobject>::handle(const boost::python::handle<_typeobject>&)". "object/enum.cpp", line 142: Error: Cannot use boost::python::detail::borrowed<_typeobject>* to initialize boost::python::handle<_typeobject>. "object/enum.cpp", line 188: Error: Cannot cast from boost::python::api::proxy to boost::python::extract. "object/enum.cpp", line 199: Error: Overloading ambiguity between "boost::python::handle<_typeobject>::handle>(boost::python::detail::borrowed<_typeobject>*)" and "boost::python::handle<_typeobject>::handle(const boost::python::handle<_typeobject>&)". "object/enum.cpp", line 199: Error: Cannot cast from boost::python::detail::borrowed<_typeobject>* to boost::python::handle<_typeobject>. "object/enum.cpp", line 201: Error: Cannot cast from boost::python::api::proxy to boost::python::extract. The statements at lines 141 and 142 giving rise to the first of the "overloading ambiguity" errors are: type_handle metatype(borrowed(&PyType_Type)); type_handle base(borrowed(&enum_type_object)); Does anyone have any suggestions ? - Shayne. ******************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority ******************************************************************** From dave at boost-consulting.com Tue Nov 5 15:43:48 2002 From: dave at boost-consulting.com (David Abrahams) Date: 05 Nov 2002 09:43:48 -0500 Subject: [C++-sig] bpl on sun errors In-Reply-To: References: Message-ID: "FLETCHER, Shayne, FM" writes: > Dear All: > > I have been trying to compile the v2 boost_python shared library on Solaris > using Sun Workshop 6 (__SUNPRO_CC=0x530) and 7 (__SUNPRO_CC=0x540). I can > report that with a little massaging (right or wrong), most of the source > files compile. The following problem though has stopped me in my tracks: > "object/enum.cpp" produces > Does anyone have any suggestions ? http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1420705 -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From warkid at hotbox.ru Tue Nov 5 17:03:52 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Tue, 5 Nov 2002 19:03:52 +0300 Subject: [C++-sig] What does it mean? Message-ID: <3629130859.20021105190352@hotbox.ru> Hello. Compiling extension with msvc6 all works ok. But if I try it with Intel 6.0 it throws this exception: ''' TypeError: No to_python (by-value) converter found for C++ type: struct boost::p ython::objects::reference_to_value ''' what coul cause it? (We suspect that we have our Intel compiler configured badly - e.g. we couldnt built boost_python.dll with it so used one built with msvc) Best regards, Kerim mailto:warkid at hotbox.ru ------------------ Get free mailbox 20 Mb at http://www.hotbox.ru From dave at boost-consulting.com Tue Nov 5 16:57:12 2002 From: dave at boost-consulting.com (David Abrahams) Date: 05 Nov 2002 10:57:12 -0500 Subject: [C++-sig] What does it mean? In-Reply-To: <3629130859.20021105190352@hotbox.ru> References: <3629130859.20021105190352@hotbox.ru> Message-ID: Kerim Borchaev writes: > Hello. > > Compiling extension with msvc6 all works ok. > But if I try it with Intel 6.0 it throws this exception: > ''' > TypeError: No to_python (by-value) converter found for C++ type: struct boost::p > ython::objects::reference_to_value > ''' > what coul cause it? Beyond the explanations below, I'm not gonna speculate. > (We suspect that we have our Intel compiler configured badly - e.g. we > couldnt built boost_python.dll with it so used one built with msvc) I use Boost.Build to make and test Boost.Python with Intel 5, 6, and 7. It all works. I have no reason to think that an msvc Boost.Python will work with Intel-built extension modules. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From Shayne.FLETCHER at rbos.com Tue Nov 5 18:15:26 2002 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Tue, 5 Nov 2002 17:15:26 -0000 Subject: [C++-sig] boost python v2 under SUN workshop 6 Message-ID: >I recently started testing parts of boost under Sun WS 7. My >experience was that the compiler's template machinery is so badly >broken that there's little hope of getting Boost Python to work with >it until a lot of time has been invested in workarounds for the >compiler bugs. I don't expect it to work with Sun for at least another >month or two, and that's if we are able to really devote time to >porting boost to that compiler. In the meantime I suggest using GCC on >Sun. Thanks for your comments Dave. - Shayne. ******************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority ******************************************************************** From gwl at u.washington.edu Tue Nov 5 20:58:15 2002 From: gwl at u.washington.edu (Graeme Lufkin) Date: 05 Nov 2002 11:58:15 -0800 Subject: [C++-sig] contained structure access Message-ID: <1036526295.30267.23.camel@ida.astro.washington.edu> I've found some strange (I think) behavior in Boost.Python, and I've boiled it down to the example below. (By the way, I'm new to Boost.Python, and am using it to get scripting language access to the C/C++ classes used in my astrophysics simulations. I think it's going to work out great.) I'm exposing several C++ classes to Python. Classes that are made of built-in types work great, and I can manipulate member variables when I def_readwrite() them. Now go up a level, and imagine a class that holds these simpler classes. I def_readwrite() the member variables of the higher-level class that are of type the simpler class. But now when I access the members of the members, my assigning gets silently ignored. Let me explain with code: Here's my .cpp file. It defines two simple structs and exposes them to Python. (I'm using Boost 1.29.0) struct Atom { double x; }; struct Holder { Atom a; }; #include using namespace boost::python; BOOST_PYTHON_MODULE(Contained_Stuff) { class_("Atom").def_readwrite("x", &Atom::x); class_("Holder").def_readwrite("a", &Holder::a); } To illustrate the problem, here's a Python session with the compiled module: >>> from Contained_Stuff import * >>> at = Atom() >>> print at.x 0.0 >>> at.x = 42 >>> print at.x 42.0 >>> h = Holder() >>> print h.a.x 0.0 >>> h.a.x = 43 >>> print h.a.x 0.0 >>> h.a = at >>> print h.a.x 42.0 I can create variables of type Atom, and get/set it's 'x' member variable fine. I can also create variables of type Holder, and get/set its 'a' member variable (of type Atom). However, when I try to modify the 'x' of the Holder's Atom, it is ignored. I can recreate this situation using regular 100% Python classes, and it works as expected. So, what am I doing wrong? -- - Graeme gwl at u.washington.edu "The experiment was inconclusive, so we had to use statistics." From dave at boost-consulting.com Tue Nov 5 22:37:18 2002 From: dave at boost-consulting.com (David Abrahams) Date: 05 Nov 2002 16:37:18 -0500 Subject: [C++-sig] contained structure access In-Reply-To: <1036526295.30267.23.camel@ida.astro.washington.edu> References: <1036526295.30267.23.camel@ida.astro.washington.edu> Message-ID: Graeme Lufkin writes: > I've found some strange (I think) behavior in Boost.Python, and I've > boiled it down to the example below. (By the way, I'm new to > Boost.Python, and am using it to get scripting language access to the > C/C++ classes used in my astrophysics simulations. I think it's going > to work out great.) > I'm exposing several C++ classes to Python. Classes that are made of > built-in types work great, and I can manipulate member variables when I > def_readwrite() them. Now go up a level, and imagine a class that holds > these simpler classes. I def_readwrite() the member variables of the > higher-level class that are of type the simpler class. But now when I > access the members of the members, my assigning gets silently ignored. > Let me explain with code: > Here's my .cpp file. It defines two simple structs and exposes them to > Python. (I'm using Boost 1.29.0) > > struct Atom { > double x; > }; > > struct Holder { > Atom a; > }; > > #include > using namespace boost::python; > > BOOST_PYTHON_MODULE(Contained_Stuff) { > class_("Atom").def_readwrite("x", &Atom::x); > class_("Holder").def_readwrite("a", &Holder::a); > } > > To illustrate the problem, here's a Python session with the compiled > module: > > >>> from Contained_Stuff import * > >>> at = Atom() > >>> print at.x > 0.0 > >>> at.x = 42 > >>> print at.x > 42.0 > >>> h = Holder() > >>> print h.a.x > 0.0 > >>> h.a.x = 43 > >>> print h.a.x > 0.0 > >>> h.a = at > >>> print h.a.x > 42.0 Nice reproducible case! > I can create variables of type Atom, and get/set it's 'x' member > variable fine. I can also create variables of type Holder, and get/set > its 'a' member variable (of type Atom). However, when I try to modify > the 'x' of the Holder's Atom, it is ignored. I can recreate this > situation using regular 100% Python classes, and it works as expected. > So, what am I doing wrong? You have to remember how def_readwrite works. It creates a property. If you look at the documentation at http://www.boost.org/libs/python/doc/v2/class.html#class_-spec-modifiers you'll see Effects: this->add_property(name, make_getter(pm), make_setter(pm)); And if you look at http://www.boost.org/libs/python/doc/v2/data_members.html#make_getter-spec you'll see that make_getter with one argument uses the default call policies, which copy of all return values. What's happening is that the x member is getting set in the copy. Instead, you could use this->add_property( name , make_getter(&Holder::a, return_internal_reference<>()) , make_setter(&Holder::a)); Which should get you the behavior you want. I'll look into fixing it so this is no longer needed, if I can find a few minutes to spend on it. > -- > - Graeme > gwl at u.washington.edu > "The experiment was inconclusive, so we had to use statistics." > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Tue Nov 5 22:48:25 2002 From: dave at boost-consulting.com (David Abrahams) Date: 05 Nov 2002 16:48:25 -0500 Subject: [C++-sig] Problems getting to grips with Boost v2.0 In-Reply-To: <1036451380.559.66.camel@scarlet> References: <1036451380.559.66.camel@scarlet> Message-ID: Oliver Malham writes: > Hiya, > > First off, let me congratulate everyone who has contributed to > Boost.Python on producing such an excellent library. (And I'm sorry if > this question is a bit long winded ;-) Thanks! > I'm currently working on a game engine that will use Python as the > ingame scripting language that controls everything. A key part of this > functionality is building the scenegraph for the current level. This > takes the form of a tree of objects which are created by a factory > object, and passed about as object pointers (the factory class manages > the object's lifetime). Building a basic scenegraph in C++ works fine; > however building the same scenegraph through the python interface > doesn't seem to setup the scenegraph properly (the scenegraph object > complains about being empty). I'm not sure where I've gone wrong, and > would appreciate it if you could point me in the right direction. Nice reproducible case! > When this enters the game's main loop, I get messages from the > constructors for the scene, scenegraph and bluescreen objects. From my > debug messages it looks like the bluescreen object is being assigned to > a different scenegraph object than the one constructed, which has me > just a bit confused. > > Thanks for any advice you can give me, and I hope I'm not being stupid > and wasting your time ;-) It's clearly not stupid; you're having the same problem as Graeme has in http://mail.python.org/pipermail/c++-sig/2002-November/002434.html. Fortunately, your workaround is also basically the same: http://mail.python.org/pipermail/c++-sig/2002-November/002435.html. It's obvious that you're not the only one who will have this problem, so I'll bump the solution up in my priority queue. HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Wed Nov 6 16:19:53 2002 From: dave at boost-consulting.com (David Abrahams) Date: 06 Nov 2002 10:19:53 -0500 Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: References: Message-ID: Brad King writes: > Dave, > > I've finally gotten the time to work on python wrapper support in > CABLE (http://public.kitware.com/Cable). Wonderful! Let's have this discussion on the C++-sig, please... > As I said before, I think generating BPL input is a good place to > start. However, I have to consider the capabilities available to > the user from python after wrapping. Good idea. > The wrapping tool will be used by ITK (www.itk.org), and that > project has certain requirements. > > There are a couple problems I'd like to discuss with you. > > 1.) Namespaces v. Python Modules > > All code in ITK is in a C++ "itk" namespace. We'd like to have this > namespace reflected in the python wrappers with code like this: > > # Load the ITK ptyhon wrappers. > import itk > > # Create an instance of an ITK object. > # Equivalent C++ code: > # itk::Object::Pointer o = itk::Object::New() > o = itk.Object.New() What's the problem? Maybe it's the fact that we don't have static function support in Boost.Python yet? http://aspn.activestate.com/ASPN/Mail/Message/c++-sig/1420969 I understand why you want this, but for this /particular/ case I'd suggest that an interface like o = itk.Object() would be more appropriate. Why expose to users that there's a factory function at work here? If you must have the static function interface, we just need to have a discussion of the C++ interface questions I pose in the link above, so that I can come up with a good design. > 2.) Pointer Comparison > > While most of ITK uses built-in intrusive smart pointers (like the > Object::Pointer in the above example), some methods return raw pointers. > We need to be able to compare these pointers: > > p1 = o.GetFoo() > p2 = o.GetFoo() > p1 == p2 > > The example at > > http://www.boost.org/libs/python/doc/v2/reference_existing_object.html > > demonstrates that this will not work. Generally speaking, that's true. > We could always write and wrap a function to compare the pointers > for us, but that seems ugly. The CABLE Tcl wrappers keep track of > all objects referenced by Tcl wrapper invokations. When a returned > pointer/reference matches the type and value of a known object, the > same pointer wrapper object is given back to Tcl, with an > incremented reference count. Aha. I've considered doing something like this in the past, but I thought that tracking every object in this way *by default* would be a price that not all users would be willing to pay. There are also issues of base/derived class tracking (what happens if you're tracking the base object and someone returns a pointer to the derived object, which has a different address?) which make doing it right especially difficult. Furthermore, when a Python object holds its C++ object by smart pointer, there may not be any one single Python object associated with a given C++ object (e.g. with shared_ptr), or the associated Python object might change over time (e.g. with auto_ptr). However, if itk's smart pointers are indeed intrusive, it seems to me that you can just generate thin wrappers for your raw-pointer-returning functions which generate the smart pointer for you. In that case: id(o.GetFoo()) != id(o.GetFoo()) But you can arrange for o.GetFoo() == o.GetFoo() by simply defining __cmp__ or __eq__ for whatever class that is. Another approach we could consider is to arrange a way for you to say, "pointers to any classes derived from X should be converted to python this way". That requires an investment in some more Boost.Python work, so it might have to wait a little while... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From brad.king at kitware.com Wed Nov 6 19:46:38 2002 From: brad.king at kitware.com (Brad King) Date: Wed, 6 Nov 2002 13:46:38 -0500 (EST) Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: Message-ID: Dave, > > 1.) Namespaces v. Python Modules > > > > All code in ITK is in a C++ "itk" namespace. We'd like to have this > > namespace reflected in the python wrappers with code like this: > > > > # Load the ITK ptyhon wrappers. > > import itk > > > > # Create an instance of an ITK object. > > # Equivalent C++ code: > > # itk::Object::Pointer o = itk::Object::New() > > o = itk.Object.New() > > What's the problem? Maybe it's the fact that we don't have static > function support in Boost.Python yet? Oops, I didn't finish this section of the email. I meant to point out that I don't see a way to have nested namespaces treated as modules in Python through BPL: # itk::foo::Bar() itk.foo.Bar() Even if it were not possible to separately load this "itk.foo" module, it would still be nice from a naming perspective. > I understand why you want this, but for this /particular/ case I'd > suggest that an interface like > > o = itk.Object() > > would be more appropriate. Why expose to users that there's a factory > function at work here? I agree that this particular case is prettier when hiding the New() method, but there is also something to be said for a one-to-one correspondence among C++, Tcl, and Python implementations of the same program. Also, CABLE is intended to be a tool separate from ITK, and should not have ITK-specific hacks in it. Then, in order to achieve this syntactic change there would have to be a way of specifying it in the configuration file. One of my design goals for CABLE was to produce wrappers that reflect the original C++ as closely as possible, and with as few configuration options as possible. This actually brings up the other main issue with automatic generation. Whenever a return_value_policy is required, CABLE will have to make some assumptions, and probably just always use reference_existing_object. Anything different would require per-method configuration, which already starts to defeat the purpose of auto-generation of wrappers. > If you must have the static function interface, we just need to have a > discussion of the C++ interface questions I pose in the link above, so > that I can come up with a good design. I'd definately prefer the def(..., static_()) approach over having static_def. Here is another approach that crossed my mind: struct A { static void StaticMethod(); }; class_("A", init<>()) .def("StaticMethod", static_(&A::StaticMethod)); I'm not sure I'd prefer this over class_("A", init<>()) .def("StaticMethod", &A::StaticMethod, static_()); but I thought I'd mention it anyway. > Aha. I've considered doing something like this in the past, but I > thought that tracking every object in this way *by default* would be a > price that not all users would be willing to pay. In Tcl the tracking is more necessary because the wrapper objects each have a corresponding Tcl command used to invoke methods on that object. CABLE needs to keep track of all the commands it creates and destroys to keep this working. The tracking isn't as necessary for Python, though, so you're right that the extra cost may not be worth it. > There are also issues of base/derived class tracking (what happens if > you're tracking the base object and someone returns a pointer to the > derived object, which has a different address?) which make doing it > right especially difficult. I went through the same thought process for CABLE's Tcl wrappers. At the time I decided to go for the pointer comparison and ignore the problems to get something working. I have yet to thoroughly revisit the issue. However, I've toyed with the idea of automatic down-casting of pointers to polymorphic C++ types. > However, if itk's smart pointers are indeed intrusive, it seems to me > that you can just generate thin wrappers for your raw-pointer-returning > functions which generate the smart pointer for you. [snip] > Another approach we could consider is to arrange a way for you to say, > "pointers to any classes derived from X should be converted to python > this way". That requires an investment in some more Boost.Python work, > so it might have to wait a little while... These options are definately worth my consideration, but this decision will depend somewhat on the configurability decision I mentioned above. -Brad From dave at boost-consulting.com Wed Nov 6 19:58:46 2002 From: dave at boost-consulting.com (David Abrahams) Date: 06 Nov 2002 13:58:46 -0500 Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: References: Message-ID: Brad King writes: > Dave, > > > > 1.) Namespaces v. Python Modules > > > > > > All code in ITK is in a C++ "itk" namespace. We'd like to have this > > > namespace reflected in the python wrappers with code like this: > > > > > > # Load the ITK ptyhon wrappers. > > > import itk > > > > > > # Create an instance of an ITK object. > > > # Equivalent C++ code: > > > # itk::Object::Pointer o = itk::Object::New() > > > o = itk.Object.New() > > > > What's the problem? Maybe it's the fact that we don't have static > > function support in Boost.Python yet? > > Oops, I didn't finish this section of the email. I meant to point out > that I don't see a way to have nested namespaces treated as modules in > Python through BPL: > > # itk::foo::Bar() > itk.foo.Bar() Sure there is. See http://www.boost.org/libs/python/doc/v2/scope.html and this thread, including Ralf's followup: http://aspn.activestate.com/ASPN/Mail/Message/1411775 > Even if it were not possible to separately load this "itk.foo" module, it > would still be nice from a naming perspective. If you do it as a subpackage, it is possible to separately load it. > > I understand why you want this, but for this /particular/ case I'd > > suggest that an interface like > > > > o = itk.Object() > > > > would be more appropriate. Why expose to users that there's a factory > > function at work here? > > I agree that this particular case is prettier when hiding the New() > method, but there is also something to be said for a one-to-one > correspondence among C++, Tcl, and Python implementations of the > same program. Yes. > Also, CABLE is intended to be a tool separate from ITK, and should not > have ITK-specific hacks in it. Then, in order to achieve this syntactic > change there would have to be a way of specifying it in the configuration > file. One of my design goals for CABLE was to produce wrappers that > reflect the original C++ as closely as possible, and with as few > configuration options as possible. OK, it sounds like you'll need static method support... eventually. Though it looks like you just want submodule support from reading your earlier text. > This actually brings up the other main issue with automatic > generation. Whenever a return_value_policy is required, CABLE will > have to make some assumptions, and probably just always use > reference_existing_object. :( I hate the idea that you can crash things from Python. > Anything different would require per-method configuration, which > already starts to defeat the purpose of auto-generation of wrappers. Yes. > > If you must have the static function interface, we just need to have a > > discussion of the C++ interface questions I pose in the link above, so > > that I can come up with a good design. > > I'd definately prefer the def(..., static_()) approach over having > static_def. Here is another approach that crossed my mind: Actually, I was not proposing that. I was proposing: def(..., static_ ) ^^ > struct A { static void StaticMethod(); }; > > class_("A", init<>()) > .def("StaticMethod", static_(&A::StaticMethod)); I thought of that, too. > I'm not sure I'd prefer this over > > class_("A", init<>()) > .def("StaticMethod", &A::StaticMethod, static_()); > > but I thought I'd mention it anyway. Given the two options with parens, I definitely prefer the first one. And I think I prefer it overall, since it nicely associates staticness with the function to be wrapped. > > Aha. I've considered doing something like this in the past, but I > > thought that tracking every object in this way *by default* would be a > > price that not all users would be willing to pay. > > In Tcl the tracking is more necessary because the wrapper objects > each have a corresponding Tcl command used to invoke methods on that > object. CABLE needs to keep track of all the commands it creates > and destroys to keep this working. The tracking isn't as necessary > for Python, though, so you're right that the extra cost may not be > worth it. It's not clear to me yet what the best approach is. As I said before, I kind of hate the idea of generating automatic wrappers which can crash the system. I think if all C++ objects are intrusively-counted, it's not a big deal to avoid this problem, though. > > There are also issues of base/derived class tracking (what happens if > > you're tracking the base object and someone returns a pointer to the > > derived object, which has a different address?) which make doing it > > right especially difficult. > > I went through the same thought process for CABLE's Tcl wrappers. > At the time I decided to go for the pointer comparison and ignore > the problems to get something working. I have yet to thoroughly > revisit the issue. However, I've toyed with the idea of automatic > down-casting of pointers to polymorphic C++ types. There is already some facility for that in Boost.Python. Take a look at libs/python/src/object/inheritance.cpp if you care. However, you have to register all the participating classes for this to work. > > However, if itk's smart pointers are indeed intrusive, it seems to > > me that you can just generate thin wrappers for your > > raw-pointer-returning functions which generate the smart pointer > > for you. > [snip] Another approach we could consider is to > > arrange a way for you to say, "pointers to any classes derived > > from X should be converted to python this way". That requires an > > investment in some more Boost.Python work, so it might have to > > wait a little while... > > These options are definately worth my consideration, but this decision > will depend somewhat on the configurability decision I mentioned above. Which one? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From brad.king at kitware.com Wed Nov 6 20:42:06 2002 From: brad.king at kitware.com (Brad King) Date: Wed, 6 Nov 2002 14:42:06 -0500 (EST) Subject: [C++-sig] Auto-Generation and BPL v2 In-Reply-To: Message-ID: Dave, > > Oops, I didn't finish this section of the email. I meant to point out > > that I don't see a way to have nested namespaces treated as modules in > > Python through BPL: > > > > # itk::foo::Bar() > > itk.foo.Bar() > > Sure there is. See > > http://www.boost.org/libs/python/doc/v2/scope.html Great, I'll try it. Thanks. > OK, it sounds like you'll need static method support... eventually. > Though it looks like you just want submodule support from reading your > earlier text. Well, the static method support is pretty critical. Almost every class in ITK uses an object factory invoked through a static method, so there are no public constructors. Any suggestions on how to fake it for now? > > This actually brings up the other main issue with automatic > > generation. Whenever a return_value_policy is required, CABLE will > > have to make some assumptions, and probably just always use > > reference_existing_object. > > :( > > I hate the idea that you can crash things from Python. > > > Anything different would require per-method configuration, which > > already starts to defeat the purpose of auto-generation of wrappers. > > Yes. Unfortunately, no matter how careful we are with object lifetime management, there is no way to prevent C++ code from deleting our objects in a way the wrappers can't detect. Even if the internal object refrence keeps the C++ object around, a method call on it may delete the internal object. The python code author will at least have to be responsible enough to prevent this problem. Random code generators will always be able to crash C++ programs :( > > class_("A", init<>()) > > .def("StaticMethod", static_(&A::StaticMethod)); > > I thought of that, too. > > > I'm not sure I'd prefer this over > > > > class_("A", init<>()) > > .def("StaticMethod", &A::StaticMethod, static_()); [snip] > Given the two options with parens, I definitely prefer the first one. > And I think I prefer it overall, since it nicely associates staticness > with the function to be wrapped. That association is a good point. I now prefer this syntax as well. Do you have a plan (and time) to implement this? I can get started on generating BPL input from CABLE without this support, but I'm going to need it eventually. > > revisit the issue. However, I've toyed with the idea of automatic > > down-casting of pointers to polymorphic C++ types. > > There is already some facility for that in Boost.Python. Take a look > at libs/python/src/object/inheritance.cpp if you care. However, you > have to register all the participating classes for this to work. Fortunately, type registration is not a problem for generated code :) I'll look at using that. > > > However, if itk's smart pointers are indeed intrusive, it seems to > > > me that you can just generate thin wrappers for your > > > raw-pointer-returning functions which generate the smart pointer > > > for you. > [snip] Another approach we could consider is to > > > arrange a way for you to say, "pointers to any classes derived > > > from X should be converted to python this way". That requires an > > > investment in some more Boost.Python work, so it might have to > > > wait a little while... > > > > These options are definately worth my consideration, but this decision > > will depend somewhat on the configurability decision I mentioned above. > > Which one? I just mean how much fine-tuning CABLE should support for wrapper generation. The more fine-tuning, the less that is automatic. The less that is automatic, the more work for library authors when they change their class interfaces. One of the requirements I've been given for this wrapping is that changes to a class's interface in C++ should not require configuration file updates. -Brad From dave at boost-consulting.com Wed Nov 6 21:01:16 2002 From: dave at boost-consulting.com (David Abrahams) Date: 06 Nov 2002 15:01:16 -0500 Subject: [C++-sig] Boost V1 build on Solaris In-Reply-To: <200210240036.g9O0awA23318@libra3.slac.stanford.edu> References: <200210231655.g9NGtOs14379@libra3.slac.stanford.edu> <200210232107.g9NL7V121141@libra3.slac.stanford.edu> <200210240036.g9O0awA23318@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: > One final question, which is not specific to boost::python but > general question on building Python modules. What my Solaris > administrators have done is to configure Python with > > > ./configure > --prefix=/afs/.slac.stanford.edu/package/python/common/2.0 > --exec-prefix=/afs/.slac.stanford.edu/package/python/sun4x_55/2.0 > > They also did a build fron Linux with the appropriate `exec-prefix'. > What apparently this has done is to put all but one of the Python > include files in the directory `common/2.0/include'. But Python.h > includes `config.h' or `pyconfig.h' (depending on the version) which > gets installed in `sun4x_55/2.0/include'. This is appropriate since > this file is machine/OS dependent. > > Now the problem is that boost::python, and other packages, gives you > one variable, like PYTHON_INCLUDES, for its build. When it is set to find > `Python.h' it will not find `pyconfig.h'. > > What is the best way to handle this situation? Is it a bug in > Python's configure script? Bug in boost::python and others? Or am > I missing something obvious? Sorry it took so long to come up with an answer, Paul. It was staring me right in the face the whole time, though: You just need to make sure your PYTHON_INCLUDES variable has two elements. Depending on how your shell treats quotes, that could take several forms. The shells I have available, e.g. bash, will let you embed a space in a command-line argument as follows: bjam -sPYTHON_INCLUDES="/afs/.slac.stanford.edu/package/python/common/2.0/include /afs/.slac.stanford.edu/package/python/sun4x_55/2.0/include" ... And bjam splits up variable values on whitespace boundaries. Some shells let you set up variables with embedded spaces in the environment; you might try that if your shell doesn't cooperate when you try to use quotes in the command-line. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Wed Nov 6 21:12:46 2002 From: dave at boost-consulting.com (David Abrahams) Date: 06 Nov 2002 15:12:46 -0500 Subject: [C++-sig] Python + Boost Python V2 + downcasting In-Reply-To: References: Message-ID: "Nicolas Lelong" writes: > Hello, > > I'm experiencing some embedding+extending with BPLv2 - and I could > not find any answer to this simple question : > > I have, say, a c++ class 'Base' and a c++ class 'Derived': > > class Base > { > public: > virtual int do_stuff() { return 0; } > }; > > class Derived > { > public: > virtual int do_more() { return 100; } > }; > > class ObjectServer > { > public: > Base* getObject(unsigned id) > { > return m_objects[id]; > } > > Base* m_objects[12]; > } > > declared in my module like this: > > class_("Base") > .def("do_stuff", &Base::do_stuff); > > class_ >("Derived") > .def("do_more", &Derived::do_more); > > class_("ObjectServer") > .def("getObject", &ObjectServer::getObject, return_internal_reference<>()); > > everything works fine - except that I can't get python to see the > _real_ class of the objects returned by getObject. I tried the > following: > > ... > obj = objectServer.getObject(0) > print isinstance(obj, Base) > print isinstance(obj, Derived) > print issubclass(Derived, Base) > print obj.__class__ > > and I get, when 'obj' is really a 'Derived*' > ... > 1 > 0 > 1 > module.Base > > how can I get to know that an object is an instance of Derived ?! Not easily. You could pass it to a function which takes a Derived& or a Derived*. > is there a builtin way in Python ? a BPL v2 way ? Nope. It is holding a Base* internally, and using C++ runtime polymorphism to call the right methods. > I even thought about implementing my own 'isinstance' function but > I'm not familiar enough with boost python & python !!... Any help or > advice will be _greatly_ appreciated :) Why do you need to do this? Such downcasting is usually the mark of a poor design. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From gwl at u.washington.edu Thu Nov 7 02:18:51 2002 From: gwl at u.washington.edu (Graeme Lufkin) Date: 06 Nov 2002 17:18:51 -0800 Subject: [C++-sig] contained structure access Message-ID: <1036631931.11127.12.camel@tigger.graemily.org> Okay, I think I understand what's going on, and why return_internal_reference<> does what I want. I used it, and it works. But if the default behavior is to return a copy, why did the other access/assignments work. That is, in the python code: > >>> at = Atom() > >>> print at.x > 0.0 > >>> at.x = 42 > >>> print at.x > 42.0 > >>> h = Holder() > >>> print h.a.x > 0.0 > >>> h.a.x = 43 > >>> print h.a.x > 0.0 > >>> h.a = at > >>> print h.a.x > 42.0 Why does 'at.x = 42' not also assign '42' to a temporary instance of the 'x' member variable? And it's not just built-in types, the assignment of 'h.a = at' works, it doesn't assign 'at' to a temporary 'a'. What am I missing? Another, unrelated question: Can operator[] be overloaded to act the same in Python, that is like __getitem__ ? I tried .def("__getitem__", &MyClass::operator[]) but it complained about sizeof() being applied to an unspecified type. Even more: overloading *= for a float. My class overloads *= for floats, and I'd like this to work in Python for integer and floating-point python types. So I did .def(self *= float()) similar to the tutorial example which uses int() instead. Now I can do the *= in Python, but only on integers! For example, I can do foo = MyClass() foo *= 2 but when I try for *= 3.14 I get a 'TypeError: can't apply sequence to non-int' or something like that. Any thoughts? -- - Graeme Lufkin gwl at u.washington.edu "The sleeper has awakened." From dave at boost-consulting.com Thu Nov 7 02:52:54 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Nov 2002 20:52:54 -0500 Subject: [C++-sig] contained structure access In-Reply-To: <1036631931.11127.12.camel@tigger.graemily.org> (Graeme Lufkin's message of "06 Nov 2002 17:18:51 -0800") References: <1036631931.11127.12.camel@tigger.graemily.org> Message-ID: Graeme Lufkin writes: > Okay, I think I understand what's going on, and why > return_internal_reference<> does what I want. I used it, and it works. > But if the default behavior is to return a copy, why did the other > access/assignments work. That is, in the python code: >> >>> at = Atom() >> >>> print at.x >> 0.0 >> >>> at.x = 42 >> >>> print at.x >> 42.0 >> >>> h = Holder() >> >>> print h.a.x >> 0.0 >> >>> h.a.x = 43 >> >>> print h.a.x >> 0.0 >> >>> h.a = at >> >>> print h.a.x >> 42.0 > Why does 'at.x = 42' not also assign '42' to a temporary instance of > the 'x' member variable? And it's not just built-in types, the > assignment of 'h.a = at' works, it doesn't assign 'at' to a temporary > 'a'. What am I missing? Try it in Python to find out: >>> class X(object): ... def get_x(self): ... print 'in get_x' ... return self.x ... def set_x(self, n): ... print 'in set_x(',n,')' ... self.x = n ... y = property(get_x,set_x) ... def __init__(self): ... self.x = 0 ... >>> x = X() >>> x.y in get_x 1 >>> x.y = 1 in set_x( 1 ) > Another, unrelated question: Can operator[] be overloaded to act the > same in Python, that is like __getitem__ ? Yes. > I tried > .def("__getitem__", &MyClass::operator[]) > but it complained about sizeof() being applied to an unspecified > type. Can you show the complete error message? > Even more: overloading *= for a float. My class overloads *= for > floats, and I'd like this to work in Python for integer and > floating-point python types. So I did > .def(self *= float()) > similar to the tutorial example which uses int() instead. Now I can do > the *= in Python, but only on integers! For example, I can do > foo = MyClass() > foo *= 2 > but when I try > for *= 3.14 > I get a 'TypeError: can't apply sequence to non-int' or something like > that. Any thoughts? This may be a Python bug, IIRC. Which version of Python are you using, and can you try with a newer Python? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From BPettersen at NAREX.com Thu Nov 7 03:11:21 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Wed, 6 Nov 2002 19:11:21 -0700 Subject: [C++-sig] fatal error C1204: compiler limit : internal structure overflow Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201774653@admin56.narex.com> I'm getting the above error when I added a new class to my BOOST_PYTHON_MODULE section. The error (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore /html/vcerrFatalErrorC1204.asp) indicates that my sources are too complex and need to be simplified (so far I'm only wrapping 8 classes, 5 of which are template specializations). How can I make MSVC happy? - Is it possible to split a BOOST_PYTHON_MODULE across several files? (I couldn't find any exmples in the docs, and looking at module_init.hpp I don't think it is possible). - Can I create multiple extensions (it isn't clear to me how I would use classes exposed in one module from another...) - Am I missing something obvious? Any help would be greatly appreciated. -- bjorn From dave at boost-consulting.com Thu Nov 7 03:47:39 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Nov 2002 21:47:39 -0500 Subject: [C++-sig] fatal error C1204: compiler limit : internal structure overflow In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201774653@admin56.narex.com> ("Bjorn Pettersen"'s message of "Wed, 6 Nov 2002 19:11:21 -0700") References: <60FB8BB7F0EFC7409B75EEEC13E2019201774653@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: > I'm getting the above error when I added a new class to my > BOOST_PYTHON_MODULE section. The error > (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore > /html/vcerrFatalErrorC1204.asp) indicates that my sources are too > complex and need to be simplified (so far I'm only wrapping 8 classes, 5 > of which are template specializations). How can I make MSVC happy? > > - Is it possible to split a BOOST_PYTHON_MODULE across several files? > (I couldn't find any exmples in the docs, and looking at > module_init.hpp > I don't think it is possible). Sure it's possible. It's just a function call. Break it up into smaller functions. > - Can I create multiple extensions Yes. > (it isn't clear to me how I would > use classes exposed in one module from another...) Just use 'em. It works. > - Am I missing something obvious? I don't know if it's obvious, but it's simple ;-) -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Thu Nov 7 03:51:36 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 06 Nov 2002 21:51:36 -0500 Subject: [C++-sig] contained structure access In-Reply-To: (David Abrahams's message of "Wed, 06 Nov 2002 20:52:54 -0500") References: <1036631931.11127.12.camel@tigger.graemily.org> Message-ID: David Abrahams writes: > Graeme Lufkin writes: > >> Even more: overloading *= for a float. My class overloads *= for >> floats, and I'd like this to work in Python for integer and >> floating-point python types. So I did >> .def(self *= float()) >> similar to the tutorial example which uses int() instead. Now I can do >> the *= in Python, but only on integers! For example, I can do >> foo = MyClass() >> foo *= 2 >> but when I try >> for *= 3.14 >> I get a 'TypeError: can't apply sequence to non-int' or something like >> that. Any thoughts? > > This may be a Python bug, IIRC. Yeah, in 2.2.1: >>> class X(object): ... def __imul__(self, x): ... print 'self *=',x ... return self ... >>> x = X() >>> x *= 3.14 Traceback (most recent call last): File "", line 1, in ? TypeError: can't multiply sequence to non-int > Which version of Python are you using, and can you try with a newer > Python? I think it's fixed for 2.2.2 -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From BPettersen at NAREX.com Thu Nov 7 05:44:13 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Wed, 6 Nov 2002 21:44:13 -0700 Subject: [C++-sig] fatal error C1204: compiler limit : internal structure overflow Message-ID: <60FB8BB7F0EFC7409B75EEEC13E201920177465E@admin56.narex.com> > From: David Abrahams [mailto:dave at boost-consulting.com] > > "Bjorn Pettersen" writes: > [snip] > > > > - Is it possible to split a BOOST_PYTHON_MODULE across > > several files? (I couldn't find any exmples in the > > docs, and looking at module_init.hpp > > I don't think it is possible). > > Sure it's possible. It's just a function call. Break it up > into smaller functions. Wow, that was simple :-) Thanks! -- bjorn From brett.calcott at paradise.net.nz Thu Nov 7 12:01:09 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Fri, 8 Nov 2002 00:01:09 +1300 Subject: [C++-sig] call_method Message-ID: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> Hi all, Firstly, thanks for the funky library - Dave and others. I am looking forward to making my development go a lot faster by scripting most of it and leaving just the core in c++. I somewhat overwhelmed by the sophistication of the methods involved to make this thing work so elegantly - so I am grappling to understand how to make it do what I want. (Likely that I should do what *it* wants..) First up - a documentation bug (if you haven't already found it). I have the download from boost.org - not CVS and I see this in call_method.html // Callback class class Base_callback : public Base { public: Base_callback(PyObject* self) : m_self(self) {} char const* class_name() const { return call_method(m_self, "class_name"); } ^^^^^^^^^^^^^^ char const* Base_name() const { return Base::class_name(); } private: PyObject* const m_self; }; That should be: char const* class_name() const { return call_method(m_self, "class_name"); } Right? That had me fooled for a bit. Now the problem: class agent { public: virtual char const *do_something() const { return "something"; } virtual ~agent() { } }; typedef boost::shared_ptr agent_ptr; typedef std::vector agents; class engine { public: void add_agent(const agent_ptr &a) { m_agents.push_back(a); } agents m_agents; }; BOOST_PYTHON_MODULE(pyengine) { using namespace boost::python; class_("agents") .def("__iter__", iterator()) ; class_, agent_ptr>("agent", init()) .def("name", &agent::name, return_value_policy()) .def("do_something", &agent::do_something) ; class_("engine", init<>()) .def("add_agent", &engine::add_agent) .add_property("agents" , make_getter(&engine::m_agents, return_internal_reference<>())) ; } This works fine as it is for creating engines and putting agents into it. What I want to do now is have the option of creating a derived agent "py_agent" which uses call_method() to allow python to "do_something". However, I want both of these types to be in able to be put into the vector of agents in the engine. To get this to work I need something like this I think: class py_agent : public agent { public: py_agent(PyObject* self = 0) : m_self(self) {} char const *do_something() const { return call_method(m_self, "do_something"); } PyObject* const m_self; }; But to use class_ on it I need to create another shared_ptr for the py_agent, typedef boost::shared_ptr py_agent_ptr; and then this: class_, py_agent_ptr, boost::noncopyable>("py_agent") .def("do_something", &py_agent::do_something) ; But now, I can't add a py_agent using the python exported "add_agent" function, as it is not the right type. I am used to using shared_ptr in vectors for containing derived types - so, as in this case, the engine can call "do_something" on all of them and they can all "do their thing". How, if at all, can I get this happening here... Cheers, Brett From dave at boost-consulting.com Thu Nov 7 14:03:56 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Nov 2002 08:03:56 -0500 Subject: [C++-sig] call_method In-Reply-To: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> ("Brett Calcott"'s message of "Fri, 8 Nov 2002 00:01:09 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > Hi all, > > Firstly, thanks for the funky library - Dave and others. I am > looking forward to making my development go a lot faster by > scripting most of it and leaving just the core in c++. > > I somewhat overwhelmed by the sophistication of the methods involved > to make this thing work so elegantly - so I am grappling to > understand how to make it do what I want. (Likely that I should do > what *it* wants..) The idea is for it to go the other way... :( > First up - a documentation bug (if you haven't already found it). I have the > download from boost.org - not CVS and I see this in call_method.html > > // Callback class > class Base_callback : public Base > { > public: > Base_callback(PyObject* self) : m_self(self) {} > > char const* class_name() const { return call_method(m_self, > "class_name"); } > ^^^^^^^^^^^^^^ > char const* Base_name() const { return Base::class_name(); } > private: > PyObject* const m_self; > }; > > That should be: > char const* class_name() const { return call_method(m_self, > "class_name"); } > > Right? That had me fooled for a bit. Right. Thanks, fixed in CVS. > Now the problem: > > But to use class_ on it I need to create another shared_ptr for the > py_agent, > > typedef boost::shared_ptr py_agent_ptr; > > and then this: > > class_, py_agent_ptr, boost::noncopyable>("py_agent") > .def("do_something", &py_agent::do_something) > ; > > But now, I can't add a py_agent using the python exported "add_agent" > function, as it is not the right type. Have you tried adding a call to implicitly_convertible() ?? > I am used to using shared_ptr in vectors for containing derived types - so, > as in this case, the engine can call "do_something" on all of them and they > can all "do their thing". How, if at all, can I get this happening here... I now have quite a pile of polymorphism-related feature requests pending, so please let me know if the above doesn't solve your problems. I'll add this to the list of things to address. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From n_lelong at hotmail.com Thu Nov 7 14:29:48 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Thu, 7 Nov 2002 14:29:48 +0100 Subject: [C++-sig] Python + Boost Python V2 + downcasting References: Message-ID: > > I even thought about implementing my own 'isinstance' function but > > I'm not familiar enough with boost python & python !!... Any help or > > advice will be _greatly_ appreciated :) > > Why do you need to do this? Such downcasting is usually the mark of a > poor design. Thanks for your reply, I'm aware that this design decision may not be the best - but it suits the needs I have for now... I have a tree structure representing hierarchical dependencies between elements of a graphical system. The objects have a similar base interface that is used to navigate through the graph - but each class of item has a set a specific properties. We decided to use a 'node class' identification system based on C++ RTTI because we did not want to reinvent the weel. Now, if I really can't get the correct info in Python, I'll have two choices: - propose a change in the node class identification system (i'd rather not) - drop Python (i'd rather not !). I believe that there must be a way to extract to RTTI info from the object holder as it is done to allow the call of a function that takes a Derived&(or *) in parameter - it would help me going on in my Python evaluation - before having to rethink the whole heart of the application ! Could you give me a few hints to create my own implementation of 'isinstance' as i don't have much time to investigate the boost python v2 internal structures ? Thank you, Nicolas. From dave at boost-consulting.com Thu Nov 7 16:09:04 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Nov 2002 10:09:04 -0500 Subject: [C++-sig] Python + Boost Python V2 + downcasting In-Reply-To: ("Nicolas Lelong"'s message of "Thu, 7 Nov 2002 14:29:48 +0100") References: Message-ID: "Nicolas Lelong" writes: >> > I even thought about implementing my own 'isinstance' function but >> > I'm not familiar enough with boost python & python !!... Any help or >> > advice will be _greatly_ appreciated :) >> >> Why do you need to do this? Such downcasting is usually the mark of a >> poor design. > > Thanks for your reply, > > I'm aware that this design decision may not be the best - but it > suits the needs I have for now... I have a tree structure > representing hierarchical dependencies between elements of a > graphical system. The objects have a similar base interface that is > used to navigate through the graph - but each class of item has a > set a specific properties. > > We decided to use a 'node class' identification system based on C++ RTTI > because we did not want to reinvent the weel. OK, I understand. > Now, if I really can't get the > correct info in Python, I'll have two choices: > - propose a change in the node class identification system (i'd rather not) > - drop Python (i'd rather not !). > > I believe that there must be a way to extract to RTTI info from the > object holder as it is done to allow the call of a function that > takes a Derived&(or *) in parameter - it would help me going on in > my Python evaluation - before having to rethink the whole heart of > the application ! Could you give me a few hints to create my own > implementation of 'isinstance' as i don't have much time to > investigate the boost python v2 internal structures ? Let's look for other solutions; I just don't think 'isinstance' is appropriate. You see, Python really is handling a class called 'Base', even when the pointer actually refers to a 'Derived', and Python's isinstance just crawls up the Python class hierarchy to find the class you're looking for. [digression: I notice that you're using return_internal_reference<>() to return the Base* from the ObjectServer. Does the ObjectServer actually control the lifetime of the objects, or is it simply holding pointers? I ask because I don't see a destructor, so in the code you sent, return_internal_reference<> is inappropriate (maybe you were just eliminating details for the sake of the post?) -- the point of return_internal_reference<> is to keep the owning object alive as long as the owned objects are also alive. If something else is managing their lifetimes, you may need another mechanism. ] Ultimately, I think the best solution is going to be to add a new kind of ReturnValuePolicy which uses typeid() on the pointer to get the most-derived class, looks up the corresponding Python class in the converter::registry, and builds a pointer_holder around it using the appropriate Python class type. Hmm, looking carefully, this might not require a new ReturnValuePolicy, and could be as simple as making some judicious changes to boost/python/object/make_instance.hpp.** This is just one of whole category of changes needed to support C++ runtime polymorphism really well. I'm currently trying to sort out my priorities at the moment; if I can secure funding for this work it will certainly get moved to the top of my queue. In the meantime, if the ObjectServer is really the owner of the C++ objects, you might consider storing boost::python::object in its m_objects array. If you convert your Derived objects to boost::python::object at their point of creation, the full dynamic type will be preserved for Python. -Dave **There are some open questions... for example, what happens if the most-derived C++ class hasn't been registered by the user with a class_<> declaration? It's possible to attempt to find a most-derived-registered class by using the facilities in libs/python/src/object/inheritance.cpp, but I'm not sure it's worth it, and that capability could be added later. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Thu Nov 7 16:17:24 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Nov 2002 10:17:24 -0500 Subject: [C++-sig] Python + Boost Python V2 + downcasting In-Reply-To: (David Abrahams's message of "Thu, 07 Nov 2002 10:09:04 -0500") References: Message-ID: I wrote: > Let's look for other solutions; I just don't think 'isinstance' is > appropriate. You see, Python really is handling a class called 'Base', > even when the pointer actually refers to a 'Derived', and Python's > isinstance just crawls up the Python class hierarchy to find the class > you're looking for. > Ultimately, I think the best solution is going to be to add a new kind > of ReturnValuePolicy which uses typeid() on the pointer to get the > most-derived class, looks up the corresponding Python class in the > converter::registry, and builds a pointer_holder around it using the > appropriate Python class type. Hmm, looking carefully, this might not > require a new ReturnValuePolicy, and could be as simple as making some > judicious changes to boost/python/object/make_instance.hpp.** In case it wasn't clear, the above change, if I can figure out how to do it, would make isinstance() work as you expect. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From rwgk at yahoo.com Thu Nov 7 18:08:12 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 7 Nov 2002 09:08:12 -0800 (PST) Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: Message-ID: <20021107170812.27263.qmail@web20205.mail.yahoo.com> Hi, Is there a plan for auto-generating bindings for template functions? Say I have a function template FloatType foo(FloatType const&); how would an auto-generating tool "know" what to use for FloatType? Sometimes I need bindings for more than one type, e.g. for void bar(std::vector const&). Another question is how to deal with class templates, e.g. template class my_container; Here one has to decide what to call the different Python types, e.g. my_container -> my_container_float, etc. (actually, I settled on creating a module my_container with types float, double etc., leading to e.g. f = my_container.float()). Ralf __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 From mike at bindkey.com Thu Nov 7 19:51:02 2002 From: mike at bindkey.com (Mike Rovner) Date: Thu, 7 Nov 2002 10:51:02 -0800 Subject: [C++-sig] custom iterator object Message-ID: I have the following class, implementing my iterator protocol: template class Iter { T* First(); T* Next(); } returning 0, when iteration is done. I'm trying to wrap it to Python iterator protocol: template struct PyIter { PyIter(IterFactory get_func) : started(false), it(get_func()) {} const T* next() { const T* res; if(started) res=it.Next(); else { started=true; res=it.First(); } if(res) return res; objects::set_stop_iteration_error(); return 0; } private: bool started; Iter it; }; but fill it's clumsy and not good. Can you point me the right way to do it. Thanks, Mike From dave at boost-consulting.com Thu Nov 7 20:21:16 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Nov 2002 14:21:16 -0500 Subject: [C++-sig] custom iterator object In-Reply-To: ("Mike Rovner"'s message of "Thu, 7 Nov 2002 10:51:02 -0800") References: Message-ID: "Mike Rovner" writes: > I have the following class, implementing my iterator protocol: > > template > class Iter > { > T* First(); > T* Next(); > } > returning 0, when iteration is done. > > I'm trying to wrap it to Python iterator protocol: > > template > struct PyIter > { > PyIter(IterFactory get_func) : started(false), it(get_func()) {} > > const T* next() { > const T* res; > if(started) > res=it.Next(); > else { > started=true; > res=it.First(); } > if(res) return res; > objects::set_stop_iteration_error(); > return 0; > } > private: > bool started; > Iter it; > }; > > but fill it's clumsy and not good. What's "not good" about it? > Can you point me the right way to do it. Boost.Python provides several ways to wrap regular C++ iterators as Python iterators. Did you consider using those? http://www.boost.org/libs/python/doc/v2/iterator.html -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From mike at bindkey.com Thu Nov 7 21:03:42 2002 From: mike at bindkey.com (Mike Rovner) Date: Thu, 7 Nov 2002 12:03:42 -0800 Subject: [C++-sig] Re: custom iterator object References: Message-ID: > > I have the following class, implementing my iterator protocol: > > > > template > > class Iter > > { > > T* First(); > > T* Next(); > > } > > returning 0, when iteration is done. > > > Boost.Python provides several ways to wrap regular C++ iterators as > Python iterators. Did you consider using those? Sure I did, but couldn't figure out how to do it ;) IMHO it's NOT a regular iterator because operations '*' and '++' are combined into 'Next'. > > I'm trying to wrap it to Python iterator protocol: > What's "not good" about it? I have problems with return value. In __iter__ I have to return self, but there is no Python self yet in wrapping class. So probably I have to duplicate part of the BPL iterator guts, but I got lost :( Mike From gwl at u.washington.edu Thu Nov 7 21:07:43 2002 From: gwl at u.washington.edu (Graeme Lufkin) Date: 07 Nov 2002 12:07:43 -0800 Subject: [C++-sig] contained structure access Message-ID: <1036699663.4248.25.camel@ida.astro.washington.edu> >> I tried >> .def("__getitem__", &MyClass::operator[]) >> but it complained about sizeof() being applied to an unspecified >> type. > >Can you show the complete error message? Aha, I wasn't being precise enough. My operator[] returns a reference, so that I can do things like m = MyClass() m[0] = 3.14 m[2] = 2.71828 If I change my operator[] to return a value, the .def() works, and I can access the values. If I leave it as returning a reference, and use return_internal_reference<>, it doesn't compile. Here's the code: struct Atom { double x, y, z; double& operator[](const int i) { switch(i) { case 0: return x; case 1: return y; case 2: return z; } return x; } }; class_("Atom") .def_readwrite("x", &Atom::x) .def_readwrite("y", &Atom::y) .def_readwrite("z", &Atom::z) .def("__getitem__", &Atom::operator[], return_internal_reference<>()); Given this, I get a long error chain with tons of templated goodness, the last few 'instantied from's of which follow: /net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/class.hpp:325: instantiated from `boost::python::class_::def_impl (const char *, Fn, const Keywords &, const Policies &, const char *, ...) [with Fn = double &(Atom::*) (int), Policies = boost::python::return_internal_reference<1, boost::python::default_call_policies>, Keywords = boost::python::detail::keywords<0>, T = Atom, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/class.hpp:369: instantiated from `boost::python::class_::dispatch_def (const void *, const char *, Fn, const A1 &) [with Fn = double &(Atom::*) (int), A1 = boost::python::return_internal_reference<1, boost::python::default_call_policies>, T = Atom, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' /net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/class.hpp:227: instantiated from `boost::python::class_::def (const char *, Arg1T, const Arg2T &) [with Arg1T = double &(Atom::*) (int), Arg2T = boost::python::return_internal_reference<1, boost::python::default_call_policies>, T = Atom, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_specified]' TestModule.cpp:26: instantiated from here /net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/object/make_instance.hpp:22: `sizeof' applied to incomplete type `boost::STATIC_ASSERTION_FAILURE' g++ -c -Wall -ftemplate-depth-100 -DBOOST_PYTHON_DYNAMIC_LIB -g -O0 -fno-inline -fPIC -I"../../../libs/python/TestModule" -isystem "/usr/include/python2.2" -isystem "/net/mondo-1/nbody/gwl/projects/boost_1_29_0" -o "../../../libs/python/TestModule/bin/TestModule.so/gcc/debug/runtime-link-dynamic/shared-linkable-true/TestModule.o" "TestModule.cpp" Hey, you asked for it! Seriously, if you want the whole thing, I'll email it to you directly. The other question: I'm still not sure I understand the business with properties and return_internal_reference<>. I don't get why the extra level of member-ness (i.e. x.y.z) reveals the copy business, which doesn't appear one level lower (i.e. x.y). But I can make it work, so maybe I'll just forget it. Regarding the *= float(), I'm using python 2.2, and will live with doing 'v = v * 2' until I can upgrade. Also, I commend you (Dave) on your ridiculously fast response time. You're making my life easier. -- - Graeme Lufkin gwl at u.washington.edu "The experiment was inconclusive, so we had to use statistics." From dave at boost-consulting.com Thu Nov 7 21:33:58 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Nov 2002 15:33:58 -0500 Subject: [C++-sig] Re: custom iterator object In-Reply-To: ("Mike Rovner"'s message of "Thu, 7 Nov 2002 12:03:42 -0800") References: Message-ID: "Mike Rovner" writes: >> > I have the following class, implementing my iterator protocol: >> > >> > template >> > class Iter >> > { >> > T* First(); >> > T* Next(); >> > } >> > returning 0, when iteration is done. >> > >> Boost.Python provides several ways to wrap regular C++ iterators as >> Python iterators. Did you consider using those? > > Sure I did, but couldn't figure out how to do it ;) > IMHO it's NOT a regular iterator because operations '*' and '++' are > combined into 'Next'. No, of course it's not. However, you could consider making a C++ iterator using, say, the Boost Iterator Adaptors library, and then wrapping that. Maybe that's too much work, though. >> > I'm trying to wrap it to Python iterator protocol: >> What's "not good" about it? > > I have problems with return value. In __iter__ I have to return > self, but there is no Python self yet in wrapping class. So > probably I have to duplicate part of the BPL iterator guts, but I > got lost :( I'm lost, too. You haven't shown enough of what you're trying to do for me to be able to help. Please try showing the code you hope to use to wrap this stuff, and add lots of comments to describe what's happening. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com From dave at boost-consulting.com Thu Nov 7 21:45:27 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Nov 2002 15:45:27 -0500 Subject: [C++-sig] contained structure access In-Reply-To: <1036699663.4248.25.camel@ida.astro.washington.edu> (Graeme Lufkin's message of "07 Nov 2002 12:07:43 -0800") References: <1036699663.4248.25.camel@ida.astro.washington.edu> Message-ID: Graeme Lufkin writes: >>> I tried >>> .def("__getitem__", &MyClass::operator[]) >>> but it complained about sizeof() being applied to an unspecified >>> type. >> >>Can you show the complete error message? > Aha, I wasn't being precise enough. My operator[] returns a reference, > so that I can do things like > m = MyClass() > m[0] = 3.14 > m[2] = 2.71828 > If I change my operator[] to return a value, the .def() works, and I can > access the values. If I leave it as returning a reference, and use > return_internal_reference<>, it doesn't compile. Here's the code: > > struct Atom { > double x, y, z; > double& operator[](const int i) { > switch(i) { > case 0: return x; > case 1: return y; > case 2: return z; > } > return x; > } > }; > class_("Atom") > .def_readwrite("x", &Atom::x) > .def_readwrite("y", &Atom::y) > .def_readwrite("z", &Atom::z) > .def("__getitem__", &Atom::operator[], return_internal_reference<>()); > > Given this, I get a long error chain with tons of templated goodness, > the last few 'instantied from's of which follow: So, did you look at this line? > /net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/object/make_instance.hpp:22: > `sizeof' applied to incomplete type > `boost::STATIC_ASSERTION_FAILURE' The source line is: BOOST_STATIC_ASSERT(is_class::value); Which means you can only return a reference to an object of class type. Since double is not of class type, it complains. Why don't you use return_value_policy instead? http://www.boost.org/libs/python/doc/v2/copy_non_const_reference.html > Hey, you asked for it! Seriously, if you want the whole thing, I'll > email it to you directly. > > The other question: I'm still not sure I understand the business with > properties and return_internal_reference<>. I don't get why the extra > level of member-ness (i.e. x.y.z) reveals the copy business, which > doesn't appear one level lower (i.e. x.y). But I can make it work, so > maybe I'll just forget it. Just remember that when reading a property, the result is returned by value unless you specify otherwise. So x.y.z = 1 becomes setattr(getattr(x, "y"), "z", 1) If you don't do something explicit to prevent it, getattr(x, "y") returns a copy of x's y member, so assigning to its z element changes the wrong object. > Regarding the *= float(), I'm using python 2.2, and will live with > doing 'v = v * 2' until I can upgrade. > Also, I commend you (Dave) on your ridiculously fast response time. > You're making my life easier. That's the aim. I just wish I had a little more time to spend on the Boost.Python code. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Thu Nov 7 22:12:57 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 7 Nov 2002 13:12:57 -0800 (PST) Subject: [C++-sig] Re: custom iterator object In-Reply-To: Message-ID: <20021107211257.69768.qmail@web20201.mail.yahoo.com> --- Mike Rovner wrote: > I have problems with return value. In __iter__ I have to return self, but > there is no Python self yet in wrapping class. > So probably I have to duplicate part of the BPL iterator guts, but I got > lost :( You could try this: inline boost::python::object pass_through(boost::python::object const& o) { return o; } class_(python_name) .def("next", next) .def("__iter__", pass_through) ; Full source: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/include/scitbx/boost_python/iterator_wrappers.h Ralf __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 From gwl at u.washington.edu Fri Nov 8 00:58:15 2002 From: gwl at u.washington.edu (Graeme Lufkin) Date: 07 Nov 2002 15:58:15 -0800 Subject: [C++-sig] Re: contained structure access Message-ID: <1036713496.4250.38.camel@ida.astro.washington.edu> >So, did you look at this line? > >> >/net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/object/make_instance.hpp:22: >> `sizeof' applied to incomplete type >> `boost::STATIC_ASSERTION_FAILURE' > >The source line is: > > BOOST_STATIC_ASSERT(is_class::value); > >Which means you can only return a reference to an object of class >type. Since double is not of class type, it complains. > >Why don't you use return_value_policy >instead? Aha! I have (sort of) seen the light. I think I'm beginning to understand these return_value_policy<> things. So I want my function to return a reference to a built-in type. But I want the actual object, not a copy, so that I can assign it to something. So I want reference_existing_object. However, this also only works on objects (same error as before). I tried using copy_non_const_reference, expecting that it would be assignable, but the change would be made to the copy, and thus not appear in the original object. However, when I tried to assign like this 'at[0] = 3', I got: TypeError: object doesn't support item assignment which confuses me again. >> The other question: I'm still not sure I understand the business with >> properties and return_internal_reference<>. I don't get why the extra >> level of member-ness (i.e. x.y.z) reveals the copy business, which >> doesn't appear one level lower (i.e. x.y). But I can make it work, so >> maybe I'll just forget it. > >Just remember that when reading a property, the result is returned by >value unless you specify otherwise. So x.y.z = 1 becomes > > setattr(getattr(x, "y"), "z", 1) > >If you don't do something explicit to prevent it, getattr(x, "y") >returns a copy of x's y member, so assigning to its z element changes >the wrong object. Aha again! I was not aware of the setattr() business. My picture of the situation was 'x.y = 2' becomes 'set(getattr(x, "y"), 2', so I thought the problem would have arisen in that call to getattr(). Instead it's 'setattr(x, "y", 2)' which works. Thanks for bearing with me. -- - Graeme Lufkin gwl at u.washington.edu "The experiment was inconclusive, so we had to use statistics." From dave at boost-consulting.com Fri Nov 8 02:27:39 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 07 Nov 2002 20:27:39 -0500 Subject: [C++-sig] Re: contained structure access In-Reply-To: <1036713496.4250.38.camel@ida.astro.washington.edu> (Graeme Lufkin's message of "07 Nov 2002 15:58:15 -0800") References: <1036713496.4250.38.camel@ida.astro.washington.edu> Message-ID: Graeme Lufkin writes: >>So, did you look at this line? >> >>> >>/net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/object/make_instance.hpp:22: >>> `sizeof' applied to incomplete type >>> `boost::STATIC_ASSERTION_FAILURE' >> >>The source line is: >> >> BOOST_STATIC_ASSERT(is_class::value); >> >>Which means you can only return a reference to an object of class >>type. Since double is not of class type, it complains. >> >>Why don't you use return_value_policy >>instead? > Aha! I have (sort of) seen the light. I think I'm beginning to > understand these return_value_policy<> things. So I want my function to > return a reference to a built-in type. You're asking it do do that by using return_internal_reference<>. I can't comment on what you want. > But I want the actual object, not a copy, so that I can assign it to > something. So I want reference_existing_object. However, this also > only works on objects (same error as before). But __getitem__ will never be called for x[y] = z in Python. You need __setitem__ for that. Python is not like C++; there are no references. I've said it before, and I'll say it again: You can learn a lot by experimenting in pure Python. You can also RTF(Python)M to find these things out. > I tried using copy_non_const_reference, expecting that it would be > assignable, but the change would be made to the copy, and thus not > appear in the original object. However, when I tried to assign like > this 'at[0] = 3', I got: TypeError: object doesn't support item > assignment which confuses me again. Because you didn't define __setitem__. You can reproduce the same error in Pure Python: >>> class X(object): ... def __getitem__(self, y): ... return 1 >>> X()[1] 1 >>> X()[1] = 2 # error >>Just remember that when reading a property, the result is returned by >>value unless you specify otherwise. So x.y.z = 1 becomes >> >> setattr(getattr(x, "y"), "z", 1) >> >>If you don't do something explicit to prevent it, getattr(x, "y") >>returns a copy of x's y member, so assigning to its z element changes >>the wrong object. > Aha again! I was not aware of the setattr() business. My picture of > the situation was 'x.y = 2' becomes 'set(getattr(x, "y"), 2', so I > thought the problem would have arisen in that call to getattr(). Because there are no references in Python, there's no such thing as setting anything which isn't indicated by a slice, item, or attribute. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brad.king at kitware.com Fri Nov 8 04:37:43 2002 From: brad.king at kitware.com (Brad King) Date: Thu, 7 Nov 2002 22:37:43 -0500 (EST) Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: <20021107170812.27263.qmail@web20205.mail.yahoo.com> Message-ID: Ralf, > Is there a plan for auto-generating bindings for template functions? Say > I have a function template FloatType foo(FloatType > const&); how would an auto-generating tool "know" what to use for > FloatType? Sometimes I need bindings for more than one type, e.g. for > void bar(std::vector const&). Another question is how to deal > with class templates, e.g. template class > my_container; Here one has to decide what to call the different Python > types, e.g. my_container -> my_container_float, etc. (actually, I > settled on creating a module my_container with types float, double etc., > leading to e.g. f = my_container.float()). I've been developing a tool called "CABLE" (Cable Automates Bindings for Language Extension). Take a look at http://public.kitware.com/Cable for more information. It already has a Tcl wrapper implementation that handles most of these problems. I plan to add a wrapper generator to the project that generates Boost.Python v2 input files. The name specification looks like this in a CABLE configuration file: namespace wrappers { typedef ::my_container my_container_float; namespace foo { typedef ::foo::bar bar; } } This will create a wrapper for my_container that is called my_container_float in the generated wrappers. It will also create a wrapper for "foo::bar" that is called "bar" in the generated wrappers, but in a namespace (or module) called "foo". The above seems pretty easy for class templates, but I've had trouble coming up with a good syntax for functions and function templates. There isn't really a problem when the function's template arguments can all be deduced because the function can keep its original name, and each instantiation becomes another overload. The problem occurs for functions like this: template void f() {} It must be called as "f()", and I'm not sure how we should go about specifying a name for this from a configuration point of view. It gets even more complicated when some of the arguments are deduced, but not all: template void f(B) {} This can be called as "f(3.4)" or "f(3.4)". If we have a set of calls: f(char()); f(float()); should they all be called "f_int" and become overloads in python? How does the user specify this in the config file? Any suggestions are welcome. -Brad From rwgk at yahoo.com Fri Nov 8 19:29:15 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 8 Nov 2002 10:29:15 -0800 (PST) Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: Message-ID: <20021108182915.32565.qmail@web20208.mail.yahoo.com> --- Brad King wrote: > I've been developing a tool called "CABLE" (Cable Automates Bindings for > Language Extension). Take a look at http://public.kitware.com/Cable for > more information. It already has a Tcl wrapper implementation that > handles most of these problems. I plan to add a wrapper generator to the > project that generates Boost.Python v2 input files. Taking a second look... Cool, no third syntax to learn! Even the "configuration files" are pure C++! To me this is a very important point. Currently this information is burried a bit in the "Running" page (I didn't get there when I first looked). It could be helpful to have a dedicated "Configuration" section and to highlight the "no third syntax" point near the beginning of the front page. Your use of typedef's forces you to require implicit template instantiations. How about something like this: namespace wrappers { // instead of typedef ::Bar Bar_int; struct Bar_int : Bar {}; } Am I right to assume that this will instantiate Bar? > It must be called as "f()", and I'm not sure how we should go about > specifying a name for this from a configuration point of view. It gets > even more complicated when some of the arguments are deduced, but not all: > > template void f(B) {} > > This can be called as "f(3.4)" or "f(3.4)". If we have > a set of calls: > > f(char()); > f(float()); > > should they all be called "f_int" and become overloads in python? How > does the user specify this in the config file? Any suggestions are > welcome. Could something like this work? namespace cable { template void wrap(T) {} } namespace wrappers { // to specify that they should all be called "f_int" void f_int() { cable::wrap(f); cable::wrap(f); } // or alternatively void f_int_double() { cable::wrap(f); } } One of the great features of Boost.Python is that you can .def Python methods that have no equivalent in C++, most importantly the methods to support pickling (__getinitarge__, __getstate__, __setstate__) but also methods such as __repr__ or __str__. Suggestion: namespace wrappers { struct Bar_int : Bar { typedef Bar w_t; // "uu" == "underscore underscore" static uu_repr(w_t const& self) { /* code here */ } static any_additional_ordinary_method(w_t const& self) { /* code here */ } }; } Ralf __________________________________________________ Do you Yahoo!? HotJobs - Search new jobs daily now http://hotjobs.yahoo.com/ From mike at bindkey.com Fri Nov 8 19:53:07 2002 From: mike at bindkey.com (Mike Rovner) Date: Fri, 8 Nov 2002 10:53:07 -0800 Subject: [C++-sig] Re: Re: custom iterator object References: Message-ID: "David Abrahams" wrote in message news:uy9853yrt.fsf at boost-consulting.com... > "Mike Rovner" writes: > > >> > I have the following class, implementing my iterator protocol: > >> > > >> > template > >> > class Iter > >> > { > >> > T* First(); > >> > T* Next(); > >> > } > >> > returning 0, when iteration is done. > >> > > >> Boost.Python provides several ways to wrap regular C++ iterators as > >> Python iterators. Did you consider using those? > > > > Sure I did, but couldn't figure out how to do it ;) > > IMHO it's NOT a regular iterator because operations '*' and '++' are > > combined into 'Next'. > > No, of course it's not. However, you could consider making a C++ > iterator using, say, the Boost Iterator Adaptors library, and then > wrapping that. Maybe that's too much work, though. > > >> > I'm trying to wrap it to Python iterator protocol: > >> What's "not good" about it? > > > > I have problems with return value. In __iter__ I have to return > > self, but there is no Python self yet in wrapping class. So > > probably I have to duplicate part of the BPL iterator guts, but I > > got lost :( > > I'm lost, too. You haven't shown enough of what you're trying to do > for me to be able to help. Please try showing the code you hope to use > to wrap this stuff, and add lots of comments to describe what's > happening. > So I have custom iterator 'Iter' as shown above. It's like Python iterator, so I tend to use it instead of wrapping in iterator. Now I have a class: class Scheme { Iter A(); Iter B(); Iter C(); } which I want to exposure. So I write: BOOST_PYTHON_MODULE(Py1) { class_("Scheme") .def("__iter__", ???(&Scheme::A)) .add_property("b", ???(&Scheme::B)) .add_property("c", ??(&Scheme::C)) ; } to pretend objects itself acts as iterator A, b and c as B and C. But I have trouble in places ???. I need a Python iterator object there like 'iterator' or 'range' functions return, but first I need to instantiate Iter with A|B|C member parameter to create a custom iterator. I can wrap an Iter as typedef Iter (*GetIterFunc)(); template struct PyIter { PyIter(GetLrIterFunc const get_func) : started(false), it(get_func()) {} const T* begin() {return it.First();} const T* end() {return 0;} const T* operator++() {return v=it.Next();} const T operator*() {return *v;} private: bool started; T* v; Iter it; }; class_("PyIter", init()) .def("__iter__", range(&PyIter::begin, &PyIter::end)) but I still don't know how to instantiate it. From dave at boost-consulting.com Fri Nov 8 21:21:45 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 08 Nov 2002 15:21:45 -0500 Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: <20021108182915.32565.qmail@web20208.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Fri, 8 Nov 2002 10:29:15 -0800 (PST)") References: <20021108182915.32565.qmail@web20208.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- Brad King wrote: >> I've been developing a tool called "CABLE" (Cable Automates Bindings for >> Language Extension). Take a look at http://public.kitware.com/Cable for >> more information. It already has a Tcl wrapper implementation that >> handles most of these problems. I plan to add a wrapper generator to the >> project that generates Boost.Python v2 input files. > > Taking a second look... Cool, no third syntax to learn! Even the "configuration > files" are pure C++! Wow, it's just another C++ layer on top of Boost.Python? That is pretty cool! > To me this is a very important point. Currently this information is > burried a bit in the "Running" page (I didn't get there when I first > looked). It could be helpful to have a dedicated "Configuration" > section and to highlight the "no third syntax" point near the > beginning of the front page. > > Your use of typedef's forces you to require implicit template instantiations. > How about something like this: > > namespace wrappers > { > // instead of typedef ::Bar Bar_int; > struct Bar_int : Bar {}; > } > > Am I right to assume that this will instantiate Bar? Yes, it will instantiate Bar. But then you also have to write forwarding constructors. And anyway, what's wrong with implicit template instantiations? Perhaps a more interesting alternative would be to have the user supply explicit instantiations for the templates she wants to wrap. However, with a function template, you may end up wanting to wrap a whole family of instantiations, and that family might be deducible from various lists. For example: typedef mpl::vector< signed char, int, short, long, float, double , long double> signed_types; // now instantiate all versions of g(T,U) where T and U both come // from signed_types. I haven't looked at CABLE closely, but if it really is pure C++ configuration, something like the above should be possible. >> It must be called as "f()", and I'm not sure how we should go about >> specifying a name for this from a configuration point of view. It gets >> even more complicated when some of the arguments are deduced, but not all: >> >> template void f(B) {} >> >> This can be called as "f(3.4)" or "f(3.4)". If we have >> a set of calls: >> >> f(char()); >> f(float()); >> >> should they all be called "f_int" and become overloads in python? How >> does the user specify this in the config file? Any suggestions are >> welcome. > > Could something like this work? > > namespace cable { > template void wrap(T) {} > } > > namespace wrappers > { > // to specify that they should all be called "f_int" > void f_int() > { > cable::wrap(f); > cable::wrap(f); > } > > // or alternatively > void f_int_double() > { > cable::wrap(f); > } > } This is an interesting idea. Maybe something like Boost.Python's support for optional arguments (http://www.boost.org/libs/python/doc/v2/overloads.html) could come in handy here? > One of the great features of Boost.Python is that you can .def Python methods > that have no equivalent in C++, most importantly the methods to support > pickling (__getinitarge__, __getstate__, __setstate__) but also methods such as > __repr__ or __str__. Suggestion: > > namespace wrappers > { > struct Bar_int : Bar > { > typedef Bar w_t; > > // "uu" == "underscore underscore" > static > uu_repr(w_t const& self) { /* code here */ } > > static > any_additional_ordinary_method(w_t const& self) { /* code here */ } > }; > } I think the constructor forwarding problem probably means this direction isn't viable, but others may disagree. BTW, this is very exciting! I'm looking forward to supporting recent Boost.Python requests, especially those related to CABLE, in the near future. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Fri Nov 8 22:49:55 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 8 Nov 2002 13:49:55 -0800 (PST) Subject: [C++-sig] Re: Auto-Generation and BPL v2 In-Reply-To: Message-ID: <20021108214955.25705.qmail@web20205.mail.yahoo.com> --- David Abrahams wrote: > Wow, it's just another C++ layer on top of Boost.Python? That is > pretty cool! My suggestions are based on the naive assumption that the "configuration code" has to conform to the C++ syntax, but is not actually used by the C++ compiler (even #ifdef'ed out?). IIUC Cable reuses the C++ parser, but then has its own machinery for interpreting the abstract syntax tree (XML representation). The syntax is identical, but the semantics in namespace "_cable_" or "wrappers" are Cable-specific. Brad, is this correct? > > namespace cable { > > template void wrap(T) {} > > } > > > > namespace wrappers > > { > > // to specify that they should all be called "f_int" > > void f_int() > > { > > cable::wrap(f); > > cable::wrap(f); > > } > > > > // or alternatively > > void f_int_double() > > { > > cable::wrap(f); > > } > > } This idea is obsolete if my assumption above is not correct. If my assumption is correct I see a whole new universe of possibilities in front of us. Ralf __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 From texrmex at yahoo.com Fri Nov 8 23:16:50 2002 From: texrmex at yahoo.com (Tex Riddell) Date: Fri, 8 Nov 2002 14:16:50 -0800 (PST) Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings Message-ID: <20021108221650.98601.qmail@web14504.mail.yahoo.com> I posted this question to the boost-users yahoo group, but I realized from the response to another message on that group regarding Boost.Python that I should send boost python questions to this list instead. ___________________________ First, I'm excited about the new work that's been done with Boost Python v2. I can't wait to see if it's enough to overcome the pitfalls that prevented me from getting past the evaluation stage with v1. I'm using VC7 IDE to build my project and link to python22.lib and boost_python.lib (built with VC7 command line tools using bjam). I'm attempting to extend and embed in my existing project, so I'm not building a dll, but and exe. First of all, can I do this? When it links it says "Creating library ....lib and object ....exp", and still creates an exe. If I don't include my test module (and thus boost/python.hpp) I don't get this message. I'm assuming that by defining a module, boost defines exports and the linker then creates the lib and exp, since there were exports? Although I've built dlls before, I really don't know the inner workings of the process. The following is a brief example of my module. At the bottom is a simple test function that I'm calling just to test importing of the module. When I call TestModule(), I get 2 memory leaks from the module definition section, one from the class definition, and the other from the method definition. If I remove these, I get no memory leaks, and if I add more classes and methods, I get one 12 byte leak per class and one 12 byte leak per method I add. I do not get a leak from defining the top level function "greet". /////////////////////////////////////////////////// #include using namespace boost::python; namespace { const char * greet() { return "Hello World"; } class CSimple { public: bool Test() { return true; } }; }; BOOST_PYTHON_MODULE(Test) { def("greet", greet); class_("Simple") .def("Test", &CSimple::Test) ; } void TestModule() { Py_Initialize(); initTest(); Py_Finalize(); } /////////////////////////////////////////////////// In addition to the memory leaks, I get a number of compiler warnings, similar to the following: d:\Boost\boost\python\instance_holder.hpp(18) : warning C4275: non dll-interface class 'boost::noncopyable' used as base for dll-interface struct 'boost::python::instance_holder' d:\Boost\boost\utility.hpp(50) : see declaration of 'boost::noncopyable' d:\Boost\boost\python\instance_holder.hpp(17) : see declaration of 'boost::python::instance_holder' *and* d:\Boost\boost\python\detail\exception_handler.hpp(34) : warning C4251: 'boost::python::detail::exception_handler::m_impl' : class 'boost::function2' needs to have dll-interface to be used by clients of struct 'boost::python::detail::exception_handler' with [ R=bool, T0=const boost::python::detail::exception_handler &, T1=const boost::function0 &, Policy=boost::empty_function_policy, Mixin=boost::empty_function_mixin, Allocator=int ] I was wondering if my project is not set up properly, and if these warnings might have something to do with the memory leaks. In v1 there was a vc project you could use for building boost python. This works well if you are planning on linking to a vc built project, since you can make sure your settings, paths and libs are consistent between the boost python lib and your project. I currently have 3 different sets of build tools (yes, 3 compilers) on this box, with several different versions of standard and other libraries, so making sure I have control of the paths and settings used is very important. This is one reason I'm weary of the jam environment. It's yet another build environment, one that I'm not familiar with, and one that I'm not going to be using with any other projects except to build boost python. So a question would be: how easy would it be for me to set up a VC project for building boost python? Has this already been done? Or am I barking up the wrong tree? Thanks in advance, -Tex __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 From brett.calcott at paradise.net.nz Sat Nov 9 02:12:03 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Nov 2002 14:12:03 +1300 Subject: [C++-sig] Constructors in callback classes. Message-ID: <001f01c2878d$26b8a9d0$2e6e4fcb@hare> Hi, Callback classes look like this: class py_agent : public agent { public: py_agent(PyObject* self) : m_self(self) {} char const *do_something() const { using namespace boost::python; return call_method(m_self, "do_something"); } PyObject* const m_self; }; But what if the parent class "agent" has no default constructor. Can I pass through arguments as well as the PyObject * ? It wasn't obvious what I should do here. Cheers, Brett From brett.calcott at paradise.net.nz Sat Nov 9 02:08:21 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Nov 2002 14:08:21 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> Message-ID: <001e01c2878d$26a34d10$2e6e4fcb@hare> Hi all, (Sorry for the delay in getting back David) > Have you tried adding a call to > > implicitly_convertible() > Damn. I Should have found that really... It works fine now. Yay! However, the example I hacked up displays a weird bug. The virtual function returns a char const *, and when I subclass this in python and return a string it throws an error: ReferenceError: Attempt to return dangling pointer to object of type: char V:/src/boost_python_test/test>python test.py ...but only if there is a space in the string returned. This must be some weird side effect. Or returning a char const * from python may just be plain dodgy. Anyway I thought you might want to know about it. Note: VC6 SP5 - XP Professional. Here's the code: namespace { class agent { public: agent() { } virtual char const *do_something() const { return "agent"; } virtual ~agent() { } }; typedef boost::shared_ptr agent_ptr; typedef std::vector agents; class py_agent : public agent { public: py_agent(PyObject* self) : m_self(self) {} char const *do_something() const { using namespace boost::python; return call_method(m_self, "do_something"); } PyObject* const m_self; }; typedef boost::shared_ptr py_agent_ptr; class engine { public: engine() {} void add_agent(const agent_ptr &a) { m_agents.push_back(a); } agents m_agents; }; } BOOST_PYTHON_MODULE(simple) { using namespace boost::python; implicitly_convertible(); class_("agents") .def("__iter__", iterator()) ; class_, agent_ptr>("agent") .def("do_something", &agent::do_something) ; class_, py_agent_ptr, boost::noncopyable>("py_agent") .def("do_something", &agent::do_something) ; class_("engine", init<>()) .def("add_agent", &engine::add_agent) .add_property("agents" , make_getter(&engine::m_agents, return_internal_reference<>())) ; } and the python: import simple e = simple.engine() class my_agent(simple.py_agent): def do_something(self): # return "my agent here" ******CRASH**** return "my_agent_here" # this is okay a1 = simple.agent() a2 = my_agent() e.add_agent(a1) e.add_agent(a2) for a in e.agents: print a.do_something() Cheers, Brett From brett.calcott at paradise.net.nz Sat Nov 9 02:51:33 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Nov 2002 14:51:33 +1300 Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings References: <20021108221650.98601.qmail@web14504.mail.yahoo.com> Message-ID: <002b01c28792$89e02ba0$2e6e4fcb@hare> Hi Tex, You have asked a few questions in your post. I am only going to answer one of them. > So a question would be: how easy would it be for me to set up a VC > project for building boost python? Has this already been done? Or am > I barking up the wrong tree? > It is *reasonably* easy to do this - though I am using VC6. If you do a >bjam -and2 at the command line and redirect it to a file you will get all of the command line options that are generated for building the DLL. You need to create DLL project, dump all of the .cpp files into it, then make sure that the command line that is being generated is the same (well, the important bits anyway). Look in the Project Options window to see this. The only problem I came across was the /Zm800 option, which is needed to compile the inheritance.cpp file (otherwise you get a compiler blowup). There seems to be NO place that I could enter this in the IDE! I fudged it by stuffing it into the .dsp file on what looked like the right line where the other options were. Of course, it gets overwritten if I change anything - but it works fine. Maybe you can set it directly in VC7? Once I tidy my test hacking environment up, I will post a copy. (2-3 days away) Cheers, Brett From dave at boost-consulting.com Sat Nov 9 04:51:08 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 08 Nov 2002 22:51:08 -0500 Subject: [C++-sig] Constructors in callback classes. In-Reply-To: <001f01c2878d$26b8a9d0$2e6e4fcb@hare> ("Brett Calcott"'s message of "Sat, 9 Nov 2002 14:12:03 +1300") References: <001f01c2878d$26b8a9d0$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > Hi, > > Callback classes look like this: > > class py_agent : public agent > { > public: > py_agent(PyObject* self) : m_self(self) {} > > char const *do_something() const > { > using namespace boost::python; > return call_method(m_self, "do_something"); > } > > PyObject* const m_self; > > }; > > But what if the parent class "agent" has no default constructor. Can > I pass through arguments as well as the PyObject * ? Yes, in fact, you should. > It wasn't obvious what I should do here. Good point. I need to add a note in http://www.boost.org/libs/python/doc/v2/class.html#HeldType and Joel should add something in http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html Thanks for pointing it out. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Sat Nov 9 05:37:13 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Nov 2002 17:37:13 +1300 Subject: [C++-sig] Constructors in callback classes. References: <001f01c2878d$26b8a9d0$2e6e4fcb@hare> Message-ID: <001201c287a9$d9e288c0$2e6e4fcb@hare> > > Good point. I need to add a note in > http://www.boost.org/libs/python/doc/v2/class.html#HeldType > and Joel should add something in > http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.ht ml > > Thanks for pointing it out. In the same area, the class_ definition is like this (4 args): template , class HeldType = T , class NonCopyable = unspecified > class class_ : .... But the docs and examples of wrapping do this (Only 3 args): class_("Base", no_init) This is confusing. I had a look at the header and see you do something I don't (yet) understand to make this happen. Very cool. Cheers, Brett From brett.calcott at paradise.net.nz Sat Nov 9 07:53:44 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Nov 2002 19:53:44 +1300 Subject: [C++-sig] MSVC project file Message-ID: <003901c287bc$c078f870$2e6e4fcb@hare> Hi all, For those interested here is a MS project file that builds boost_python. Create a directory under boost/libs/python/build I called mine ./msvc-project. Drop the file into the directory and then load it in DevStudio and build. It will create a ./bin underneath it with boost_python.dll and boost_python_d.dll. David, (if you are listening) given the work in Boost.Build I'm not sure if you are interested in this at all - though I would hazard a guess that there will be more requests. In any case - adding some extra warning switches to the detail/config.hpp makes the build a little easier to watch both for bjam and DevStudio. --- config_old.hpp Sat Nov 09 19:47:06 2002 +++ config.hpp Sat Nov 09 16:19:26 2002 @@ -32,7 +32,11 @@ # define BOOST_MSVC6_OR_EARLIER 1 # endif -# pragma warning (disable : 4786) +# pragma warning (disable : 4786) // disable truncated debug symbols +# pragma warning (disable : 4251) // disable exported dll function +# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or 'false' +# pragma warning (disable : 4275) // non dll-interface class + # elif defined(__ICL) && __ICL < 600 // Intel C++ 5 -------------- next part -------------- A non-text attachment was scrubbed... Name: boost_python.dsp Type: application/octet-stream Size: 5834 bytes Desc: not available URL: From brett.calcott at paradise.net.nz Sat Nov 9 08:16:43 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Nov 2002 20:16:43 +1300 Subject: [C++-sig] MSVC project file References: <003901c287bc$c078f870$2e6e4fcb@hare> Message-ID: <004e01c287bf$f5b63ea0$2e6e4fcb@hare> ...and I forgot to mention. I haven't verified the resultant build against that made by bjam. All I know is that it works with my current 'experiments'. If there are any problems, you might want to relink with the 'official' build before posting a bug - for the moment at least. Brett From brett.calcott at paradise.net.nz Sat Nov 9 08:28:11 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 9 Nov 2002 20:28:11 +1300 Subject: [C++-sig] Constructors in callback classes. References: <001f01c2878d$26b8a9d0$2e6e4fcb@hare> Message-ID: <006001c287c1$9194ef50$2e6e4fcb@hare> > > > It wasn't obvious what I should do here. > > Good point. I need to add a note in > http://www.boost.org/libs/python/doc/v2/class.html#HeldType > and Joel should add something in > http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.ht ml > > Thanks for pointing it out. > -- For those tuned in... Okay, now I get it. You don't have to declare the PyObject * in the init<..> list. Boost.Python already knows it there... Brett From brett.calcott at paradise.net.nz Sat Nov 9 12:59:34 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 10 Nov 2002 00:59:34 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> Message-ID: <001901c287e7$792e7c80$2e6e4fcb@hare> I spoke to soon. It seems that it works *sometimes*. Other times it crashes and returns with a C++ exception. There seems to be some corruption going on as I get some strange results. This is what happens. I have a base type and a derived type which calls back to python. I have a vector of base type shared pointers. In python I put a few python subclassed types into the vector. I then get them out and try to call the virtual function in them. The first one I get out works, it actually makes it to the python callback code. The next one returns with a C++ runtime exception error Debugging the code it looks as if the m_self member that is held in the callback class has been deleted - causing the crash. I have included the code (which is very grubby). Let me know if you need more. Apologies that I can't find this myself. I get lost pretty fast in amongst the templates and preprocessor stuff. Cheers, Brett ps. I tried this with both the project build dll and the bjam one. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.py URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: pch.h Type: application/octet-stream Size: 880 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: test.cpp Type: application/octet-stream Size: 2191 bytes Desc: not available URL: From achim.domma at syynx.de Sat Nov 9 19:55:39 2002 From: achim.domma at syynx.de (Achim Domma) Date: Sat, 9 Nov 2002 19:55:39 +0100 Subject: [jamboost] Re: [C++-sig] gcc-link-action actions to long (max 10240) In-Reply-To: Message-ID: > -----Original Message----- > From: David Abrahams [mailto:dave at boost-consulting.com] > Another approach is to break your extension module into libraries: > > lib part1 : a.cpp b.cpp c.cpp ; > lib part2 : d.cpp e.cpp f.cpp ; > extension ext : part1 part2 ../build/boost_python ; Hi Dave, I tried this, but the libs do not have the same settings, which are set automaticaly for extensions. This means, that and the python include files are not found. I know I could add "my/path/to/boost" to my jamfile, but is there a simpler way to use the settings of the extension target? thanks, Achim From nobbis at mcs.vuw.ac.nz Sat Nov 9 22:10:10 2002 From: nobbis at mcs.vuw.ac.nz (Tim Field) Date: 10 Nov 2002 10:10:10 +1300 Subject: [C++-sig] call_method In-Reply-To: <001901c287e7$792e7c80$2e6e4fcb@hare> References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> Message-ID: <1036876211.17159.10.camel@beast> On Sun, 2002-11-10 at 00:59, Brett Calcott wrote: > The next one returns with a C++ runtime exception error > Debugging the code it looks as if the m_self member that is held in the > callback class has been deleted - causing the crash. Hey Brett, My (relatively uninformed) guess is that the inheritance/call-back issue is a red herring -- I think the agent is getting garbage-collected before you call 'do_something' on it. I reckon you should just replace .def("add_agent", &engine::add_agent) with .def("add_agent", &engine::add_agent, with_custodian_and_ward<1, 2>()) so that the lifetime of the agent object is linked to that of the engine. I could be wrong, of course (has been known to happen)... Hope that helps, Tim From brett.calcott at paradise.net.nz Sun Nov 10 01:04:15 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 10 Nov 2002 13:04:15 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <1036876211.17159.10.camel@beast> Message-ID: <005001c2884c$b7fa9560$2e6e4fcb@hare> Hiya Tim, > > My (relatively uninformed) guess is that the inheritance/call-back issue > is a red herring -- I think the agent is getting garbage-collected > before you call 'do_something' on it. I reckon you should just replace > > .def("add_agent", &engine::add_agent) > > with > > .def("add_agent", &engine::add_agent, with_custodian_and_ward<1, 2>()) > > so that the lifetime of the agent object is linked to that of the > engine. I could be wrong, of course (has been known to happen)... > > > Hope that helps, Yup, that helps a lot. So much so that it actually works now :) Whew... I had assumed that since Boost.Python passed me the PyObject *self, that the lifetime of the PyObject was already bound to my C++ object. That is what I actually want, as binding the agent to the engine is only safe if I the C++ engine is responsible for the lifetime of the C++ agent (actually a reasonable assumption is this case). Of course doing something like that requires cyclic dependencies as the python object holds a shared_ptr to the C++ object. Hmmm. How hard would that be... Thanks Tim, Brett From dave at boost-consulting.com Sun Nov 10 03:01:00 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Nov 2002 21:01:00 -0500 Subject: [jamboost] Re: [C++-sig] gcc-link-action actions to long (max 10240) In-Reply-To: ("Achim Domma"'s message of "Sat, 9 Nov 2002 19:55:39 +0100") References: Message-ID: "Achim Domma" writes: >> -----Original Message----- >> From: David Abrahams [mailto:dave at boost-consulting.com] >> Another approach is to break your extension module into libraries: >> >> lib part1 : a.cpp b.cpp c.cpp ; >> lib part2 : d.cpp e.cpp f.cpp ; >> extension ext : part1 part2 ../build/boost_python ; > > Hi Dave, > > I tried this, but the libs do not have the same settings, which are set > automaticaly for extensions. This means, that and the > python include files are not found. I know I could add > "my/path/to/boost" to my jamfile, but is there a simpler way to use > the settings of the extension target? > Oh, yeah: try lib part1 : a.cpp b.cpp c.cpp : $(PYTHON_PROPERTIES) ; etc. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 10 04:15:10 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Nov 2002 22:15:10 -0500 Subject: [C++-sig] call_method In-Reply-To: <001e01c2878d$26a34d10$2e6e4fcb@hare> ("Brett Calcott"'s message of "Sat, 9 Nov 2002 14:08:21 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > Hi all, > > (Sorry for the delay in getting back David) > >> Have you tried adding a call to >> >> implicitly_convertible() >> > > Damn. I Should have found that really... > It works fine now. Yay! > > However, the example I hacked up displays a weird bug. The virtual function > returns a char const *, and when I subclass this in python and return a > string it throws an error: > > ReferenceError: Attempt to return dangling pointer to object of type: char > V:/src/boost_python_test/test>python test.py > > ...but only if there is a space in the string returned. This must be some > weird side effect. Or returning a char const * from python may just be plain > dodgy. It's not exactly dodgy, but you have to be somewhat careful. When you convert from a Python string to a char const*, you're getting a pointer to the internals of that Python object. If the Python object you're pointing into has only a single reference (because it's the unique return value of the function you just called), then by the time your C++ function returns it will have zero references. At that point your char const* will be pointing at invalid memory. The library is protecting you by throwing an exception instead. Read all about it at http://www.boost.org/libs/python/doc/v2/callbacks.html#result_handling So if you're going to return a char const*, you'd better be sure it points into some object that you know will persist past the call. Returning std::string instead works much more uniformly, because a C++ std::string owns its resources. > and the python: > > import simple > > e = simple.engine() > > class my_agent(simple.py_agent): > def do_something(self): > # return "my agent here" ******CRASH**** > return "my_agent_here" # this is okay Note: this is not a ******CRASH****, since you got a nice Python exception out of it. A ******CRASH**** looks like a core dump or other unrecoverable program error -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Sun Nov 10 05:06:50 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 10 Nov 2002 17:06:50 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare> Message-ID: <003001c2886e$99cf8790$2e6e4fcb@hare> From: "David Abrahams" > > > Note: this is not a ******CRASH****, since you got a nice Python > exception out of it. A ******CRASH**** looks like a core dump or other > unrecoverable program error > Ok, I'll use ****IT NOT DOING WHAT I WANT!**** or ****I MUST READ MORE DOCUMENTATION**** from now on :) Cheers, Brett From dave at boost-consulting.com Sun Nov 10 05:13:24 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Nov 2002 23:13:24 -0500 Subject: [C++-sig] call_method In-Reply-To: <001901c287e7$792e7c80$2e6e4fcb@hare> ("Brett Calcott"'s message of "Sun, 10 Nov 2002 00:59:34 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > I spoke to soon. It seems that it works *sometimes*. Other times it > crashes What do you mean by "crashes"?... Oh, this one really is a crash. > and returns with a C++ exception. Really? don't you mean a Python exception?... oh, I guess you don't. What do you mean by "returns"? Usually "return" and "throw/raise" are mutually-exclusive. You can only do one or the other. Incidentally, if you want to see what's really happening with the crash, #include "$BOOST_ROOT/libs/python/test/module_tail.cpp" at the end of your source file. > There seems to be some corruption going on as I get some strange > results. > > This is what happens. > I have a base type and a derived type which calls back to python. > I have a vector of base type shared pointers. > In python I put a few python subclassed types into the vector. > I then get them out and try to call the virtual function in them. > The first one I get out works, it actually makes it to the python callback > code. > The next one returns with a C++ runtime exception error > Debugging the code it looks as if the m_self member that is held in the > callback class has been deleted - causing the crash. > > I have included the code (which is very grubby). Let me know if you need > more. > > Apologies that I can't find this myself. I get lost pretty fast in amongst > the templates and preprocessor stuff. It has nothing to do with all that. The first thing I notice is that what you're doing makes no sense: class_, agent_ptr>("agent", init<>()) .def("do_something", &agent::do_something) ; class_, py_agent_ptr, boost::noncopyable> ("py_agent", init<>()) .def("do_something", &agent::do_something) ; You can't wrap class "agent" two different ways. I probably ought to generate some kind of assertion for this, but life is short... Secondly, you've got a lifetime management problem, and this is what's causing the crash. The basic model of Boost.Python is that Python objects manage the lifetimes of the C++ objects they wrap, not the other way around. Reviewing your code for a moment: class py_agent : public agent { public: py_agent(PyObject* self) : m_self(self) { assert(self); } ... Note that the initial PyObject* passed to the py_agent constructor is just a raw pointer. The Python object actually contains a shared_ptr, so when the Python object is deleted, if there are no other copies of this shared_ptr, the py_agent object dies, too. However, by sticking the shared_ptr into a vector in your engine class, you keep the py_agent object alive longer than the Python object which wraps it. If nothing's explicitly holding onto the Python object, eventually the m_self member will dangle. You could solve this problem by holding instances of handle<> in your vector (http://www.boost.org/libs/python/doc/v2/handle.html) and then you could use extract(object(h)) on each one to get the agent object out. The only things I can imagine doing in the library which might help you are: 1. Change the protocol for derived wrapper classes (e.g. py_agent) so that they accept an instance of class object which actually holds a Python weak reference to the Python object. That way it would be possible to report errors when the m_self object was destroyed, instead of gracelessly crashing. Existing user code, would have to change to accomodate this, of course. Another downside is that every such Python instance would acquire a WeakRefList upon creation, which could cost a fair amount of memory per instance. 2. Build a nicer smart pointer than handle<> which also manages the Python object. handle won't work, because agent is not a PyObject (there's no ob_refcnt to manage). So, imagine py_ptr, which, when dereferenced, returns an agent&, but which manages the reference count of the owning Python object. You could stick those in your vector and then you wouldn't need to use extract<> explicitly. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 10 05:16:03 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Nov 2002 23:16:03 -0500 Subject: [C++-sig] call_method In-Reply-To: <1036876211.17159.10.camel@beast> (Tim Field's message of "10 Nov 2002 10:10:10 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <1036876211.17159.10.camel@beast> Message-ID: Tim Field writes: > On Sun, 2002-11-10 at 00:59, Brett Calcott wrote: > > > >> The next one returns with a C++ runtime exception error >> Debugging the code it looks as if the m_self member that is held in the >> callback class has been deleted - causing the crash. > > Hey Brett, > > My (relatively uninformed) guess is that the inheritance/call-back issue > is a red herring -- I think the agent is getting garbage-collected > before you call 'do_something' on it. I reckon you should just replace > > .def("add_agent", &engine::add_agent) > > with > > .def("add_agent", &engine::add_agent, with_custodian_and_ward<1, 2>()) > > so that the lifetime of the agent object is linked to that of the > engine. I could be wrong, of course (has been known to happen)... That's an ingenious thought... One caveat: the agent will never get destroyed until the engine does, even if you erase it from the vector. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 10 05:30:34 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Nov 2002 23:30:34 -0500 Subject: [C++-sig] Re: Re: custom iterator object In-Reply-To: ("Mike Rovner"'s message of "Fri, 8 Nov 2002 10:53:07 -0800") References: Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:uy9853yrt.fsf at boost-consulting.com... >> "Mike Rovner" writes: > So I have custom iterator 'Iter' as shown above. It's like Python iterator, > so I tend to use it instead of wrapping in iterator. > Now I have a class: > > class Scheme { > Iter A(); > Iter B(); > Iter C(); > } > > which I want to exposure. So I write: > > BOOST_PYTHON_MODULE(Py1) > { > class_("Scheme") > .def("__iter__", ???(&Scheme::A)) > .add_property("b", ???(&Scheme::B)) > .add_property("c", ??(&Scheme::C)) > ; > } > > to pretend objects itself acts as iterator A, b and c as B and C. But I have > trouble in places ???. > I need a Python iterator object there like 'iterator' or 'range' functions > return, but first I need to instantiate Iter with A|B|C member parameter to > create a custom iterator. > > I can wrap an Iter as > > typedef Iter (*GetIterFunc)(); > template > struct PyIter > { > PyIter(GetLrIterFunc const get_func) : started(false), it(get_func()) {} > const T* begin() {return it.First();} > const T* end() {return 0;} > const T* operator++() {return v=it.Next();} > const T operator*() {return *v;} > private: > bool started; > T* v; > Iter it; > }; > > class_("PyIter", init()) OK, there's no point in bothering with the init<...> declaration there. You might as well use no_init, since you're not going to construct these from Python and Boost.Python doesn't have a way to convert any Python objects to C++ function pointers. > .def("__iter__", range(&PyIter::begin, &PyIter::end)) Well, you can't use range(...) here; that's intended for real C++ iterators, and you don't have any (PyIter doesn't conform). Here's my suggestion: Try doing what you need to do in Pure Python. Build a little new-style class (derived from object) called Scheme, and add the iterator interface you want to see. To do that, you may find yourself building some little Python iterator classes. Now, when you have all that working, translate your Python iterator classes into C++, and wrap them with Boost.Python. Remember that the iterator's own __iter__ method can be implemented by wrapping this C++ function: object identity(object x) { return x; } HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 10 05:18:08 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Nov 2002 23:18:08 -0500 Subject: [C++-sig] call_method In-Reply-To: <005001c2884c$b7fa9560$2e6e4fcb@hare> ("Brett Calcott"'s message of "Sun, 10 Nov 2002 13:04:15 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <1036876211.17159.10.camel@beast> <005001c2884c$b7fa9560$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > Hiya Tim, > > >> >> My (relatively uninformed) guess is that the inheritance/call-back issue >> is a red herring -- I think the agent is getting garbage-collected >> before you call 'do_something' on it. I reckon you should just replace >> >> .def("add_agent", &engine::add_agent) >> >> with >> >> .def("add_agent", &engine::add_agent, with_custodian_and_ward<1, 2>()) >> >> so that the lifetime of the agent object is linked to that of the >> engine. I could be wrong, of course (has been known to happen)... >> >> >> Hope that helps, > > Yup, that helps a lot. So much so that it actually works now :) > > Whew... > > I had assumed that since Boost.Python passed me the PyObject *self, that the > lifetime of the PyObject was already bound to my C++ object. That is what I > actually want, as binding the agent to the engine is only safe if I the C++ > engine is responsible for the lifetime of the C++ agent (actually a > reasonable assumption is this case). Of course doing something like that > requires cyclic dependencies as the python object holds a shared_ptr to the > C++ object. Hmmm. How hard would that be... > > > Thanks Tim, Yeah, Tim, thanks for your sharp analysis! Too bad I didn't read it before writing the foregoing diatribe! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 10 05:46:40 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 09 Nov 2002 23:46:40 -0500 Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings In-Reply-To: <20021108221650.98601.qmail@web14504.mail.yahoo.com> (Tex Riddell's message of "Fri, 8 Nov 2002 14:16:50 -0800 (PST)") References: <20021108221650.98601.qmail@web14504.mail.yahoo.com> Message-ID: Tex Riddell writes: > I posted this question to the boost-users yahoo group, but I realized > from the response to another message on that group regarding > Boost.Python that I should send boost python questions to this list > instead. Thanks! > First, I'm excited about the new work that's been done with Boost > Python v2. I can't wait to see if it's enough to overcome the > pitfalls that prevented me from getting past the evaluation stage > with v1. Me neither ... > I'm using VC7 IDE to build my project and link to python22.lib and > boost_python.lib (built with VC7 command line tools using bjam). Proceed at your own risk. Many people report problems which are due to getting the wrong project configuration using the IDE. I strongly suggest you use the -n -a option with some of the bjam examples to see how the command-line options come out, so you can match them. > I'm attempting to extend and embed in my existing project, so I'm > not building a dll, but and exe. First of all, can I do this? Yes. However, there are some caveats. Boost.Python keeps some Python objects alive in global variables (it has some registries and a few other resources it needs). There is currently no integration with PyFinalize() to get these cleaned up, so if you call PyFinalize() your application may crash on exit as the reference counts are decremented and the dead Python interpreter is invoked. This is something we plan to address in a future version. > When it links it says "Creating library ....lib and object ....exp", ^^ What is "it"? > and still creates an exe. If I don't include my test module (and > thus boost/python.hpp) I don't get this message. I'm assuming that > by defining a module, boost defines exports and the linker then > creates the lib and exp, since there were exports? Although I've > built dlls before, I really don't know the inner workings of the > process. If you're talking about what you're building in the IDE, I have no clue and no control over that. Boost.Python itself lives in a DLL, though if you're determined to you there are ways to link it into your app directly. Normally, the code your module gets from boost.python generates only /imports/ from boost_python.dll, so I really have no idea. > The following is a brief example of my module. At the bottom is a > simple test function that I'm calling just to test importing of the > module. When I call TestModule(), I get 2 memory leaks from the module > definition section, one from the class definition Yes, extension modules are never unloaded, and classes in the extension module are kept alive additionally by Boost.Python's registry. > , and the other from the method definition. Of course, since the class holds a reference to its method, the class keeps the method alive also. > In addition to the memory leaks, I get a number of compiler warnings, > similar to the following: > > d:\Boost\boost\python\instance_holder.hpp(18) : warning C4275: non > dll-interface class 'boost::noncopyable' used as base for dll-interface > struct 'boost::python::instance_holder' > d:\Boost\boost\utility.hpp(50) : see declaration of > 'boost::noncopyable' > d:\Boost\boost\python\instance_holder.hpp(17) : see declaration > of 'boost::python::instance_holder' You can ignore this. > *and* > > d:\Boost\boost\python\detail\exception_handler.hpp(34) : warning C4251: > 'boost::python::detail::exception_handler::m_impl' : class > 'boost::function2' needs to have > dll-interface to be used by clients of struct > 'boost::python::detail::exception_handler' > with > [ > R=bool, > T0=const boost::python::detail::exception_handler &, > T1=const > boost::function0 > &, > Policy=boost::empty_function_policy, > Mixin=boost::empty_function_mixin, > Allocator=int > ] You can ignore this, too. > I was wondering if my project is not set up properly, Maybe your warning level is too high ;-) Actually, I'm kidding. Someone should add #pragmas to suppress these warnings. Patches graciously accepted. > and if these > warnings might have something to do with the memory leaks. Nope. > In v1 there was a vc project you could use for building boost > python. This works well if you are planning on linking to a vc > built project, since you can make sure your settings, paths and libs > are consistent between the boost python lib and your project. I > currently have 3 different sets of build tools (yes, 3 compilers) on > this box, with several different versions of standard and other > libraries, so making sure I have control of the paths and settings > used is very important. That's why we created Boost.Build. I'm currently building and testing with 11 different compilers on this machine alone, and many others on other machines. > This is one reason I'm weary of the jam environment. It's yet > another build environment, one that I'm not familiar with, and one > that I'm not going to be using with any other projects except to > build boost python. Your loss ;-) > So a question would be: how easy would it be for me to set up a VC > project for building boost python? Has this already been done? Or > am I barking up the wrong tree? Personally I think you're barking up the wrong tree, since maintaining platform-specific solutions like that is difficutl, but other people have done it and I believe I'm probably going to end up having to supply one eventually :( -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Sun Nov 10 06:33:39 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 10 Nov 2002 18:33:39 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare> Message-ID: <007501c2887b$0e508c70$2e6e4fcb@hare> From: "David Abrahams" > > It has nothing to do with all that. The first thing I notice is that > what you're doing makes no sense: > > class_, agent_ptr>("agent", init<>()) > .def("do_something", &agent::do_something) > ; > > class_, py_agent_ptr, boost::noncopyable> > ("py_agent", init<>()) > .def("do_something", &agent::do_something) > ; > > You can't wrap class "agent" two different ways. I probably ought to > generate some kind of assertion for this, but life is short... Ok, I thought this looked weird too. But given I want: 1) An agent which I can instantiate from python but the execution of do_something happens in c++. 2) An agent which inherits all of the c++ agents properties, but can do_something in python. ...then the above code seemed the way to do it. You can stick some intermediary class in, but it is effectively empty. Hmm. I guess I am blindly following the examples. Should I do this? class_, agent_ptr>("agent", init<>()) .def("do_something", &agent::do_something) ; class_, py_agent_ptr, boost::noncopyable> ("py_agent", init<>()) ; > The only things I can imagine doing in the library which might help > you are: > > 1. Change the protocol for derived wrapper classes (e.g. py_agent) so > that they accept an instance of class object which actually holds a > Python weak reference to the Python object. That way it would be > possible to report errors when the m_self object was destroyed, > instead of gracelessly crashing. Existing user code, would have to > change to accomodate this, of course. Another downside is that > every such Python instance would acquire a WeakRefList upon > creation, which could cost a fair amount of memory per instance. > > 2. Build a nicer smart pointer than handle<> which also manages the > Python object. handle won't work, because agent is not a > PyObject (there's no ob_refcnt to manage). So, imagine > py_ptr, which, when dereferenced, returns an agent&, but > which manages the reference count of the owning Python object. You > could stick those in your vector and then you wouldn't need to use > extract<> explicitly. > I was trying to think of a solution myself today. I thought of something along the lines of 2. Can I help?. (Of course, it may be quicker if you just do it yourself, given my knowledge of the internals of Boost.Python.) Cheers, Brett From brett.calcott at paradise.net.nz Sun Nov 10 06:36:42 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 10 Nov 2002 18:36:42 +1300 Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings References: <20021108221650.98601.qmail@web14504.mail.yahoo.com> Message-ID: <007601c2887b$28895900$2e6e4fcb@hare> From: "David Abrahams" > > > Maybe your warning level is too high ;-) > Actually, I'm kidding. Someone should add #pragmas to suppress these > warnings. Patches graciously accepted. > > > and if these > > warnings might have something to do with the memory leaks. > see my post [MSVC project file] > > Personally I think you're barking up the wrong tree, since maintaining > platform-specific solutions like that is difficutl, but other people > have done it and I believe I'm probably going to end up having to > supply one eventually :( > Likewise. Cheers, Brett From dave at boost-consulting.com Sun Nov 10 13:43:47 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 10 Nov 2002 07:43:47 -0500 Subject: [C++-sig] call_method In-Reply-To: <007501c2887b$0e508c70$2e6e4fcb@hare> ("Brett Calcott"'s message of "Sun, 10 Nov 2002 18:33:39 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > Ok, I thought this looked weird too. But given I want: > > 1) An agent which I can instantiate from python but the execution of > do_something happens in c++. > 2) An agent which inherits all of the c++ agents properties, but can > do_something in python. > > ...then the above code seemed the way to do it. You can stick some > intermediary class in, but it is effectively empty. Hmm. I guess I > am blindly following the examples. No, you are not. You should never expose py_agent explicitly. > Should I do this? > > class_, agent_ptr>("agent", init<>()) > .def("do_something", &agent::do_something) No, you should never expose a virtual funtion you intend to override in Python that way. Take a look at how "default_f" is used in http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html. If you made agent::do_something pure virtual, you wouldn't need to expose it at all. > ; > > class_, py_agent_ptr, boost::noncopyable> > ("py_agent", init<>()) > ; > >> The only things I can imagine doing in the library which might help >> you are: >> >> 1. Change the protocol for derived wrapper classes (e.g. py_agent) so >> that they accept an instance of class object which actually holds a >> Python weak reference to the Python object. That way it would be >> possible to report errors when the m_self object was destroyed, >> instead of gracelessly crashing. Existing user code, would have to >> change to accomodate this, of course. Another downside is that >> every such Python instance would acquire a WeakRefList upon >> creation, which could cost a fair amount of memory per instance. >> >> 2. Build a nicer smart pointer than handle<> which also manages the >> Python object. handle won't work, because agent is not a >> PyObject (there's no ob_refcnt to manage). So, imagine >> py_ptr, which, when dereferenced, returns an agent&, but >> which manages the reference count of the owning Python object. You >> could stick those in your vector and then you wouldn't need to use >> extract<> explicitly. >> > > I was trying to think of a solution myself today. I thought of something > along the lines of 2. Can I help?. (Of course, it may be quicker if you just > do it yourself, given my knowledge of the internals of Boost.Python.) I'm always interested in getting helpful patches. You don't need to know very much about internals to do this job, since most everything you need to do involves existing documented high-level components like extract<>. I'll help out when you get to the stage of needing to supply Python<->C++ conversions for these pointers. One thing you might consider is deriving these things from python::object... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From warkid at hotbox.ru Mon Nov 11 10:57:02 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Mon, 11 Nov 2002 12:57:02 +0300 Subject: [C++-sig] Data members and inheritance Message-ID: <414374984.20021111125702@hotbox.ru> Hello. I'm trying to export a class's data member that's declared in parent class. But I can't. Please explain me what am I doing wrong. Here's the test code: //hello.cpp #include using namespace boost::python; struct t { float a; }; struct xt : t { }; BOOST_PYTHON_MODULE(hello) { class_("xt", no_init) .def_readonly("a", &xt::a); } /////////////////// compiling it I get this error: hello.cpp(16) : error C2784: 'boost::python::class_::self &boost::py thon::class_::def_readonly(const char *,D xt::* )' : could not deduc e template argument for ' xt::* ' from 'float t::* ' with [ T=xt, X1=boost::python::detail::not_specified, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] Best regards, Kerim mailto:warkid at hotbox.ru ------------------ Get free mailbox 20 Mb at http://www.hotbox.ru From warkid at hotbox.ru Mon Nov 11 11:19:19 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Mon, 11 Nov 2002 13:19:19 +0300 Subject: [C++-sig] () and [] operators Message-ID: <475711718.20021111131919@hotbox.ru> Hello again. I wasn't able to find an "intuitive"(like for other operators) way to expose () and [] operators. How am I supposed to do it? Best regards, Kerim mailto:warkid at hotbox.ru ------------------ Get free mailbox 20 Mb at http://www.hotbox.ru From dave at boost-consulting.com Mon Nov 11 14:29:33 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Nov 2002 08:29:33 -0500 Subject: [C++-sig] Re: Q: Problems building boost.python under cygwin In-Reply-To: <3DCC6C47.68D39432@mailzone.com> (Claudius =?iso-8859-1?q?Schn=F6rr's?= message of "Sat, 09 Nov 2002 03:00:39 +0100") References: <30E10C5E4EE6D31181EF00508B8B5BBB117AF0@EXCHANGE-SERVER.ddg.de> <3DCC6C47.68D39432@mailzone.com> Message-ID: Claudius Schn?rr writes: > Hello David, > > since only you answered me, I think my problems are very specific. > I therefore reply to you directly: Please don't assume that. You'll get much better service if you post your C++-sig questions to the C++-sig. > 1) You are right, I didn't use the downloadable bjam.exe but built > it from boost/tools/build/jam_src. After having defined the > cygwin-options in Makefile (CC=gcc, CFLAGS=-D__cygwin__), I could > build it. > > Since I don't have MSVC, I now tried both, the downloadable bjam.exe for > Cygwin and Windows, as you suggested: > a) bjam.exe.gz for Cygwin is somehow corrupted, gzip -t bjam.exe.gz > reports 'unexpected end of file'. That appears to be true. John, are you ever going to fix this? > I tried it three times. In addition, I tried to rename it > (bjam.exe.gz --> bjam.exe) for the case Netscape decompressed it but > keept its name). This was not the case. Oh, well. bjam is easy enough to rebuild under Cygwin, though: just go to $BOOST_ROOT/tools/build and do "make CC=gcc". Not that it matters. I was suggesting that you use the regular Win32 bjam executable in a regular Win32 shell. > b) With bjam.exe for Windows, I cannot figure out how to set the > environment variables correctly. > It would be easier to find the right settings, if not all variables > were reported but only those which are still set badly. It can't tell which ones are badly set, though. > This bjam does not accept the settings which worked in 1). Which settings? > 3) I try to reformulate my last sentence (sorry for my bad English): > Since bjam tried to build shared libs as *.so instead of *.dll, I > got the impression that I have missed to set some necessary > environment variables/options/directives for cygwin. No, you haven't. A cygwin-built bjam is not the same as a Win32-built bjam. Quit messing around with the cygwin one if you want to use Boost.Python (we'll support that in Boost.Build v2, but not yet). Just download the "Microsoft Windows" version of bjam and use that. It will generate the appropriate extensions. > David Abrahams wrote: >> >> The following message is a courtesy copy of an article >> that has been posted to gmane.comp.lib.boost.user as well. >> >> "Schn?rr, Claudius Dr." writes: >> >> > Hello, >> > >> > I run into problems building boost under cygwin. >> > >> > It seems to be merely a matter of a wrong configuration or wrong scripts. >> > >> > After running 'bjam -sTOOLS=gcc -n > build.com' in boost/libs/python/build >> > in order to get hands on the statements being executed by bjam, >> >> Did you use the Win32 bjam downloaded from the website, or did you try >> to build your own bjam under Cygwin? I build and test a Cygwin version >> of on Boost.Python on a regular basis using the former executable (or >> one built from source with a regular Win32 toolset like MSVC). >> >> > there had to be made a lot of textual replacements to get the statements in >> > build.com run: >> > >> > Just to mention some: >> > >> > - replace '-isystem ' by '-I' >> >> Was that neccessary? My Cygwin GCC responds nicely to -isystem. >> >> > - remove '-I""' >> > - change shared library-names from *.so to *.dll >> >> That's handled automatically when you do it my way. >> >> > - insert '-L -lpython2.2' where shared libs are >> > created >> > >> > >> > In boost/libs/python/test, going the same way, there have in addition this >> > changes to be made: >> > - LD_LIBRARY_PATH=... --> PATH=$PATH:..., because cygwin uses PATH to look >> > for .dlls >> > >> > >> > My question: >> > >> > I think there have to be made more configurations than I did to create the >> > boost.python-stuff under cygwin. >> >> I don't understand that sentence. >> >> -- >> David Abrahams >> dave at boost-consulting.com * http://www.boost-consulting.com -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 11 14:33:26 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Nov 2002 08:33:26 -0500 Subject: [C++-sig] MSVC project file In-Reply-To: <003901c287bc$c078f870$2e6e4fcb@hare> ("Brett Calcott"'s message of "Sat, 9 Nov 2002 19:53:44 +1300") References: <003901c287bc$c078f870$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > Hi all, > > For those interested here is a MS project file that builds boost_python. > > Create a directory under boost/libs/python/build > > I called mine ./msvc-project. > > Drop the file into the directory and then load it in DevStudio and build. It > will create a ./bin underneath it with boost_python.dll and > boost_python_d.dll. > > > David, (if you are listening) given the work in Boost.Build I'm not sure if > you are interested in this at all - though I would hazard a guess that there > will be more requests. In any case - adding some extra warning switches to > the detail/config.hpp makes the build a little easier to watch both for bjam > and DevStudio. > > --- config_old.hpp Sat Nov 09 19:47:06 2002 > +++ config.hpp Sat Nov 09 16:19:26 2002 > @@ -32,7 +32,11 @@ > # define BOOST_MSVC6_OR_EARLIER 1 > # endif > > -# pragma warning (disable : 4786) > +# pragma warning (disable : 4786) // disable truncated debug symbols > +# pragma warning (disable : 4251) // disable exported dll function > +# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or > 'false' > +# pragma warning (disable : 4275) // non dll-interface class > + > > # elif defined(__ICL) && __ICL < 600 // Intel C++ 5 Hi Brett, A couple of questions: 1. Does your project work with MSVC6, or just with 7? 2. Are you interested in officially maintaining this work? I'll only add it to the Boost distribution if there's someone to stand behind it. If you wish to proceed, I'd also like a documentation patch which describes how to use it. This could be very exciting! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Mon Nov 11 16:13:16 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Mon, 11 Nov 2002 10:13:16 -0500 Subject: [C++-sig] RE: Problems building boost.python under cygwin In-Reply-To: Message-ID: FWIW After reading the message by Claudius Schn?rr I tried compiling Boost.Python again under Cygwin. I had not done this since CygWin switched to gcc-3.2. At first it failed, but I recall that there was an upgrade to their GCC a day or so ago. After upgrading, it worked fine. So with 1.) The latest distribution of Python (which is 1.29.0), 2.) With the latest bjam for Windows (not Cygwin), 3.) The latest gcc/binutils from Cygwin, Boost.Python compiled for me just fine. There was one warning about an unused variable: ../src/object/inheritance.cpp:217: warning: unused variable `vertex_t v2' As for how the build was accomplished: 1.) I worked in a bash shell (from Cygwin) 2.) I put bjam.exe in /usr/local/bin (in my path) 3.) I changed into the BOOST/libs/python/build subdirectory 4.) I set my environment with the following (reflects where I have installed cygwin) export PYTHON='C:\cygwin\bin\python.exe' export PYTHON_ROOT='C:\cygwin\lib\python2.2' export PYTHON_VERSION='2.2' export PYTHON_INCLUDES='C:\cygwin\usr\include\python2.2' export PYTHON_LIB_PATH='C:\cygwin\lib\python2.2\config' export PYTHON_STDLIB_PATH='C:\cygwin\lib\python2.2' export GCC_PYTHON_ROOT='C:\cygwin\usr' 5.) I ran "bjam -sTOOLS=gcc -sBUILD=release" I have not tested the build yet, but everything looks fine. Regards, Scott From ssmith at magnet.fsu.edu Mon Nov 11 17:40:15 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Mon, 11 Nov 2002 11:40:15 -0500 Subject: [C++-sig] MSVC project file In-Reply-To: <003901c287bc$c078f870$2e6e4fcb@hare> Message-ID: Bruce, Thanks for the MSVC++ project for Boost.Python. I hope it will elucidate some aspects of building Boost.Python as I still find jam to be too much of a black-box. Today I downloaded the Boost distribution (1.29.0) and built it using bjam. That was done in a DOSish command window on Windows 2000, I have MSVC++ V6. I ran the tests after the build and things went to completion, so I believe that build is OK. Then I attempted to use your MSVC project to accomplish the build. Unfortunately, it didn't work for me. Perhaps you could clarify how it is used. I think I have a late service pack for MSVC, so that should not be a problem. I did not alter the config.hpp file, but I that will not prevent any the build problems I see. 1.) Without a workspace, my MSVC version complains a lot and sometimes even crashes. I think they recommend that a workspace is used even if it only contains a single project? It automatically will make one if it doesn't die first. 2.) Why do you use /Zm800 several times in the compiler options? Does that do something more with the available memory than a single one? 3.) It looks as if the libraries will be built in ../test not ./bin as you specified? These are called bpl_d.dll and boost_python.dll respectively in the project you sent out, not boost_python_d.dll. Is it true that "bpl" is the Boost.Python library name now? The builds I did today with Jam made boost_python.dll libraries, but I think this is Boost.Python V2? 4.) None of the Boost.Python headers are included in the project. Should they be? I set the header includes directory (globally using Tools-Options), is that good enough? 5.) Lastly, MSVC++ just begins spitting out errors during the build. Have you used MSVC V6 with Boost 1.29.0 and this project? Here is a sample of the errors: arg_to_python_base.cpp c:\program files\microsoft visual studio\vc98\include\mmreg.h(1383) : error C2146: syntax error : missing ';' before identifier 'wFormatTag' c:\program files\microsoft visual studio\vc98\include\mmreg.h(1383) : error C2501: 'WORD' : missing storage-class or type specifiers c:\program files\microsoft visual studio\vc98\include\mmreg.h(1383) : error C2501: 'wFormatTag' : missing storage-class or type specifiers c:\program files\microsoft visual studio\vc98\include\mmreg.h(1384) : error C2146: syntax error : missing ';' before identifier 'nChannels' c:\program files\microsoft visual studio\vc98\include\mmreg.h(1384) : error C2501: 'WORD' : missing storage-class or type specifiers c:\program files\microsoft visual studio\vc98\include\mmreg.h(1384) : error C2501: 'nChannels' : missing storage-class or type specifiers c:\program files\microsoft visual studio\vc98\include\mmreg.h(1385) : error C2146: syntax error : missing ';' before identifier 'nSamplesPerSec' I have built many other projects with MSVC++, although I would not swear that this isn't a compiler problem. I have no clue why mmreg.h is even included at all. I'll look around in the MS KnowledgeBase, but perhaps you have seen something similar? It may just be some compiler flag(s) set wrong? Thanks, Scott From n_lelong at hotmail.com Mon Nov 11 17:53:07 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Mon, 11 Nov 2002 17:53:07 +0100 Subject: [C++-sig] Re: Python + Boost Python V2 + downcasting References: Message-ID: David Abrahams wrote: > [digression: > > I notice that you're using return_internal_reference<>() to return the > Base* from the ObjectServer. Does the ObjectServer actually control > the lifetime of the objects, or is it simply holding pointers? I ask > because I don't see a destructor, so in the code you sent, > return_internal_reference<> is inappropriate (maybe you were just > eliminating details for the sake of the post?) -- the point of > return_internal_reference<> is to keep the owning object alive as long > as the owned objects are also alive. If something else is managing > their lifetimes, you may need another mechanism. > ] nope, of course the ObjectServer manages the lifetime of the Base objects ; I just made up a simple example for the post. > ... > > In the meantime, if the ObjectServer is really the owner of the C++ > objects, you might consider storing boost::python::object in its > m_objects array. If you convert your Derived objects to > boost::python::object at their point of creation, the full dynamic > type will be preserved for Python. I'll use some other mecanisms for now (such as a collection of functions that wrap a collection of dynamic_casts - as for my tests I don't need a full blown solution), as I try to extend Python with existing code and I like the non-intrusive paradigm. As for your other points, I'll try to take some time to take a closer look to all this ... I'll see what I can get playing with custom return value policies and/or boost/python/object/make_instance.hpp [I'll have a look at this first, I'd really like to have a 'working' isinstance :) ]. I'll let you know if I have some results ! Thanks for the hints & your help, Nicolas. From n_lelong at hotmail.com Mon Nov 11 19:37:26 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Mon, 11 Nov 2002 19:37:26 +0100 Subject: [C++-sig] Re: Python + Boost Python V2 + downcasting Message-ID: David Abrahams wrote: >[...] > > Ultimately, I think the best solution is going to be to add a new kind > of ReturnValuePolicy which uses typeid() on the pointer to get the > most-derived class, looks up the corresponding Python class in the > converter::registry, and builds a pointer_holder around it using the > appropriate Python class type. Hmm, looking carefully, this might not > require a new ReturnValuePolicy, and could be as simple as making some > judicious changes to boost/python/object/make_instance.hpp.** > OK Dave, I've decided to go for it, and I think I've made up the kind of changes needed in 'boost/python/object/make_instance.hpp'. I replaced the following line from 'PyObject* make_instance::execute(Arg& x)' : PyTypeObject* type = converter::registered::converters.class_object; with: PyTypeObject* type = query_most_derived_PyTypeObject( x ); Having some news methods in make_instance: template static dynamic_id_t query_most_derived_dynamic_id_t(Arg& x) { typedef typename dynamic_id_generator::type generator; return generator::execute( (void*)&(*x) ); } static dynamic_id_t query_most_derived_dynamic_id_t(reference_wrapper x) { typedef typename dynamic_id_generator::type generator; return generator::execute( (void*)x.get_pointer() ); } template static PyTypeObject* query_most_derived_PyTypeObject(Arg& x) { if (is_polymorphic::value) { dynamic_id_t dynamic_id = query_most_derived_dynamic_id_t( x ); converter::registration const* registration_data = converter::registry::query( dynamic_id.second ); return registration_data->class_object; } else { return converter::registered::converters.class_object; } } It seems to work fine on a few examples I tried here - I must admit that I've not run the whole test suite, but what do you think of it ?! Thanks, Nicolas. > [...] From dave at boost-consulting.com Mon Nov 11 20:40:51 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Nov 2002 14:40:51 -0500 Subject: [C++-sig] MSVC project file In-Reply-To: <003901c287bc$c078f870$2e6e4fcb@hare> ("Brett Calcott"'s message of "Sat, 9 Nov 2002 19:53:44 +1300") References: <003901c287bc$c078f870$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > David, (if you are listening) given the work in Boost.Build I'm not sure if > you are interested in this at all - though I would hazard a guess that there > will be more requests. In any case - adding some extra warning switches to > the detail/config.hpp makes the build a little easier to watch both for bjam > and DevStudio. > > --- config_old.hpp Sat Nov 09 19:47:06 2002 > +++ config.hpp Sat Nov 09 16:19:26 2002 > @@ -32,7 +32,11 @@ > # define BOOST_MSVC6_OR_EARLIER 1 > # endif > > -# pragma warning (disable : 4786) > +# pragma warning (disable : 4786) // disable truncated debug symbols > +# pragma warning (disable : 4251) // disable exported dll function > +# pragma warning (disable : 4800) //'int' : forcing value to bool 'true' or > 'false' > +# pragma warning (disable : 4275) // non dll-interface class > + > > # elif defined(__ICL) && __ICL < 600 // Intel C++ 5 I've made this patch in CVS. Thanks! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Mon Nov 11 23:44:39 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 11 Nov 2002 14:44:39 -0800 Subject: [C++-sig] Re: Re: Re: custom iterator object References: Message-ID: > Well, you can't use range(...) here; that's intended for real C++ > iterators, and you don't have any (PyIter doesn't conform). (Aside question) Why? To put it another way, how to write a conforming or use an iterator_adaptor? I was convinced that that way will be more clear and maintainable. > Here's my suggestion: > > Try doing what you need to do in Pure Python. Build a little > new-style class (derived from object) called Scheme, and add the > iterator interface you want to see. To do that, you may find > yourself building some little Python iterator classes. Like that: class Iter: def __init__(self,a): self.a=a() def __iter__(self): return self def next(self): return self.a class Scheme: def __iter__(self): return Iter(self.A) def i2(self): return Iter(self.B) def i3(self): return Iter(self.C) def A(self): return 1 def B(self): return 2 def C(self): return 3 > Now, when you have all that working, translate your Python iterator > classes into C++, and wrap them with Boost.Python. Remember that the Python code above working but I still have problems with C++: How can I pass 'this' from wrapping class? PyIter make_iter(const Scheme* s, GetFunc f) { return s->(*f)(); } ... class_("Scheme") .def("__iter__", make_iter(this,&Scheme::A)) .add_property("b", make_iter(this,&Scheme::B)) .add_property("c", make_iter(this,&Scheme::C)) ; Mike From mike at bindkey.com Mon Nov 11 23:46:37 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 11 Nov 2002 14:46:37 -0800 Subject: [C++-sig] Re: Re: custom iterator object References: <20021107211257.69768.qmail@web20201.mail.yahoo.com> Message-ID: That's fine, thanks. Can you point some usage of iterators_wrappers::wrap(). I couldn't find any. :( "Ralf W. Grosse-Kunstleve" wrote in message news:20021107211257.69768.qmail at web20201.mail.yahoo.com... > --- Mike Rovner wrote: > > I have problems with return value. In __iter__ I have to return self, but > > there is no Python self yet in wrapping class. > > So probably I have to duplicate part of the BPL iterator guts, but I got > > lost :( > > You could try this: > > inline > boost::python::object > pass_through(boost::python::object const& o) { return o; } > > class_(python_name) > .def("next", next) > .def("__iter__", pass_through) > ; > > Full source: > > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/include/scitbx/b oost_python/iterator_wrappers.h > > Ralf > > > __________________________________________________ > Do you Yahoo!? > U2 on LAUNCH - Exclusive greatest hits videos > http://launch.yahoo.com/u2 From texrmex at yahoo.com Tue Nov 12 00:38:48 2002 From: texrmex at yahoo.com (Tex Riddell) Date: Mon, 11 Nov 2002 15:38:48 -0800 (PST) Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings In-Reply-To: <002b01c28792$89e02ba0$2e6e4fcb@hare> Message-ID: <20021111233848.85327.qmail@web14504.mail.yahoo.com> --- Brett Calcott wrote: > Hi Tex, > > You have asked a few questions in your post. I am only going to > answer one > of them. > > > So a question would be: how easy would it be for me to set up a VC > > project for building boost python? Has this already been done? Or > am > > I barking up the wrong tree? > > > > It is *reasonably* easy to do this - though I am using VC6. If you do > a > >bjam -and2 That, there, would be the ticket to knowing all the details of the build that I wanted to know, thanks! Had I explored the command line options of bjam I may have found some of this out, but probably not the debug level part (the important bit). I think from here I should be able to solve any other build issues I have. > at the command line and redirect it to a file you will get all of the > command line options that are generated for building the DLL. You > need to > create DLL project, dump all of the .cpp files into it, then make > sure that > the command line that is being generated is the same (well, the > important > bits anyway). Look in the Project Options window to see this. > > The only problem I came across was the /Zm800 option, which is needed > to > compile the inheritance.cpp file (otherwise you get a compiler > blowup). > There seems to be NO place that I could enter this in the IDE! I > fudged it > by stuffing it into the .dsp file on what looked like the right line > where > the other options were. Of course, it gets overwritten if I change > anything - but it works fine. Maybe you can set it directly in VC7? > > Once I tidy my test hacking environment up, I will post a copy. (2-3 > days > away) > > Cheers, > Brett I probably won't actually use VC to build BP after all, but the information above is definately helpful.. Thanks! -Tex __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 From texrmex at yahoo.com Tue Nov 12 01:04:25 2002 From: texrmex at yahoo.com (Tex Riddell) Date: Mon, 11 Nov 2002 16:04:25 -0800 (PST) Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings In-Reply-To: Message-ID: <20021112000425.68225.qmail@web14506.mail.yahoo.com> --- David Abrahams wrote: > Tex Riddell writes: > *snip* > > I'm using VC7 IDE to build my project and link to python22.lib and > > boost_python.lib (built with VC7 command line tools using bjam). > > Proceed at your own risk. Many people report problems which are due > to > getting the wrong project configuration using the IDE. I strongly > suggest you use the -n -a option with some of the bjam examples to > see > how the command-line options come out, so you can match them. This, and Bret's suggestion, I'm sure will prove to be most helpful. > > I'm attempting to extend and embed in my existing project, so I'm > > not building a dll, but and exe. First of all, can I do this? > > Yes. However, there are some caveats. Boost.Python keeps some Python > objects alive in global variables (it has some registries and a few > other resources it needs). There is currently no integration with > PyFinalize() to get these cleaned up, so if you call PyFinalize() > your > application may crash on exit as the reference counts are decremented > and the dead Python interpreter is invoked. This is something we plan > to address in a future version. That would be most helpful, how do you suggest I proceed in the mean time? I don't think it will be acceptable for my uses to just live with leaks or crashes. Is there any way I can clean up these objects before the app exits? > > When it links it says "Creating library ....lib and object > ....exp", > ^^ > What is "it"? Sorry, that's VC7's linker. In light of the build information I can get from bjam, are there any simple examples of an app that extends and embeds, instead of building to a .pyd? Then I might be able to clean up my build configuration. > > and still creates an exe. If I don't include my test module (and > > thus boost/python.hpp) I don't get this message. I'm assuming that > > by defining a module, boost defines exports and the linker then > > creates the lib and exp, since there were exports? Although I've > > built dlls before, I really don't know the inner workings of the > > process. > > If you're talking about what you're building in the IDE, I have no > clue and no control over that. Boost.Python itself lives in a DLL, > though if you're determined to you there are ways to link it into > your > app directly. Normally, the code your module gets from boost.python > generates only /imports/ from boost_python.dll, so I really have no > idea. My intent was not to link Boost.Python directly, but to embed my extension directly in my app, instead of producing a .pyd. That, along with embeding the interpreter. I have done this in the past with Boost.Python v1, but not v2. > > The following is a brief example of my module. At the bottom is a > > simple test function that I'm calling just to test importing of the > > module. When I call TestModule(), I get 2 memory leaks from the > module > > definition section, one from the class definition > > Yes, extension modules are never unloaded, and classes in the > extension module are kept alive additionally by Boost.Python's > registry. Is this to accomidate cross-extension module communication? *snip* > > In v1 there was a vc project you could use for building boost > > python. This works well if you are planning on linking to a vc > > built project, since you can make sure your settings, paths and > libs > > are consistent between the boost python lib and your project. I > > currently have 3 different sets of build tools (yes, 3 compilers) > on > > this box, with several different versions of standard and other > > libraries, so making sure I have control of the paths and settings > > used is very important. > > That's why we created Boost.Build. I'm currently building and testing > with 11 different compilers on this machine alone, and many others on > other machines. > > > This is one reason I'm weary of the jam environment. It's yet > > another build environment, one that I'm not familiar with, and one > > that I'm not going to be using with any other projects except to > > build boost python. > > Your loss ;-) > > So a question would be: how easy would it be for me to set up a VC > > project for building boost python? Has this already been done? Or > > am I barking up the wrong tree? > > Personally I think you're barking up the wrong tree, since > maintaining > platform-specific solutions like that is difficutl, but other people > have done it and I believe I'm probably going to end up having to > supply one eventually :( Well being able to see all the commands generated by bjam will solve the unknown factor with integration with our project tools, which will never be changed to jam (not up to me ;). > -- > David Abrahams > dave at boost-consulting.com * http://www.boost-consulting.com > Boost support, enhancements, training, and commercial distribution Thanks for all your help on this! Now I might just be ready to ask my *real* BPL questions :P ... when I have time to get back to this that is. -Tex __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 From dave at boost-consulting.com Tue Nov 12 01:08:14 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Nov 2002 19:08:14 -0500 Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings In-Reply-To: <20021112000425.68225.qmail@web14506.mail.yahoo.com> (Tex Riddell's message of "Mon, 11 Nov 2002 16:04:25 -0800 (PST)") References: <20021112000425.68225.qmail@web14506.mail.yahoo.com> Message-ID: Tex Riddell writes: > --- David Abrahams wrote: >> Tex Riddell writes: >> > *snip* >> > I'm using VC7 IDE to build my project and link to python22.lib and >> > boost_python.lib (built with VC7 command line tools using bjam). >> >> Proceed at your own risk. Many people report problems which are due >> to >> getting the wrong project configuration using the IDE. I strongly >> suggest you use the -n -a option with some of the bjam examples to >> see >> how the command-line options come out, so you can match them. > > This, and Bret's suggestion, I'm sure will prove to be most helpful. > >> > I'm attempting to extend and embed in my existing project, so I'm >> > not building a dll, but and exe. First of all, can I do this? >> >> Yes. However, there are some caveats. Boost.Python keeps some Python >> objects alive in global variables (it has some registries and a few >> other resources it needs). There is currently no integration with >> PyFinalize() to get these cleaned up, so if you call PyFinalize() >> your >> application may crash on exit as the reference counts are decremented >> and the dead Python interpreter is invoked. This is something we plan >> to address in a future version. > > That would be most helpful, how do you suggest I proceed in the mean > time? I don't think it will be acceptable for my uses to just live > with leaks or crashes. Is there any way I can clean up these objects > before the app exits? Do you need to? For many applications it is sufficient to simply not call PyFinalize(). >> > When it links it says "Creating library ....lib and object >> ....exp", >> ^^ >> What is "it"? > > Sorry, that's VC7's linker. In light of the build information I can > get from bjam, are there any simple examples of an app that extends and > embeds, instead of building to a .pyd? Then I might be able to clean > up my build configuration. No, there aren't. People have done it, with BPLv2 though. I would love to have an example that I could put in the distribution... >> > and still creates an exe. If I don't include my test module (and >> > thus boost/python.hpp) I don't get this message. I'm assuming that >> > by defining a module, boost defines exports and the linker then >> > creates the lib and exp, since there were exports? Although I've >> > built dlls before, I really don't know the inner workings of the >> > process. >> >> If you're talking about what you're building in the IDE, I have no >> clue and no control over that. Boost.Python itself lives in a DLL, >> though if you're determined to you there are ways to link it into >> your app directly. Normally, the code your module gets from >> boost.python generates only /imports/ from boost_python.dll, so I >> really have no idea. > > My intent was not to link Boost.Python directly, but to embed my > extension directly in my app, instead of producing a .pyd. That, along > with embeding the interpreter. I have done this in the past with > Boost.Python v1, but not v2. OK. Well, like I said, I have no clue about what the IDE is doing. >> > The following is a brief example of my module. At the bottom is >> > a simple test function that I'm calling just to test importing of >> > the module. When I call TestModule(), I get 2 memory leaks from >> > the module definition section, one from the class definition >> >> Yes, extension modules are never unloaded, and classes in the >> extension module are kept alive additionally by Boost.Python's >> registry. > > Is this to accomidate cross-extension module communication? The registry part is, yes. The fact that extension modules are never unloaded is a built-in feature/limitation of Python, so you'll see that leak anyway, at least until PyFinalize() becomes viable with Boost.Python. At that point, we'll also clean up the registry of course. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Tue Nov 12 01:31:00 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 11 Nov 2002 16:31:00 -0800 (PST) Subject: [C++-sig] Re: Re: custom iterator object In-Reply-To: Message-ID: <20021112003100.50183.qmail@web20204.mail.yahoo.com> --- Mike Rovner wrote: > Can you point some usage of iterators_wrappers::wrap(). I couldn't find any. Sure, although I doubt that you will learn much more from the additional code. Ralf http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/cctbx/eltbx/boost_python/tiny_pse_ext.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/cctbx/include/cctbx/eltbx/tiny_pse.h?rev=1.2&content-type=text/vnd.viewcvs-markup http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/cctbx/eltbx/tiny_pse.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup __________________________________________________ Do you Yahoo!? U2 on LAUNCH - Exclusive greatest hits videos http://launch.yahoo.com/u2 From dave at boost-consulting.com Tue Nov 12 02:34:55 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Nov 2002 20:34:55 -0500 Subject: [C++-sig] Re: Re: Re: custom iterator object In-Reply-To: ("Mike Rovner"'s message of "Mon, 11 Nov 2002 14:44:39 -0800") References: Message-ID: "Mike Rovner" writes: >> Well, you can't use range(...) here; that's intended for real C++ >> iterators, and you don't have any (PyIter doesn't conform). > > (Aside question) Why? > To put it another way, how to write a conforming or use an iterator_adaptor? > I was convinced that that way will be more clear and maintainable. > >> Here's my suggestion: >> >> Try doing what you need to do in Pure Python. Build a little >> new-style class (derived from object) called Scheme, and add the >> iterator interface you want to see. To do that, you may find >> yourself building some little Python iterator classes. > > Like that: > > class Iter: > def __init__(self,a): self.a=a() > def __iter__(self): return self > def next(self): return self.a > > class Scheme: > def __iter__(self): return Iter(self.A) > def i2(self): return Iter(self.B) > def i3(self): return Iter(self.C) > def A(self): return 1 > def B(self): return 2 > def C(self): return 3 > >> Now, when you have all that working, translate your Python iterator >> classes into C++, and wrap them with Boost.Python. Remember that the > > Python code above working but I still have problems with C++: > How can I pass 'this' from wrapping class? Didn't I write this? > > Remember that the iterator's own __iter__ method can be > > implemented by wrapping this C++ function: > > > > object identity(object x) { return x; } Did I leave something out? You can use: .def("__iter__", identity) inside your iterator wrapper class. Does that make it clear? Or are you really asking something else? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Tue Nov 12 04:25:52 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 11 Nov 2002 19:25:52 -0800 Subject: [C++-sig] Re: Re: Re: Re: custom iterator object References: Message-ID: "David Abrahams" wrote in message news:un0ofy3i8.fsf at boost-consulting.com... > > How can I pass 'this' from wrapping class? > > > Didn't I write this? > > > > Remember that the iterator's own __iter__ method can be > > > implemented by wrapping this C++ function: > > > > > > object identity(object x) { return x; } > > Did I leave something out? You can use: > > .def("__iter__", identity) > > inside your iterator wrapper class. Does that make it clear? Or are I'm really sorry not making myself clear. I have no problem wrapping my itereator class. > you really asking something else? I have problem _creating that iterator_ from another object. For creating an iterator I have to call member function. For calling it I have to have a C++ object reference, i.e. Scheme& s; MyIter s.*pm(); Now I'm trying to wrap that class (that shall return an iterator): class_("Scheme") .def("__iter__", mem_fun_ref(&Scheme::GetIter)) where Scheme has a memeber returning MyIter: class Scheme{ ... MyIter GetIter(); }; Now .def get confused and complains: /export/home/mike/boost_1_29_0/boost/python/make_function.hpp: In function `boost::python::api::object boost::python::make_function(F, const Policies&, const Keywords&) [with F = std::const_mem_fun_ref_t, Scheme>, Policies = boost::python::default_call_policies, Keywords = boost::python::detail::keywords<0>]': /export/home/mike/boost_1_29_0/boost/python/class.hpp:319: instantiated from `void boost ::python::class_::def_impl(const char*, Fn, const Keywords&, const Policies &, const char*, ...) [with Fn = std::const_mem_fun_ref_t, Policies = boost::python::default_call_policies, Keywords = boost::python::detail::keywords<0>, T = Scheme, X1 = boost::python::detail::not_specified, X2 = boost::python::detail::not_specified, X3 = boost::python::detail::not_sp ecified]' /export/home/mike/boost_1_29_0/boost/python/class.hpp:207: instantiated from `boost::pyt hon::class_& boost::python::class_::def(const char*, F) [wit h F = std::const_mem_fun_ref_t, T = Scheme, X1 = boost::python::detail::not_specified, X2 = boost::python: :detail::not_specified, X3 = boost::python::detail::not_specified]' PyTcn.cpp:141: instantiated from here /export/home/mike/boost_1_29_0/boost/python/make_function.hpp:39: incomplete type ` boost::python::detail::arg_tuple_size >' does not have member `value' /export/home/mike/boost_1_29_0/boost/python/make_function.hpp:39: enumerator value for `n_arguments' not integer constant because I'm trying to feed a function object (returning MyIter from operator()) to .def. From dave at boost-consulting.com Tue Nov 12 04:43:52 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 11 Nov 2002 22:43:52 -0500 Subject: [C++-sig] Re: Re: Re: Re: custom iterator object In-Reply-To: ("Mike Rovner"'s message of "Mon, 11 Nov 2002 19:25:52 -0800") References: Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:un0ofy3i8.fsf at boost-consulting.com... > >> > How can I pass 'this' from wrapping class? >> >> >> Didn't I write this? >> >> > > Remember that the iterator's own __iter__ method can be >> > > implemented by wrapping this C++ function: >> > > >> > > object identity(object x) { return x; } >> >> Did I leave something out? You can use: >> >> .def("__iter__", identity) >> >> inside your iterator wrapper class. Does that make it clear? Or are > > I'm really sorry not making myself clear. > I have no problem wrapping my itereator class. > >> you really asking something else? > > I have problem _creating that iterator_ from another object. > For creating an iterator I have to call member function. > For calling it I have to have a C++ object reference, i.e. > > Scheme& s; > MyIter s.*pm(); > > Now I'm trying to wrap that class (that shall return an iterator): > > class_("Scheme") > .def("__iter__", mem_fun_ref(&Scheme::GetIter)) Why aren't you just using .def("__iter__", &Scheme::GetIter) here? What is mem_fun_ref supposed to buy you? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Tue Nov 12 06:43:43 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 11 Nov 2002 21:43:43 -0800 Subject: [C++-sig] Re: Re: Re: Re: Re: custom iterator object References: Message-ID: "David Abrahams" wrote in message news:u8yzzxxjb.fsf at boost-consulting.com... > > I have problem _creating that iterator_ from another object. > > For creating an iterator I have to call member function. > > For calling it I have to have a C++ object reference, i.e. > > > > Scheme& s; > > MyIter s.*pm(); > > > > Now I'm trying to wrap that class (that shall return an iterator): > > > > class_("Scheme") > > .def("__iter__", mem_fun_ref(&Scheme::GetIter)) > > Why aren't you just using > > .def("__iter__", &Scheme::GetIter) > > here? What is mem_fun_ref supposed to buy you? I'm sorry again. I'm using mem_fun_ref because class Scheme { //has only CustomIter GetIter(); } and I use class MyIter { MyIter(CustomIter& init); T next(); } class_("_myiter") .def("__iter__", identity) .def("next, &MyIter::next) ; instead of CustomIter to convert it to Python iterator protocol. So mem_fun_ref returns some mem_fun_ref_t object instance with operator() which when called with Scheme& produces MyIter object. That wrapped MyIter object shall be return value from wrapped Scheme::GetIter() member function. I already figured out that if I want call .def with object it shall be 'object'. So I need to wrap mem_fun_ref_t into callable python object and instantiate it, right? Wrapping is easy: typedef mem_fun_ref_t Gen; class_("_gen").def("__call__", detail::operator_()); // is it correct? but how to instantiate that new object? Thanks, Mike From brett.calcott at paradise.net.nz Tue Nov 12 08:35:38 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Tue, 12 Nov 2002 20:35:38 +1300 Subject: [C++-sig] MSVC project file References: <003901c287bc$c078f870$2e6e4fcb@hare> Message-ID: <004d01c28a1e$7c935ec0$2e6e4fcb@hare> Hi David, > > A couple of questions: > > 1. Does your project work with MSVC6, or just with 7? I don't have VC7 unfortunately, so I don't know. Can someone out there comment? > > 2. Are you interested in officially maintaining this work? I'll only > add it to the Boost distribution if there's someone to stand behind > it. > > If you wish to proceed, I'd also like a documentation patch which > describes how to use it. > I am planning on using Boost.Python quite a bit - so I think I can look after it 'officially'. You will have to give me a little time (10-12 days?) to give you a documented release. My explorations in Boost.Python mean I have neglected some writing I need to finish... Should I send to you, or do you want to let me into CVS? Cheers, Brett From brett.calcott at paradise.net.nz Tue Nov 12 09:07:03 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Tue, 12 Nov 2002 21:07:03 +1300 Subject: [C++-sig] MSVC project file References: Message-ID: <005701c28a22$804ee350$2e6e4fcb@hare> Hi Scott, Thanks for the feedback. > > 1.) Without a workspace, my MSVC version complains a lot and sometimes even > crashes. > I think they recommend that a workspace is used even if it only contains > a > single project? It automatically will make one if it doesn't die first. Ok, Since Dave is interested in putting this in the official release I will provide a workspace file. Note that the fact that it crashes makes me think that you have NOT got the latest service pack. We're up to 5 now I believe. > > 2.) Why do you use /Zm800 several times in the compiler options? Does that > do something more > with the available memory than a single one? Where are you seeing this? Are you looking in the .dsp file? The reason is that I could not find any way of putting in this option via the interface, so I hacked it into the .dsp with a text editor. I didn't want to take time to learn all the complexities of how a .dsp works - so I just stuck it in all the places where I thought it would help. I think you will find many options are repeated... No harm is done. > > 3.) It looks as if the libraries will be built in ../test not ./bin as you > specified? These are > called bpl_d.dll and boost_python.dll respectively in the project you > sent out, not boost_python_d.dll. > Is it true that "bpl" is the Boost.Python library name now? The builds I > did today with Jam made > boost_python.dll libraries, but I think this is Boost.Python V2? yeah. I think I attached the file before saving the changes. This is wrong. I will post an updated one. > > 4.) None of the Boost.Python headers are included in the project. Should > they be? I set the > header includes directory (globally using Tools-Options), is that good > enough? This makes no difference to the compilation. But I will include them in the post as it makes it easier to 'tour' the source. > > 5.) Lastly, MSVC++ just begins spitting out errors during the build. Have > you used MSVC V6 > with Boost 1.29.0 and this project? Here is a sample of the errors: > > arg_to_python_base.cpp > c:\program files\microsoft visual studio\vc98\include\mmreg.h(1383) : error > C2146: syntax error : missing ';' before identifier 'wFormatTag' > c:\program files\microsoft visual studio\vc98\include\mmreg.h(1383) : error > C2501: 'WORD' : missing storage-class or type specifiers > c:\program files\microsoft visual studio\vc98\include\mmreg.h(1383) : error > C2501: 'wFormatTag' : missing storage-class or type specifiers > c:\program files\microsoft visual studio\vc98\include\mmreg.h(1384) : error > C2146: syntax error : missing ';' before identifier 'nChannels' > c:\program files\microsoft visual studio\vc98\include\mmreg.h(1384) : error > C2501: 'WORD' : missing storage-class or type specifiers > c:\program files\microsoft visual studio\vc98\include\mmreg.h(1384) : error > C2501: 'nChannels' : missing storage-class or type specifiers > c:\program files\microsoft visual studio\vc98\include\mmreg.h(1385) : error > C2146: syntax error : missing ';' before identifier 'nSamplesPerSec' > > I have built many other projects with MSVC++, although I would not swear > that this isn't a compiler problem. > I have no clue why mmreg.h is even included at all. I'll look around in the > MS KnowledgeBase, but perhaps you have seen something similar? It may just > be some compiler flag(s) set wrong? > I had this same problem a while back. It is an include file problem. I never figured out exactly where it comes from (why doesn't msvc give an #include traceback!!), but I fixed it by reordering the include directories in Tools/Options. Make sure that the python and boost dirs come BEFORE the MS default ones. Good luck. Brett From brett.calcott at paradise.net.nz Tue Nov 12 09:26:10 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Tue, 12 Nov 2002 21:26:10 +1300 Subject: [C++-sig] MSVC project file [UPDATED] References: <003901c287bc$c078f870$2e6e4fcb@hare> Message-ID: <007101c28a25$291ec2a0$2e6e4fcb@hare> Here's one that fixes the errors Scott mentioned. Enjoy, Brett -------------- next part -------------- A non-text attachment was scrubbed... Name: boost_python.dsp Type: application/octet-stream Size: 22980 bytes Desc: not available URL: From sashang at ihug.co.nz Tue Nov 12 09:51:41 2002 From: sashang at ihug.co.nz (sashan) Date: Tue, 12 Nov 2002 21:51:41 +1300 Subject: [C++-sig] MSVC project file References: <003901c287bc$c078f870$2e6e4fcb@hare> <004d01c28a1e$7c935ec0$2e6e4fcb@hare> Message-ID: <3DD0C11D.7050606@ihug.co.nz> Brett Calcott wrote: >Hi David, > > > >>A couple of questions: >> >>1. Does your project work with MSVC6, or just with 7? >> >> > >I don't have VC7 unfortunately, so I don't know. Can someone out there >comment? > > I had to add the relevant include and lib paths but otherwise it worked. -- sashan ------------------------------- P: Egad! You astound me, Brain! B: That's a simple task, Pinky. -------------- next part -------------- An HTML attachment was scrubbed... URL: From brett.calcott at paradise.net.nz Tue Nov 12 10:59:57 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Tue, 12 Nov 2002 22:59:57 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare> Message-ID: <001601c28a32$6862f9b0$2e6e4fcb@hare> From: "David Abrahams" Sent: Monday, November 11, 2002 1:43 AM > > > Ok, I thought this looked weird too. But given I want: > > > > 1) An agent which I can instantiate from python but the execution of > > do_something happens in c++. > > 2) An agent which inherits all of the c++ agents properties, but can > > do_something in python. > > > > ...then the above code seemed the way to do it. You can stick some > > intermediary class in, but it is effectively empty. Hmm. I guess I > > am blindly following the examples. > > No, you are not. You should never expose py_agent explicitly. The problem is I wanted to expose agent and py_agent, both of which require using agent as the first template parameter. So this means I must use an intermediary class between the two - Right? > > > Should I do this? > > > > class_, agent_ptr>("agent", init<>()) > > .def("do_something", &agent::do_something) > > No, you should never expose a virtual funtion you intend to override > in Python that way. Take a look at how "default_f" is used in > http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.ht ml. > If you made agent::do_something pure virtual, you wouldn't need to > expose it at all. Ok, I need to RTFM. Hmmm. Why can't you do that? Mem fun pointers to virtual functions are ok. Aren't you storing them somewhere... I think I would blunder less if I actually knew how this stuff worked. I believe you are writing something about the internals - I look forward to reading it. > >> The only things I can imagine doing in the library which might help > >> you are: > >> > >> 1. Change the protocol for derived wrapper classes (e.g. py_agent) so > >> that they accept an instance of class object which actually holds a > >> Python weak reference to the Python object. That way it would be > >> possible to report errors when the m_self object was destroyed, > >> instead of gracelessly crashing. Existing user code, would have to > >> change to accomodate this, of course. Another downside is that > >> every such Python instance would acquire a WeakRefList upon > >> creation, which could cost a fair amount of memory per instance. > >> > >> 2. Build a nicer smart pointer than handle<> which also manages the > >> Python object. handle won't work, because agent is not a > >> PyObject (there's no ob_refcnt to manage). So, imagine > >> py_ptr, which, when dereferenced, returns an agent&, but > >> which manages the reference count of the owning Python object. You > >> could stick those in your vector and then you wouldn't need to use > >> extract<> explicitly. > >> > > > > I was trying to think of a solution myself today. I thought of something > > along the lines of 2. Can I help?. (Of course, it may be quicker if you just > > do it yourself, given my knowledge of the internals of Boost.Python.) > > I'm always interested in getting helpful patches. You don't need to > know very much about internals to do this job, since most everything > you need to do involves existing documented high-level components like > extract<>. > > I'll help out when you get to the stage of needing to supply > Python<->C++ conversions for these pointers. > > One thing you might consider is deriving these things from > python::object... > Ok, I have something that works. I don't think it resembles what you had in mind as I don't use extract<> or python::object. This is just a 'proof of concept' - I would like your feedback on what might be bad/wrong/silly about this. The outline is this: 1. I use the intrusive_ptr template in boost. This is currently undocumented, and I also needed to add a 'typedef T element_type' to the class to make it work with Boost.Python. Note that the pointee<> approach documented for the smart_ptr example doesn't work with msvc. 2. I use a py_counted_base which is inherited by the class that is pointed too. I keep the PyObject *self in this class and Py_INCREF it if the use count of the intrusive_ptr goes above 1. (see the code) 3. I create a to_python converter that returns the PyObject *self out of the base class so we get object identity back in python. See the included code. Cheers, Brett -------------- next part -------------- A non-text attachment was scrubbed... Name: test.cpp Type: application/octet-stream Size: 4176 bytes Desc: not available URL: From brett.calcott at paradise.net.nz Tue Nov 12 11:02:54 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Tue, 12 Nov 2002 23:02:54 +1300 Subject: [C++-sig] MSVC project file References: <003901c287bc$c078f870$2e6e4fcb@hare> <004d01c28a1e$7c935ec0$2e6e4fcb@hare> <3DD0C11D.7050606@ihug.co.nz> Message-ID: <002401c28a32$bacd2680$2e6e4fcb@hare> Hi sashan, > > I had to add the relevant include and lib paths but otherwise it worked. > Yay. Thanks for the info. The relevant include and lib paths I assume are in the tools/options/directories. I could add the includes to the project, but I don't imagine everyone has the same setup. Cheers, Brett From hugo at adept.co.za Tue Nov 12 11:07:24 2002 From: hugo at adept.co.za (Hugo van der Merwe) Date: Tue, 12 Nov 2002 12:07:24 +0200 Subject: [C++-sig] Static, again... Message-ID: <20021112100724.GA26115@vervet.localnet> I had a look at the mailing list archives about this topic, I'm still not clear on how exactly it works: > #include > #include > > struct Num { > Num() {} > ~Num() {} > static int getDims() {return 3;} > int dims() {return 5;} > }; > > BOOST_PYTHON_MODULE_INIT(numTest) > { > using namespace boost::python; > module numTestMod("numTest"); > numTestMod > .add > ( class_("Num") > .def_init() > .def("getDims",&Num::getDims) > .def("dims", &Num::dims) > ) > ; > } > We don't have a way to make true static methods yet. > getDims will work fine if you access it through the class like this: > > Nums.getDims() I am trying to wrap a "Settings" class which does not have a public constructor, it expects you to call "GetInstance" to get a pointer to the always-existing instance (making the settings "global"). The above would make me think that this will work: class_("Settings", no_init) .def("GetInstance", &Settings::GetInstance, return_value_policy()); I cannot call Settings.GetInstance(), it gives me: TypeError: unbound method Boost.Python.function object must be called with Settings instance as first argument (got nothing instead) I also read about an approach that looks something like this: object settings_class = class_("Settings", no_init); settings_class.attr("Settings") = &Settings::GetInstance; But I don't know how that is supposed to work... If I wanted to expose GetInstance as Settings() instead (once I get it working), is it as simple as just calling it "__init__" instead? (Should I then have no_init in the class_<> invocation or not? I noticed the tutorial talks about no_init, but then mentions as soon as you wish to derive classes from it, you do not want no_init. So when is no_init useful? Only when you cannot construct a class and don't want to derive from it, i.e. when you're using "factories"?) I am really astonished with what can be achieved with C++ - Boost.Python is really amazing! Thanks a lot, Hugo van der Merwe From ssmith at magnet.fsu.edu Tue Nov 12 14:20:16 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Tue, 12 Nov 2002 08:20:16 -0500 Subject: [C++-sig] MSVC project file In-Reply-To: <005701c28a22$804ee350$2e6e4fcb@hare> Message-ID: Hi Brett, > > 1.) Without a workspace, my MSVC version complains / crashes. > Ok, I will provide a workspace file. Note that the fact that it crashes > makes me think that you have NOT got the latest service pack. > We're up to 5 now I believe. No, to be sure I upgraded to SP5 yesterday and the same problem occurs with the recent project you posted. I think it has more to do with opening a new project while another workspace is loaded. I have to use Task Manager to kill MSVC after it dies then load the workspace it had created just before its demise. Supplying a workspace will solve that. > > 2.) Why do you use /Zm800 several times in the compiler options? > Where are you seeing this? ... No harm is done. Right click boost_python files (in FileView), choose Settings, the C++ in the resulting window's tab. At the bottom (of any C++ options) will be a window showing all compiler flags. At the end in your project is /FD /Zm800 /Zm800 /Zm800 /Zm800 /Zm800 /GZ /c When you change the various options in the C++ menu, these will automatically update. But there is no menued option to adjust the memory use, so /Zm must be set by hand in that window. I will try just /FD /Zm800 /GZ /c and let you know. Any idea why this needs such a memory adjustment anyway? Or is it just the MS assumes one always builds smaller libraries. > > 3.) It looks as if the libraries will be built in ../test > yeah. I think I attached the file before saving the changes. This > is wrong. I will post an updated one. Yep, this is now fixed. What is the difference between the Win32 Debug and Win32 Debug Python builds? I don't even know how one adds another build option as you have done. (Note that this latter project built but could not write the library, I think the output directory setting is bad.... I didn't look at it further since I don't know what it does and ran the build by accident anyway.) > > 4.) None of the Boost.Python headers are included in the project. > This makes no difference to the compilation. But I will include > them in the post as it makes it easier to 'tour' the source. Great, looks good. The sub-folders are nice too. > > 5.) Lastly, MSVC++ just begins spitting out errors during the > build. > I had this same problem a while back. It is an include file > problem. I never figured out exactly where it comes from > (why doesn't msvc give an #include traceback!!), but I fixed it by > reordering the include directories in Tools/Options. Make sure that > the python and boost dirs come BEFORE the MS default ones. Wow, that is a bit odd. There must be some definition that messes things up? The worst part is that the errors stem from including some MSVC files that have to do with Multimedia and sound cards.... how this even is considered in the build is a mystery. But your suggestion works (with a single /Zm)! Again, thanks for the project. I was postponing switching to Boost.Python V2 because I develop my stuff using MSVC++ (for the IDE), but could not get anything of mine to work with V2 because of the aforementioned errors even though the Boost.Python V2 builds fine with jam. If you need any help with testing, proofing the docs, etc. I'd be glad to help. Regards, Scott From n_lelong at hotmail.com Tue Nov 12 14:18:56 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Tue, 12 Nov 2002 14:18:56 +0100 Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings References: <20021112000425.68225.qmail@web14506.mail.yahoo.com> Message-ID: > > >> > When it links it says "Creating library ....lib and object > >> ....exp", > >> ^^ > >> What is "it"? > > > > Sorry, that's VC7's linker. In light of the build information I can > > get from bjam, are there any simple examples of an app that extends and > > embeds, instead of building to a .pyd? Then I might be able to clean > > up my build configuration. > > No, there aren't. People have done it, with BPLv2 though. I would love > to have an example that I could put in the distribution... > The linker wants to create the ".lib" and ".exp" files because your EXE exports some symbols (the way a DLL would do it). I had this 'problem' recently and fixed it. The symbols exported from the EXE are the init functions for the modules you create (the code can be found in boost/python/module_init.hpp) that are declared with the keyword __declspec(dllexport). The simple thing you can do is to remove the __declspec(dllexport) there, and you're done. Ideally, someone should make a patch to account for that via 'boost/python/detail/config.hpp' as I've done it [but I don't known how to submit a patch - any pointers (no time to search myself...) ]. Hope that helps, Nicolas. From n_lelong at hotmail.com Tue Nov 12 14:21:54 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Tue, 12 Nov 2002 14:21:54 +0100 Subject: [C++-sig] MSVC project file References: <005701c28a22$804ee350$2e6e4fcb@hare> Message-ID: > > 2.) Why do you use /Zm800 several times in the compiler options? Does that > > do something more > > with the available memory than a single one? > > Where are you seeing this? Are you looking in the .dsp file? The reason is > that I could not find any way of putting in this option via the interface, > so I hacked it into the .dsp with a text editor. I didn't want to take time > to learn all the complexities of how a .dsp works - so I just stuck it in > all the places where I thought it would help. I think you will find many > options are repeated... No harm is done. In the VC7 IDE, you can define additional compile/link options in the projet properties, in the [C/C++]/[Command Line] tab for compile ; in the [Linker]/[Command Line] tab for the linker. Nicolas. From dave at boost-consulting.com Tue Nov 12 14:21:23 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 08:21:23 -0500 Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings In-Reply-To: ("Nicolas Lelong"'s message of "Tue, 12 Nov 2002 14:18:56 +0100") References: <20021112000425.68225.qmail@web14506.mail.yahoo.com> Message-ID: "Nicolas Lelong" writes: >> >> >> > When it links it says "Creating library ....lib and object >> >> ....exp", >> >> ^^ >> >> What is "it"? >> > >> > Sorry, that's VC7's linker. In light of the build information I can >> > get from bjam, are there any simple examples of an app that extends and >> > embeds, instead of building to a .pyd? Then I might be able to clean >> > up my build configuration. >> >> No, there aren't. People have done it, with BPLv2 though. I would love >> to have an example that I could put in the distribution... I'd still love to have a small embedding example... > The linker wants to create the ".lib" and ".exp" files because your EXE > exports some symbols (the way a DLL would do it). I had this 'problem' > recently and fixed it. > > The symbols exported from the EXE are the init functions for the modules you > create (the code can be found in boost/python/module_init.hpp) that are > declared with the keyword __declspec(dllexport). Aha. > The simple thing you can do is to remove the __declspec(dllexport) there, > and you're done. Ideally, someone should make a patch to account for that > via 'boost/python/detail/config.hpp' as I've done it [but I don't known how > to submit a patch - any pointers (no time to search myself...) ]. Just `diff -wu' your copy of the file with the copy in the source distro, and post the output /as an attachment/. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 15:10:15 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 09:10:15 -0500 Subject: [C++-sig] Re: Re: Re: Re: Re: custom iterator object In-Reply-To: ("Mike Rovner"'s message of "Mon, 11 Nov 2002 21:43:43 -0800") References: Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:u8yzzxxjb.fsf at boost-consulting.com... >> > I have problem _creating that iterator_ from another object. >> > For creating an iterator I have to call member function. >> > For calling it I have to have a C++ object reference, i.e. >> > >> > Scheme& s; >> > MyIter s.*pm(); >> > >> > Now I'm trying to wrap that class (that shall return an iterator): >> > >> > class_("Scheme") >> > .def("__iter__", mem_fun_ref(&Scheme::GetIter)) >> >> Why aren't you just using >> >> .def("__iter__", &Scheme::GetIter) >> >> here? What is mem_fun_ref supposed to buy you? > > I'm sorry again. I'm using mem_fun_ref because > > class Scheme { > //has only > CustomIter GetIter(); > } What is CustomIter? I've never seen this before. I'm sorry, but I can't be expected to understand your code if you don't give me a complete picture. > and I use > > class MyIter { > MyIter(CustomIter& init); > T next(); > } > > class_("_myiter") > .def("__iter__", identity) > .def("next, &MyIter::next) > ; > > instead of CustomIter to convert it to Python iterator protocol. So, you want CustomIter objects to be converted to python by first building a MyIter object around them? > So mem_fun_ref returns some > mem_fun_ref_t object instance with operator() which when called > with Scheme& produces MyIter object. Not unless there's a "typedef MyIter CustomIter;" you haven't shown me. According to the code here, that isn't what mem_fun_ref is doing. It's making a mem_fun_ref object which when called with Scheme& produces a CustomIter object. So it's hard to see what advantage it would give you, even if it could work (which it can't). > That wrapped MyIter object shall be return value from wrapped > Scheme::GetIter() member function. > > I already figured out that if I want call .def with object it shall > be 'object'. So I need to wrap mem_fun_ref_t into callable > python object and instantiate it, right? I guess so... though everything else you've said makes this sound misguided. > Wrapping is easy: > > typedef mem_fun_ref_t Gen; > class_("_gen").def("__call__", detail::operator_()); // is it correct? No, you're not supposed to touch anything in boost::python::detail::. > but how to instantiate that new object? I still don't know what you're driving at. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From n_lelong at hotmail.com Tue Nov 12 16:41:17 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Tue, 12 Nov 2002 16:41:17 +0100 Subject: [C++-sig] Boost Python v2 - extending and embedding - memory leaks, compiler warnings References: <20021112000425.68225.qmail@web14506.mail.yahoo.com> Message-ID: > >> No, there aren't. People have done it, with BPLv2 though. I would love > >> to have an example that I could put in the distribution... > > I'd still love to have a small embedding example... > OK, I crafted a small example from my test files ; it's quite dumb - and may not be perfect - so I'm open to every comment ... > > The simple thing you can do is to remove the __declspec(dllexport) there, > > and you're done. Ideally, someone should make a patch to account for that > > via 'boost/python/detail/config.hpp' as I've done it [but I don't known how > > to submit a patch - any pointers (no time to search myself...) ]. > > Just `diff -wu' your copy of the file with the copy in the source > distro, and post the output /as an attachment/. > Here it is, I hope I ordered well the files on the command line... All that is to be done is define BOOST_PYTHON_EXTEND_EMBEDDED in boost/detail/config.hpp - or perhaps just defining before the boost.python includes in the embedding application should do (if boost.python does not define modules). Nicolas. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: extend_embedded_patch.txt URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: extend_embedded_example.cpp URL: From mrussell8081 at pacbell.net Tue Nov 12 18:16:37 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Tue, 12 Nov 2002 09:16:37 -0800 Subject: [C++-sig] Problem Wrapping DirectX with Boost Python Message-ID: I am using Boost Python to wrap DirectX and have run into a problem I can't seem to get around. Def seems to have trouble with __stdcall this works ok for me when I call bind directly so I'm not sure where to go from here. I have attached a short test example cloned from the bind tests to show where the problem is. I am using msvc 6.5 and have tried both boost 1.29 and the latest from CVS. Thanks in advance Test Code: #define BOOST_BIND_ENABLE_STDCALL #define BOOST_MEM_FN_ENABLE_STDCALL #include using namespace boost::python; long __stdcall f_0() { return 17041L; } BOOST_PYTHON_MODULE_INIT(test_std_call) { def("f_0", f_0); } Error Message: Compiling... stdcall.cpp c:\boost\boost\python\detail\arg_tuple_size.hpp(61) : error C2664: 'struct boost::python::detail::char_array<0> __cdecl boost::python::detail::arg_tuple_size_helper(long (__cdecl *)(void))' : cannot convert parameter 1 from 'long (__stdcall *)(void) ' to 'long (__cdecl *)(void)' This conversion requires a reinterpret_cast, a C-style cast or function-style cast From dave at boost-consulting.com Tue Nov 12 18:16:34 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 12:16:34 -0500 Subject: [C++-sig] call_method In-Reply-To: <001601c28a32$6862f9b0$2e6e4fcb@hare> ("Brett Calcott"'s message of "Tue, 12 Nov 2002 22:59:57 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > From: "David Abrahams" > Sent: Monday, November 11, 2002 1:43 AM > > >> >> > Ok, I thought this looked weird too. But given I want: >> > >> > 1) An agent which I can instantiate from python but the execution of >> > do_something happens in c++. >> > 2) An agent which inherits all of the c++ agents properties, but can >> > do_something in python. >> > >> > ...then the above code seemed the way to do it. You can stick some >> > intermediary class in, but it is effectively empty. Hmm. I guess I >> > am blindly following the examples. >> >> No, you are not. You should never expose py_agent explicitly. Let me rephrase that, since I don't really know what you intend py_agent to be. You should never explicitly expose a class that's fulfilling the same role as BaseWrap does in http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html. > The problem is I wanted to expose agent and py_agent, Why? > both of which require using agent as the first template > parameter. So this means I must use an intermediary class between > the two - Right? I don't have any idea what you're trying to accomplish, but no addition of intermediary classes makes it OK to directly expose a class fulfilling the same role as BaseWrap does in http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html. >> No, you should never expose a virtual funtion you intend to override >> in Python that way. Take a look at how "default_f" is used in >> > http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.ht > ml. >> If you made agent::do_something pure virtual, you wouldn't need to >> expose it at all. > > Ok, I need to RTFM. Always a good plan. > Hmmm. Why can't you do that? Mem fun pointers to virtual functions > are ok. Aren't you storing them somewhere... Because when they're called from Python, they'll just end up calling the override which tries to call them from Python again, and you'll get an infinite recursion. > I think I would blunder less if I actually knew how this stuff > worked. I believe you are writing something about the internals - I > look forward to reading it. Don't hold your breath; that's not on the front burner at the moment. > Ok, I have something that works. I don't think it resembles what you had in > mind as I don't use extract<> or python::object. This is just a 'proof of > concept' - I would like your feedback on what might be bad/wrong/silly about > this. > > The outline is this: > 1. I use the intrusive_ptr template in boost. This is currently > undocumented, and I also needed to add a 'typedef T element_type' to the > class to make it work with Boost.Python. Note that the pointee<> approach > documented for the smart_ptr example doesn't work with msvc. Of course not ;-) > 2. I use a py_counted_base which is inherited by the class that is pointed > too. I keep the PyObject *self in this class and Py_INCREF it if the use > count of the intrusive_ptr goes above 1. (see the code) > > 3. I create a to_python converter that returns the PyObject *self out of the > base class so we get object identity back in python. Well, I think it's damned cool! I spent a bunch of time turning approaches like this one over and over in my mind, but I couldn't see how to make it work. At first I thought your design had to be broken, but I failed to poke any holes in it. IIUC, the structure looks like this: PyObject +-----------+ | ob_refcnt | py_agent +-----------+ +------------+ | agent_ptr |------>| use_count_ | +-----------+ +------------+ ^ | pyobj_ |--+ | +------------+ | | | ... | | | +------------+ | | | +-------------------------------+ The key is that as soon as the agent_ptr is copied, you bump ob_refcnt. Now you know that the PyObject can't die, the only way use_count_ can go to 1 is if all copies of the agent_ptr have been destroyed. At that point you can decrement ob_refcnt and let Python's regular reference management take over. Your remarks here: // need to put them in the boost namespace so they get found // before the defaults namespace boost { inline void intrusive_ptr_add_ref(py_counted_base * p) { p->add_ref(); } inline void intrusive_ptr_release(py_counted_base * p) { p->release(); } } // end namespace boost Are wrong, and putting these in namespace boost will not work on conforming compilers. They need to go in the same namespace as py_counted_base on most compilers. For compilers that don't do Koenig lookup namespace boost will probably be OK. I'd like to explore a few refinements with you. For example, it may be possible to get real shared_ptr interoperability by deriving py_counted_base from counted_base. Maybe we should ask Peter to weigh in on this. Peter, Brett's code is attached to this page: http://aspn.activestate.com/ASPN/Mail/Message/1430235 -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Tue Nov 12 18:38:55 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Tue, 12 Nov 2002 12:38:55 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: Message-ID: I am biting the bullet and switching my project over to use V2 finally. Many thanks to everyone working on the BP, the new documentation looks terrific. I am hoping someone can take the time to answer a couple of very simple questions to get me started. 1.) In the Hello tutorial, I see that one uses the Python Module name when creating instances of a class object. >>> import hello >>> planet = hello.World() But in other places, it seems like the module name is not required. I don't recall ever needing the module name for any exposed classes from V1. I understand that once planet (above) is made one does not need hello. to access its members, but is it always true that one needs it when declaring class objects? What about global functions? Is there a way to set things so they do not need this? 2.) The tutorial begins dealing with classes, and looks so nice that I doubt I'll have many problems switching to use V2. But on simpler things I am at a loss. At the start of my project, before I even get to dealing with my C++ classes, I have some global variables and functions declared. For example, extern const double PLANCK; (in .hpp) const double PLANCK = 6.6260755e-34; (in .cpp) which in BP V1 I exposed using something like PyModName.add(boost::python::make_ref(PLANCK), "PLANCK"); Now make_ref & PyModName.add are gone, so I took a guess & tried def("PLANCK", PLANCK, reference_existing_object()); which compiles but doesn't link. How do I exposes a simple constant, not in any class but globally defined. Can I do it "read-only" as suggested in the tutorial when explaining class Var where it uses .def_readonly("name", &Var::name)? Thanks, Scott From dave at boost-consulting.com Tue Nov 12 18:35:11 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 12:35:11 -0500 Subject: [C++-sig] Data members and inheritance In-Reply-To: <414374984.20021111125702@hotbox.ru> (Kerim Borchaev's message of "Mon, 11 Nov 2002 12:57:02 +0300") References: <414374984.20021111125702@hotbox.ru> Message-ID: Kerim Borchaev writes: > Hello. > > I'm trying to export a class's data member that's declared in parent > class. But I can't. Please explain me what am I doing wrong. > > Here's the test code: > > //hello.cpp > #include > using namespace boost::python; > > struct t { > float a; > }; > > struct xt : t { > }; > > BOOST_PYTHON_MODULE(hello) > { > class_("xt", no_init) > .def_readonly("a", &xt::a); > } You need to explicitly cast your member pointer to the right type: .def_readonly("a", (float xt::*)&xt::a); I've added a fix to the CVS which makes this unneccessary. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 18:37:00 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 12:37:00 -0500 Subject: [C++-sig] () and [] operators In-Reply-To: <475711718.20021111131919@hotbox.ru> (Kerim Borchaev's message of "Mon, 11 Nov 2002 13:19:19 +0300") References: <475711718.20021111131919@hotbox.ru> Message-ID: Kerim Borchaev writes: > Hello again. > > I wasn't able to find an "intuitive"(like for other operators) way to expose () and [] > operators. How am I supposed to do it? Gee, it sure would be nice to do it automatically, wouldn't it? In the meantime, you can add '__call__', '__getitem__', and '__setitem__' methods as you would in Python. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Tue Nov 12 18:52:00 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 12 Nov 2002 09:52:00 -0800 Subject: [C++-sig] Re: Re: Re: Re: Re: Re: custom iterator object References: Message-ID: "David Abrahams" wrote in message news:usmy6zxo8.fsf at boost-consulting.com... > What is CustomIter? I've never seen this before. I'm sorry, but I > can't be expected to understand your code if you don't give me a > complete picture. OK. Let me try to give a whole picture: 1) I have an API: typedef int* T; // some type class CustomIter { T First(); T Next(); }; class Scheme { CustomIter GetIter() const; CustomIter GetIter1() const; CustomIter GetIter2() const; }; 2) I want to expose Scheme to Python with 3 iterators GetIter as __iter__, GetIter1 as attribute 'base', GetIter2 as attribute 'top' i.e. I want to be able to write: s=Scheme() for i in s: print i for i in s.base: print i for i in s.top: print i 3) In order to do that I created C++ wrap for CustomIter: class MyIter { MyIter(CustomIter& init); T next(); }; and exposed it: object identity(object x) { return x; } class_("_myiter", no_init) .def("__iter__", identity) .def("next, &MyIter::next) ; Now I use 'make_iter' to create a 'iter_gen' object instance with operator() which when called with Scheme& produces MyIter object: class iter_gen { typedef CustomIter (Scheme::*PM)() const; iter_gen(PM pm) : _pm(pm); MyIter operator()(Scheme& s) { return MyIter((s.*pm)()); } private: PM _pm; }; iter_gen make_iter(PM pm) { return iter_gen(pm); } Then I hope to wrap Scheme with using of that 'iter_gen' objects to produce my iterators. make_iter(&Scheme::GetIter) make_iter(&Scheme::GetIter1) make_iter(&Scheme::GetIter2) But I still don't know how. And even not sure that I'm going in right direction at all :( Thank you for your patience, Mike From dave at boost-consulting.com Tue Nov 12 19:14:40 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 13:14:40 -0500 Subject: [C++-sig] Re: Python + Boost Python V2 + downcasting In-Reply-To: ("Nicolas Lelong"'s message of "Mon, 11 Nov 2002 19:37:26 +0100") References: Message-ID: "Nicolas Lelong" writes: > David Abrahams wrote: > >>[...] >> >> Ultimately, I think the best solution is going to be to add a new kind >> of ReturnValuePolicy which uses typeid() on the pointer to get the >> most-derived class, looks up the corresponding Python class in the >> converter::registry, and builds a pointer_holder around it using the >> appropriate Python class type. Hmm, looking carefully, this might not >> require a new ReturnValuePolicy, and could be as simple as making some >> judicious changes to boost/python/object/make_instance.hpp.** >> > > OK Dave, > I've decided to go for it, and I think I've made up the kind of changes > needed in 'boost/python/object/make_instance.hpp'. > > I replaced the following line from 'PyObject* make_instance::execute(Arg& > x)' : > PyTypeObject* type = converter::registered::converters.class_object; > with: > PyTypeObject* type = query_most_derived_PyTypeObject( x ); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FWIW, unqualified calls are banned unless you intend to allow customization via Koenig Lookup. > Having some news methods in make_instance: > > template > static dynamic_id_t query_most_derived_dynamic_id_t(Arg& x) > { > typedef typename dynamic_id_generator::type generator; > return generator::execute( (void*)&(*x) ); You shouldn't use a cast here. Any object pointer is implicitly convertible to void*. > } > > static dynamic_id_t query_most_derived_dynamic_id_t(reference_wrapper const> x) > { > typedef typename dynamic_id_generator::type generator; > return generator::execute( (void*)x.get_pointer() ); > } Are you sure you don't need an overload for reference_wrapper as well? And, is a reference_wrapper check really needed? Don't I unwrap all reference_wrappers before they arrive here? Hmm, maybe not... > template > static PyTypeObject* query_most_derived_PyTypeObject(Arg& x) > { > if (is_polymorphic::value) > { > dynamic_id_t dynamic_id = query_most_derived_dynamic_id_t( x ); > converter::registration const* registration_data = > converter::registry::query( dynamic_id.second ); > return registration_data->class_object; This won't work. If the most-derived class is not registered, registration_data will be 0. You need a fallback. Also, it seems like overkill since dynamic_id_generator is already checking for is_polymorphic... and it's doing a lot more than that in order to avoid using dynamic_cast on non-polymorphic types. > } > else > { > return converter::registered::converters.class_object; > } > } Why not implement the above as, simply: template type_info dynamic_id(T const volatile* x, ...) { // const_cast to T* used to work around broken compilers which // leave cv-qualifications on type_info. return boost::python::type_info(typeid(const_cast(x))); } template static PyTypeObject* query_most_derived_PyTypeObject(Arg& x) { typedef typename unforward::type arg_type; arg_type a = x; converter::registration const* registration_data = converter::registry::query( dynamic_id(&a) ); if (registration_data && registration_data->class_object) return registration_data->class_object; else return converter::registered::converters.class_object; } (or something like that)? > It seems to work fine on a few examples I tried here - I must admit that > I've not run the whole test suite, but what do you think of it ?! I think you're barking up the right tree, but it still needs some work. Very exciting! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 19:46:23 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 13:46:23 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> ("Peter Dimov"'s message of "Tue, 12 Nov 2002 20:10:59 +0200") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> Message-ID: "Peter Dimov" writes: >> I'd like to explore a few refinements with you. For example, it may >> be possible to get real shared_ptr interoperability by deriving >> py_counted_base from counted_base. Maybe we should ask Peter to >> weigh in on this. Peter, Brett's code is attached to this page: >> http://aspn.activestate.com/ASPN/Mail/Message/1430235 > > I don't really understand what the code is about ;-) Here's the quick skinny: - Boost.Python allows you to specify how Python objects will hold the C++ objects they wrap. You can specify that they be held by shared_ptr (or any other smart pointer), in which case the library will generate converters to/from Python for shared_ptr. The to_python converters will simply build a new Python object around the shared_ptr<>. - If you have virtual functions you want to ``override in Python'', you actually have to hold the T object with a derived class U which overrides the virtual functions to dispatch back to Python. In this case, class U naturally has to have access to the Python object (that's the pyobj_ member you see in Brett's code). - You can further specify that your C++ object is held by shared_ptr, which is what Brett is doing. That allows you to hold a U object for dispatching, yet still pass shared_ptrs around in your C++ code. There are several problems with the above arrangement, but the most important one is that if you keep the shared_ptr alive longer than its corresponding Python object, calls to the Python-overridable virtual functions will crash, because they'll try to call through an invalid pointer. That's what Brett is trying to address with his crazy pointer. > but I'm leaning towards moving counted_base back to boost::detail > and removing the intrusive counting "feature" of shared_ptr. > > The interoperability/shared_from_this problems have alternate solutions as > described in the techniques "document". Hmm. I guess that rules out that option. > I'm not sure whether this helps or not, but it's also possible to have a > shared_ptr to PyObject, by using Py_DECREF as the deleter (also described in > the attached file). Now /that's/ starting to sound intriguing. I wonder if it's possible to derive our U class from boost::python::objects::instance<>, and automatically generate shared_ptr<> converters for it. Maybe the whole idea of holding a shared_ptr is bogus from the get-go. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 20:05:59 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 14:05:59 -0500 Subject: [C++-sig] Re: Problem Wrapping DirectX with Boost Python In-Reply-To: (Mark Russell's message of "Mon, 11 Nov 2002 10:53:31 -0800") References: Message-ID: Mark Russell writes: > Hi Dave, Hi Mark. Please post Boost.Python questions to the C++-sig: http://www.python.org/sigs/c++-sig > I am using Boost Python to wrap DirectX and have run into a problem > I can't seem to get around. Def seems to have trouble with > __stdcall this works ok for me when I call bind directly so I'm not > sure where to go from here. I have attached a short test example > cloned from the bind tests to show you where the problem is. I am > using msvc 6.5 and have tried both boost 1.29 and the latest from > CVS. Thanks in advance -- great library! I am very excited to be > working with it. Thanks, I'm excited that so many people are using it! > > Test Code: > > #define BOOST_BIND_ENABLE_STDCALL > #define BOOST_MEM_FN_ENABLE_STDCALL > > #include > using namespace boost::python; > > long __stdcall f_0() > { > return 17041L; > } > > > BOOST_PYTHON_MODULE_INIT(test_std_call) > { > def("f_0", f_0); > > } > > Error Message: > > Compiling... > stdcall.cpp > c:\boost\boost\python\detail\arg_tuple_size.hpp(61) : error C2664: 'struct > boost::python::detail::char_array<0> __cdecl > boost::python::detail::arg_tuple_size_helper(long (__cdecl *)(void))' : > cannot convert parameter 1 from 'long (__stdcall *)(void) > ' to 'long (__cdecl *)(void)' > This conversion requires a reinterpret_cast, a C-style cast or > function-style cast Right. The problem is that there are lots of Boost.Python components which don't account for the presence of "extralegal" constructs like __stdcall and __fastcall. In order to handle these automatically we'd need, at the very least, to extend boost/python/detail/arg_tuple_size.hpp to handle these cases, and I'm guessing that there are a quite a few other places like that in the code as well (e.g. boost/python/detail/returning.hpp). Here are your choices: 1. Implement the extensions yourself and submit a patch. We'd really love that! 2. Write "thin wrapper" functions around all the functions you want to wrap, and wrap the wrappers: long f_0_aux() { return f_0(); } ... def("f_0", f_0_aux); 3. Wait for us to get around to extending Boost.Python to deal with __stdcall. Joel may be working on an ActiveX project soon himself, so it's not an impossibility that it will happen. However, this is still somewhat of a long shot. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 20:36:07 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 14:36:07 -0500 Subject: [C++-sig] MSVC project file In-Reply-To: ("Scott A. Smith"'s message of "Tue, 12 Nov 2002 08:20:16 -0500") References: Message-ID: "Scott A. Smith" writes: > Yep, this is now fixed. What is the difference between the Win32 > Debug and Win32 Debug Python builds? See http://www.boost.org/libs/python/doc/building.html#variants -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 20:42:01 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 14:42:01 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: ("Scott A. Smith"'s message of "Tue, 12 Nov 2002 12:38:55 -0500") References: Message-ID: "Scott A. Smith" writes: > I am biting the bullet and switching my project over to use V2 finally. > Many thanks to everyone working on the BP, the new documentation looks > terrific. I am hoping someone can take the time to answer a couple of > very simple questions to get me started. > > 1.) In the Hello tutorial, I see that one uses the Python Module name > when creating instances of a class object. > > >>> import hello > >>> planet = hello.World() > > But in other places, it seems like the module name is not > required. Where? > I don't recall ever needing the module name for any exposed classes > from V1. It was no different in V1. > I understand that once planet (above) is made one does not need > hello. to access its members, but is it always true that one > needs it when declaring class objects? What about global > functions? Is there a way to set things so they do not need > this? >>> from hello import * > 2.) The tutorial begins dealing with classes, and looks so nice that I > doubt I'll have many problems switching to use V2. But on simpler things > I am at a loss. At the start of my project, before I even get to dealing > with my C++ classes, I have some global variables and functions > declared. > For example, > > extern const double PLANCK; (in .hpp) > const double PLANCK = 6.6260755e-34; (in .cpp) > > which in BP V1 I exposed using something like > > PyModName.add(boost::python::make_ref(PLANCK), "PLANCK"); > > Now make_ref & PyModName.add are gone, so I took a guess & tried > > def("PLANCK", PLANCK, reference_existing_object()); > > which compiles but doesn't link. How do I exposes a simple constant, not > in any class but globally defined. scope().attr("PLANCK") = 6.6260755e-34; > Can I do it "read-only" as suggested > in the tutorial when explaining class Var where it uses > .def_readonly("name", &Var::name)? Nope. This is a Python feature/limitation. There's no way to add properties to modules, and they don't have overridable __getattr__/__setattr__ functions. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 20:55:03 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 14:55:03 -0500 Subject: [C++-sig] Static, again... In-Reply-To: <20021112100724.GA26115@vervet.localnet> (Hugo van der Merwe's message of "Tue, 12 Nov 2002 12:07:24 +0200") References: <20021112100724.GA26115@vervet.localnet> Message-ID: Hugo van der Merwe writes: > I had a look at the mailing list archives about this topic, I'm still > not clear on how exactly it works: > >> #include >> #include >> >> struct Num { >> Num() {} >> ~Num() {} >> static int getDims() {return 3;} >> int dims() {return 5;} >> }; >> >> BOOST_PYTHON_MODULE_INIT(numTest) >> { >> using namespace boost::python; >> module numTestMod("numTest"); >> numTestMod >> .add >> ( class_("Num") >> .def_init() >> .def("getDims",&Num::getDims) >> .def("dims", &Num::dims) >> ) >> ; >> } > >> We don't have a way to make true static methods yet. This part is still true. >> getDims will work fine if you access it through the class like this: >> >> Nums.getDims() I was wrong when I posted that. > I am trying to wrap a "Settings" class which does not have a public > constructor, it expects you to call "GetInstance" to get a pointer to > the always-existing instance (making the settings "global"). The above > would make me think that this will work: > > class_("Settings", no_init) > .def("GetInstance", &Settings::GetInstance, > return_value_policy()); > > I cannot call Settings.GetInstance(), it gives me: > > TypeError: unbound method Boost.Python.function object must be called with Settings instance as first argument (got nothing instead) Right, that won't work. > I also read about an approach that looks something like this: > > object settings_class = > class_("Settings", no_init); > settings_class.attr("Settings") = &Settings::GetInstance; > > But I don't know how that is supposed to work... Yeah, that won't work either. > If I wanted to expose GetInstance as Settings() instead (once I get it > working), is it as simple as just calling it "__init__" instead? Unfortunately, no. That would be cool, though, wouldn't it? I'm pretty sure you can do this after you define class_, though: // Note no leading dot. def("Settings", &Settings::GetInstance , return_value_policy()); This will replace the class in the module by a function called Settings that gets the instance. > (Should I then have no_init in the class_<> invocation or not? Yep. > I noticed the tutorial talks about no_init, but then mentions as > soon as you wish to derive classes from it, you do not want > no_init. So when is no_init useful? Only when you cannot construct a > class and don't want to derive from it, i.e. when you're using > "factories"?) I think that's right. However, I wonder if we should change the __init__ function that you get from no_init to be a no-op unless the Python class actually has the same type as the abstract base... > I am really astonished with what can be achieved with C++ - > Boost.Python is really amazing! Thank you! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 12 21:25:18 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 15:25:18 -0500 Subject: [C++-sig] Re: Re: Re: Re: Re: Re: custom iterator object In-Reply-To: ("Mike Rovner"'s message of "Tue, 12 Nov 2002 09:52:00 -0800") References: Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:usmy6zxo8.fsf at boost-consulting.com... >> What is CustomIter? I've never seen this before. I'm sorry, but I >> can't be expected to understand your code if you don't give me a >> complete picture. > > OK. Let me try to give a whole picture: > > 1) I have an API: > > typedef int* T; // some type > > class CustomIter { > T First(); > T Next(); > }; > > class Scheme { > CustomIter GetIter() const; > CustomIter GetIter1() const; > CustomIter GetIter2() const; > }; > > 2) I want to expose Scheme to Python with 3 iterators > GetIter as __iter__, GetIter1 as attribute 'base', GetIter2 as attribute > 'top' > i.e. I want to be able to write: > s=Scheme() > for i in s: print i > for i in s.base: print i > for i in s.top: print i OK so far. > 3) In order to do that I created C++ wrap for CustomIter: > > class MyIter { > MyIter(CustomIter& init); > T next(); > }; Why? Why not just expose CustomIter? > and exposed it: > > object identity(object x) { return x; } > > class_("_myiter", no_init) > .def("__iter__", identity) > .def("next, &MyIter::next) > ; > > Now I use 'make_iter' to create a 'iter_gen' object instance with operator() > which when called with Scheme& produces MyIter object: > > class iter_gen { > typedef CustomIter (Scheme::*PM)() const; > iter_gen(PM pm) : _pm(pm); > MyIter operator()(Scheme& s) { return MyIter((s.*pm)()); } > private: > PM _pm; > }; > > iter_gen make_iter(PM pm) { return iter_gen(pm); } > > Then I hope to wrap Scheme with using of that 'iter_gen' objects to produce > my iterators. > > make_iter(&Scheme::GetIter) > make_iter(&Scheme::GetIter1) > make_iter(&Scheme::GetIter2) > > But I still don't know how. > And even not sure that I'm going in right direction at all :( You certainly have _me_ confused with all these levels of indirection. But I think I finally see what you're driving at, and it would obviously be helpful if there were a way to wrap function objects instead of just function pointers. Fortunately, I think there's a solution for your case: template class iter_gen { static MyIter execute(Scheme& s) { return MyIter((s.*pm)()); } }; ... .def("__iter__", &iter_gen<&Scheme::GetIter>::execute) .add_property("a", &iter_gen<&Scheme::GetIter1>::execute) ... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Tue Nov 12 22:21:24 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Tue, 12 Nov 2002 16:21:24 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: Message-ID: Hi Dave, Thanks for the response. > > 1.) In the Hello tutorial, I see that one uses the Python Module name > > when creating instances of a class object. > > > > >>> import hello > > >>> planet = hello.World() > > > > But in other places, it seems like the module name is not > > required. > > Where? > > > I don't recall ever needing the module name for any exposed classes > > from V1. > > > It was no different in V1. Well, you forced me to search for a way to explain how you could possibly state that! I've never before even tried using the module name method and was fairly successful using my exported classes with V1. What I found out was that I didn't know the difference between >>> import hello and >>> from hello import * Now I do, probably about doubling my Python abilities. Since the day I first tried Python (not so long ago, as this was the day I first saw Boost.Python also), I have always used "from PyModule import *" and never knew any different. Nor can I find mention of it in my O'Reilly Python book. But I did find out about it from a Google search and then http://www.python.org/doc/current/ref/import.html, so that mystery is solved. I take it good Python programmers largely frown on using "from PyModule import *"? As for where the tutorial seems to not have any module name, on http://www.boost.org/libs/python/doc/tutorial/doc/class_data_members.html the line >>> x = Var('pi') should be something like x = hello.Var('pi') if it is in the hello module, unless I am again mistaken. > > How do I exposes a simple constant, not > > in any class but globally defined. > scope().attr("PLANCK") = 6.6260755e-34; But this is a re-definition isn't it? I don't mind doing that, but then if I change my C++ code (maybe to add more significant digits or the foundations of physics change) I'll have to change the Python export too. I can live with that though. > > Can I do it "read-only" as suggested > > in the tutorial when explaining class Var where it uses > > .def_readonly("name", &Var::name)? > > Nope. This is a Python feature/limitation. There's no way to add > properties to modules, and they don't have overridable > __getattr__/__setattr__ functions. > I guess that is still OK. But then would the statement >>> X = PyModule.PLANCK >>> Y = 1.e-27 or even PyModule.PLANCK = 1.e-27 actually alter what the value of PLANCK is within the Python interpreter? Thanks Dave, this should keep me going for a while. Scott From mike at bindkey.com Tue Nov 12 23:07:07 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 12 Nov 2002 14:07:07 -0800 Subject: [C++-sig] Re: Re: Re: Re: Re: Re: Re: custom iterator object References: Message-ID: "David Abrahams" wrote in message news:ufzu6cz81.fsf at boost-consulting.com... > > 1) I have an API: > > > > typedef int* T; // some type > > > > class CustomIter { > > T First(); > > T Next(); > > }; > > > > class Scheme { > > CustomIter GetIter() const; > > CustomIter GetIter1() const; > > CustomIter GetIter2() const; > > }; > > > > 2) I want to expose Scheme to Python with 3 iterators > > GetIter as __iter__, GetIter1 as attribute 'base', GetIter2 as attribute > > 'top' > > i.e. I want to be able to write: > > s=Scheme() > > for i in s: print i > > for i in s.base: print i > > for i in s.top: print i > > OK so far. > > > 3) In order to do that I created C++ wrap for CustomIter: > > > > class MyIter { > > MyIter(CustomIter& init); > > T next(); > > }; > > Why? Why not just expose CustomIter? If I understand correctly, I will NOT be able to use exposed CustomIter as Python iterator. Please correct me, if I'm wrong. > You certainly have _me_ confused with all these levels of indirection. > But I think I finally see what you're driving at, and it would > obviously be helpful if there were a way to wrap function objects > instead of just function pointers. Fortunately, I think there's a > solution for your case: Wonderful! It's working perfectly fine. Thanks a lot! Mike PS. For a next dark (for me) corner I'm opening a new thread. From dave at boost-consulting.com Tue Nov 12 23:15:53 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 17:15:53 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: ("Scott A. Smith"'s message of "Tue, 12 Nov 2002 16:21:24 -0500") References: Message-ID: "Scott A. Smith" writes: > Hi Dave, > > Thanks for the response. > >> > 1.) In the Hello tutorial, I see that one uses the Python Module >> > name when creating instances of a class object. >> > >> > >>> import hello planet = hello.World() >> >> > But in other places, it seems like the module name is not >> > required. >> >> Where? >> >> > I don't recall ever needing the module name for any exposed >> > classes from V1. >> >> It was no different in V1. > > Well, you forced me to search for a way to explain how you could possibly state that! I've never > before even tried using the module name method and was fairly successful using my exported classes with > V1. What I found out was that I didn't know the difference between > > >>> import hello and >>> from hello import * > > Now I do, probably about doubling my Python abilities. Since the > day I first tried Python (not so long ago, as this was the day I > first saw Boost.Python also), I have always used "from PyModule > import *" and never knew any different. Nor can I find mention of > it in my O'Reilly Python book. But I did find out about it from a > Google search and then > http://www.python.org/doc/current/ref/import.html, so that mystery > is solved. I take it good Python programmers largely frown on using > "from PyModule import *"? Yes, and rightly so. > As for where the tutorial seems to not have any module name, on > > http://www.boost.org/libs/python/doc/tutorial/doc/class_data_members.html > > the line > >>>> x = Var('pi') > > should be something like x = hello.Var('pi') if it is in the hello > module, unless I am again mistaken. Yes, I guess you're right. We start leaving out a bunch of detail on that page. Joel, would you consider what we can do to clarify that? >> > How do I exposes a simple constant, not in any class but >> > globally defined. > >> scope().attr("PLANCK") = 6.6260755e-34; > > But this is a re-definition isn't it? Huh? What do you mean by "re-definition"? > I don't mind doing that, but then if I change my C++ code (maybe to > add more significant digits or the foundations of physics change) > I'll have to change the Python export too. I can live with that > though. Oh, well of course you can write: scope().attr("PLANCK") = PLANCK; >> > Can I do it "read-only" as suggested in the tutorial when >> > explaining class Var where it uses .def_readonly("name", >> > &Var::name)? >> Nope. This is a Python feature/limitation. There's no way to add properties to modules, and they >> don't have overridable __getattr__/__setattr__ functions. >> > > I guess that is still OK. But then would the statement > >>>> X = PyModule.PLANCK Y = 1.e-27 ???syntax error---------^ > or even > > PyModule.PLANCK = 1.e-27 > > actually alter what the value of PLANCK is within the Python interpreter? Sure. It's just a binding in the module. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Wed Nov 13 00:12:34 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Tue, 12 Nov 2002 18:12:34 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: Message-ID: Hi Dave, > Oh, well of course you can write: > > scope().attr("PLANCK") = PLANCK; Yep, I did a "du-oh" just after sending off my last e-mail. Now I am trying to figure out how to deal with a class member function that returns const std::string&. I assume I need to figure out call policies, but the tutorial info isn't real clear to me. I just have const std::string& myclass::myfunction() The compiler complains when I add this to the class using .def("myfunction", &myclass::myfunction) but since the function takes no arguments I cannot figure out how or if I need to modify it with return_internal_reference and with_custodian_and_ward. Or perhaps something else that sets the call policy.... Scott From mike at bindkey.com Wed Nov 13 00:08:16 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 12 Nov 2002 15:08:16 -0800 Subject: [C++-sig] wrapping complex attributes Message-ID: Here is another dark corner: I have a complex C++ object: class Heavy { void SetX(const char *name, const T1& val); T1 GetX(const char *name); void DelX(const char *name); Iter EnumX(); void SetY(const char *name, const T2& val); T2 GetY(const char *name); void DelY(const char *name); Iter EnumY(); void SetZ(const char *name, const T3& val); T3 GetZ(const char *name); void DelZ(const char *name); Iter EnumZ(); } It seems natural to expose class Heavy with 3 attributes: x,y and z which will behave like dictionaries. How to do that? I think in favor of following approach, but can't follow it to the finest detail. Create a helper object: struct helper { static R create(Heavy& o) { return (o.*pm)(arg); } } Than create a helper class(es) ala dictionary: helper_z = class_<>("map_z") .def("__setattr__", helper::create) .def("__getattr__", helper::create) .def("__delattr__", helper::create) .def("__iter__", helper,&Heavy::EnumZ>::create) ; and expose them: class_("Heavy") .def_readwrite("x", helper_x) .def_readwrite("y", helper_y) .def_readwrite("z", helper_z) ; Is it a right approach and if so, how to refine it? Thanks, Mike From dave at boost-consulting.com Wed Nov 13 00:13:11 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 18:13:11 -0500 Subject: [C++-sig] wrapping complex attributes In-Reply-To: ("Mike Rovner"'s message of "Tue, 12 Nov 2002 15:08:16 -0800") References: Message-ID: "Mike Rovner" writes: > Here is another dark corner: > > I have a complex C++ object: > > class Heavy { > void SetX(const char *name, const T1& val); > T1 GetX(const char *name); > void DelX(const char *name); > Iter EnumX(); > > void SetY(const char *name, const T2& val); > T2 GetY(const char *name); > void DelY(const char *name); > Iter EnumY(); > > void SetZ(const char *name, const T3& val); > T3 GetZ(const char *name); > void DelZ(const char *name); > Iter EnumZ(); > } > > It seems natural to expose class Heavy with 3 attributes: x,y and z which > will behave like dictionaries. > How to do that? Use the add_property member of class_<>: http://www.boost.org/libs/python/doc/v2/class.html#class_-spec-modifiers HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 13 00:14:52 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 18:14:52 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: ("Scott A. Smith"'s message of "Tue, 12 Nov 2002 18:12:34 -0500") References: Message-ID: "Scott A. Smith" writes: > Hi Dave, > > >> Oh, well of course you can write: >> >> scope().attr("PLANCK") = PLANCK; > > Yep, I did a "du-oh" just after sending off my last e-mail. Now I am > trying to figure out how to deal with a class member function that > returns const std::string&. I assume I need to figure out call > policies, but the tutorial info isn't real clear to me. Then please read the reference manual, which describes Call Policies in detail. > I just have > > const std::string& myclass::myfunction() > > The compiler complains when I add this to the class using > > .def("myfunction", &myclass::myfunction) > > but since the function takes no arguments I cannot figure out how > or if I need to modify it with > return_internal_reference and with_custodian_and_ward. Or perhaps > something else that sets the call policy.... How about return_value_policy? Is it important to avoid copying the resulting string? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From BPettersen at NAREX.com Wed Nov 13 00:33:44 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Tue, 12 Nov 2002 16:33:44 -0700 Subject: [C++-sig] () and [] operators Message-ID: <60FB8BB7F0EFC7409B75EEEC13E20192017747EA@admin56.narex.com> > From: Kerim Borchaev [mailto:warkid at hotbox.ru] > > I wasn't able to find an "intuitive"(like for other > operators) way to expose () and [] > operators. How am I supposed to do it? The () operator should be pretty straight forward binding to __call__, however operator[] must raise a Python IndexError when called with an out of range argument (e.g. the old for loop protocol required this and it is still used for objects that don't define __iter__). Here's example code from wrapping our internal string class, NString: namespace { char NString_get_item(NString& self, int index) { if (index >= self.size()) { PyErr_SetObject(PyExc_IndexError, PyInt_FromLong(index)); boost::python::throw_error_already_set(); } return self[index]; } } void wrap_NString() { class_ >("NString", init()) ... .def("__getitem__", &NString_get_item) ; } (basically, just bind __getitem__ to a standalone function that does the index checking...) hth, -- bjorn From djowel at gmx.co.uk Wed Nov 13 00:54:32 2002 From: djowel at gmx.co.uk (Joel de Guzman) Date: Wed, 13 Nov 2002 07:54:32 +0800 Subject: [C++-sig] A couple of simple BP V2 questions References: Message-ID: <015801c28aa6$ebc844d0$8c564eca@kim> ----- Original Message ----- From: "David Abrahams" > > As for where the tutorial seems to not have any module name, on > > > > http://www.boost.org/libs/python/doc/tutorial/doc/class_data_members.html > > > > the line > > > >>>> x = Var('pi') > > > > should be something like x = hello.Var('pi') if it is in the hello > > module, unless I am again mistaken. > > Yes, I guess you're right. We start leaving out a bunch of detail on > that page. Joel, would you consider what we can do to clarify that? Sure. Thanks for your comment, Scott. If there are some more things you wish from the tutorial, feel free to post them here. I'm taking notes and collecting a TODO list. --Joel From BPettersen at NAREX.com Wed Nov 13 04:09:15 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Tue, 12 Nov 2002 20:09:15 -0700 Subject: [C++-sig] Calling python function from C++ Message-ID: <60FB8BB7F0EFC7409B75EEEC13E20192017747ED@admin56.narex.com> In http://www.boost.org/libs/python/doc/v2/callbacks.html it says "...given an _object_ instance f holding the function...", however I can't find a simple way to get a reference to a Python function into an object instance. My test code is: PyRun_String( "def hello(s): \n" " return 'hello ' + s \n", Py_file_input, ns, ns); PyObject* fn = PyRun_String("hello", Py_eval_input, ns, ns); I then want code with the same semantics as: PyObject* res = PyObject_CallFunction(fn, "s", "world"); Py_DECREF(fn); std::string cpp_res = PyString_AsString(res); Py_DECREF(res); the closest I've gotten is: object hello = object(handle<>(borrowed(fn))); object res = hello("world"); std::string cpp_res = extract(res); I found the wrapping of 'fn' in the example in the "errors.hpp" section. Is this the easiest/correct way to do this? Second question: are the reference counts in the Boost example all taken care of at end-of-scope? -- bjorn From dave at boost-consulting.com Wed Nov 13 04:08:43 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 12 Nov 2002 22:08:43 -0500 Subject: [C++-sig] Calling python function from C++ In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E20192017747ED@admin56.narex.com> ("Bjorn Pettersen"'s message of "Tue, 12 Nov 2002 20:09:15 -0700") References: <60FB8BB7F0EFC7409B75EEEC13E20192017747ED@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: > In http://www.boost.org/libs/python/doc/v2/callbacks.html it says > "...given an _object_ instance f holding the function...", however I > can't find a simple way to get a reference to a Python function into > an object instance. > > My test code is: > > PyRun_String( > "def hello(s): \n" > " return 'hello ' + s \n", > Py_file_input, ns, ns); The PyRun_String docs say: PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals) Return value: New reference. ^^^^^^^^^^^^^ Which means you're leaking a reference here. > PyObject* fn = PyRun_String("hello", Py_eval_input, ns, ns); > > I then want code with the same semantics as: > > PyObject* res = PyObject_CallFunction(fn, "s", "world"); > Py_DECREF(fn); > std::string cpp_res = PyString_AsString(res); > Py_DECREF(res); > > the closest I've gotten is: > > object hello = object(handle<>(borrowed(fn))); Why are you using borrowed()? That causes another reference to be leaked. > object res = hello("world"); > std::string cpp_res = extract(res); > > I found the wrapping of 'fn' in the example in the "errors.hpp" > section. Is this the easiest/correct way to do this? You want something like: handle<> fn = PyRun_String("hello", Py_eval_input, ns, ns); object hello(fn); std::string cpp_res = extract(hello("world")); > Second > question: are the reference counts in the Boost example all taken > care of at end-of-scope? Yes. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From BPettersen at NAREX.com Wed Nov 13 05:18:31 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Tue, 12 Nov 2002 21:18:31 -0700 Subject: [C++-sig] Calling python function from C++ Message-ID: <60FB8BB7F0EFC7409B75EEEC13E20192017747F2@admin56.narex.com> > From: David Abrahams [mailto:dave at boost-consulting.com] > > "Bjorn Pettersen" writes: > [snip] > > > > My test code is: > > > > PyRun_String( > > "def hello(s): \n" > > " return 'hello ' + s \n", > > Py_file_input, ns, ns); [snip] > Which means you're leaking a reference here. Thanks (bug in my testapp, my library does the right thing ;-) > > PyObject* fn = PyRun_String("hello", Py_eval_input, ns, ns); [snip] > > object hello = object(handle<>(borrowed(fn))); > > Why are you using borrowed()? That causes another reference > to be leaked. It was the only example I could find of converting a PyObject* to an object ;-) Safe to say I was a little confused by the handle documentation also... [snip] > You want something like: > > handle<> fn = PyRun_String("hello", Py_eval_input, ns, ns); > object hello(fn); > std::string cpp_res = extract(hello("world")); Ah.. that actually makes sense now. Thanks a bunch. -- bjorn ps: the way Python functions are exposed is extremely cool, especially for embedded apps! From hugo at adept.co.za Wed Nov 13 07:51:12 2002 From: hugo at adept.co.za (Hugo van der Merwe) Date: Wed, 13 Nov 2002 08:51:12 +0200 Subject: [C++-sig] Static, again... In-Reply-To: References: <20021112100724.GA26115@vervet.localnet> Message-ID: <20021113065112.GA539@vervet.localnet> > Unfortunately, no. That would be cool, though, wouldn't it? I'm > pretty sure you can do this after you define class_, though: > > // Note no leading dot. > def("Settings", &Settings::GetInstance > , return_value_policy()); > > This will replace the class in the module by a function called > Settings that gets the instance. Yes, that worked beautifully! Now I just do (in Python): Settings().detailThreshold = 10 Settings().verbose = true Just found it hard to decide whether I should keep the Python wrapper as close as possible to the C++ library and use "SetVerbose" and "GetVerbose", or whether to use Boost.Python's really nifty properties. Well, I couldn't resist! ;) Do properties currently only handle straight forward single parameter "setters"? How difficult would it be to allow it to do two parameters, with e.g. "object.property[5] = 10"? (Or can it do that already?) > I think that's right. However, I wonder if we should change the > __init__ function that you get from no_init to be a no-op unless the > Python class actually has the same type as the abstract base... Sounds like an idea ... Thanks again! Hugo van der Merwe From hugo at adept.co.za Wed Nov 13 08:25:48 2002 From: hugo at adept.co.za (Hugo van der Merwe) Date: Wed, 13 Nov 2002 09:25:48 +0200 Subject: [C++-sig] Static, again... In-Reply-To: <20021113065112.GA539@vervet.localnet> References: <20021112100724.GA26115@vervet.localnet> <20021113065112.GA539@vervet.localnet> Message-ID: <20021113072548.GB539@vervet.localnet> On Wed, Nov 13, 2002 at 08:51:12AM +0200, Hugo van der Merwe wrote: > Do properties currently only handle straight forward single parameter > "setters"? How difficult would it be to allow it to do two parameters, > with e.g. "object.property[5] = 10"? (Or can it do that already?) I just saw this in another email: > > It seems natural to expose class Heavy with 3 attributes: x,y and z which > > will behave like dictionaries. > > How to do that? > > Use the add_property member of class_<>: > > http://www.boost.org/libs/python/doc/v2/class.html#class_-spec-modifiers Cool, I'll try testing it later. Is there a way to expose a 3 parameter "setter" (which can then be addressed like a matrix)? I'd think this is asking a bit too much, at this point one should probably just stick with "Get(x,y)" and "Set(x,y,value)" methods. Thanks, Hugo van der Merwe From brett.calcott at paradise.net.nz Wed Nov 13 09:48:02 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Wed, 13 Nov 2002 21:48:02 +1300 Subject: [C++-sig] Re: call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare><003601c28a76$dc2e96d0$1d00a8c0@pdimov2> Message-ID: <003501c28af1$de7b9e30$f6784fcb@hare> > > > > The interoperability/shared_from_this problems have alternate solutions as > > described in the techniques "document". > Where is this document? I had a look around the boost files section and couldn't find anything that looked relevant. > > Now /that's/ starting to sound intriguing. I wonder if it's possible > to derive our U class from boost::python::objects::instance<>, and > automatically generate shared_ptr<> converters for it. > > Maybe the whole idea of holding a shared_ptr is bogus from the get-go. > I'm not sure what it buys you either. If I have to derive the U class from boost::python::objects::instance<> then I have already given away non-intrusiveness. Are there some other advantages to using shared_ptr? Cheers, Brett From brett.calcott at paradise.net.nz Wed Nov 13 10:07:23 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Wed, 13 Nov 2002 22:07:23 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare> Message-ID: <003601c28af4$151387d0$f6784fcb@hare> > > > The problem is I wanted to expose agent and py_agent, > > Why? > Here is some context: I am writing a multi-agent simulation. I have done a bit of this in C++, but this time I want to write just the core engine in C++ and use python for all the surrounding framework. I want to be able to create agents, save them, query them, all using a commandline or gui in python (wx probably). However, when it comes to the actual simulation I want this to happen in C++. It's a bit like Numeric - the workhorse calls involving iteration across lots of data happen in C. However, for experimental purposes, I want to be able create a python agent which inherits all of the features of the normal agent - but allows me to override certain things. Once I get something right, I can push the python code back into C++ for speed. So - I wanted agent to be exposed to python so I can create pure C++ agents, and py_agent exposed so I can choose to override the default compiled behaviour and sacrifice some speed whilst I mess around with new features. Actually (although it no longer matters with the solution I have no using to_python converters) I needed to expose agent otherwise the the python calls involving agent_ptr would not work. > > > > The outline is this: > > 1. I use the intrusive_ptr template in boost. This is currently > > undocumented, and I also needed to add a 'typedef T element_type' to the > > class to make it work with Boost.Python. Note that the pointee<> approach > > documented for the smart_ptr example doesn't work with msvc. > > Of course not ;-) > I tried it first before I realised (Duh). Probably worth mentioning in the Docs. > > Well, I think it's damned cool! I spent a bunch of time turning > approaches like this one over and over in my mind, but I couldn't see > how to make it work. At first I thought your design had to be broken, > but I failed to poke any holes in it. IIUC, the structure looks like > this: > Yeah, I thought it had to be broken too at first :) > > PyObject > +-----------+ > | ob_refcnt | py_agent > +-----------+ +------------+ > | agent_ptr |------>| use_count_ | > +-----------+ +------------+ > ^ | pyobj_ |--+ > | +------------+ | > | | ... | | > | +------------+ | > | | > +-------------------------------+ > Nice picture! > > Your remarks here: > > // need to put them in the boost namespace so they get found > // before the defaults > namespace boost > { > inline void intrusive_ptr_add_ref(py_counted_base * p) > { > p->add_ref(); > } > > inline void intrusive_ptr_release(py_counted_base * p) > { > p->release(); > } > } // end namespace boost > > Are wrong, and putting these in namespace boost will not work on > conforming compilers. They need to go in the same namespace as > py_counted_base on most compilers. For compilers that don't do Koenig > lookup namespace boost will probably be OK. > Koenig lookup. Sigh... You forget about that sort of thing after using the same broken compiler for 4 years. 'Whatever works' becomes your motto. > I'd like to explore a few refinements with you. For example, it may be > possible to get real shared_ptr interoperability by deriving > py_counted_base from counted_base. Maybe we should ask Peter to weigh > in on this. Peter, Brett's code is attached to this page: > http://aspn.activestate.com/ASPN/Mail/Message/1430235 > Ok. I'm enjoying this. ciao, Brett From hugo at adept.co.za Wed Nov 13 11:06:33 2002 From: hugo at adept.co.za (Hugo van der Merwe) Date: Wed, 13 Nov 2002 12:06:33 +0200 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: <015801c28aa6$ebc844d0$8c564eca@kim> References: <015801c28aa6$ebc844d0$8c564eca@kim> Message-ID: <20021113100633.GA8172@vervet.localnet> On Wed, Nov 13, 2002 at 07:54:32AM +0800, Joel de Guzman wrote: > Sure. Thanks for your comment, Scott. If there are some more things > you wish from the tutorial, feel free to post them here. I'm taking notes > and collecting a TODO list. Another idea for the tutorial: I do not recall seeing an example in the new tutorial about returning tuples. It might be worthwhile adding an example for wrapping a function returning more than one value via references by writing a wrapper function that uses make_tuple. HTH, Hugo van der Merwe From dave at boost-consulting.com Wed Nov 13 14:19:53 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 08:19:53 -0500 Subject: [C++-sig] Static, again... In-Reply-To: <20021113072548.GB539@vervet.localnet> (Hugo van der Merwe's message of "Wed, 13 Nov 2002 09:25:48 +0200") References: <20021112100724.GA26115@vervet.localnet> <20021113065112.GA539@vervet.localnet> <20021113072548.GB539@vervet.localnet> Message-ID: Hugo van der Merwe writes: > On Wed, Nov 13, 2002 at 08:51:12AM +0200, Hugo van der Merwe wrote: >> Do properties currently only handle straight forward single parameter >> "setters"? How difficult would it be to allow it to do two parameters, >> with e.g. "object.property[5] = 10"? (Or can it do that already?) > > I just saw this in another email: > >> > It seems natural to expose class Heavy with 3 attributes: x,y and z which >> > will behave like dictionaries. >> > How to do that? >> >> Use the add_property member of class_<>: >> >> http://www.boost.org/libs/python/doc/v2/class.html#class_-spec-modifiers > > Cool, I'll try testing it later. Is there a way to expose a 3 > parameter "setter" (which can then be addressed like a matrix)? I'd > think this is asking a bit too much, at this point one should probably > just stick with "Get(x,y)" and "Set(x,y,value)" methods. Yes, but I'll leave it as an "exercise for the reader". Properties are a Python 2.2 thing, not a Boost.Python feature. Try it in pure Python. If you can get that to work, you can probably get it to work in Boost.Python. Hint: you'll need a proxy class. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 13 14:33:29 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 08:33:29 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: <003501c28af1$de7b9e30$f6784fcb@hare> ("Brett Calcott"'s message of "Wed, 13 Nov 2002 21:48:02 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> <003501c28af1$de7b9e30$f6784fcb@hare> Message-ID: "Brett Calcott" writes: >> > >> > The interoperability/shared_from_this problems have alternate solutions > as >> > described in the techniques "document". >> > > Where is this document? I had a look around the boost files section and > couldn't find anything that looked relevant. It was enclosed in Peter's message. Here it is again. >> Now /that's/ starting to sound intriguing. I wonder if it's possible >> to derive our U class from boost::python::objects::instance<>, and >> automatically generate shared_ptr<> converters for it. >> >> Maybe the whole idea of holding a shared_ptr is bogus from the get-go. >> > > I'm not sure what it buys you either. If I have to derive the U > class from boost::python::objects::instance<> then I have already > given away non-intrusiveness. Which really doesn't matter at all because the U class is purpose-built. > Are there some other advantages to using shared_ptr? Oh, yes: many, many. For example, shared_ptr -> shared_ptr is a legitimate conversion, even though you haven't intruded on U. And probably more-importantly, shared_ptr<> interoperates seamlessly in many contexts and serves as a "one-stop shop" for nearly all smart pointer needs. Just see the enclosed document for reasons why. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: shared_ptr_techniques.txt URL: -------------- next part -------------- -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 13 14:40:34 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 08:40:34 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: <20021113100633.GA8172@vervet.localnet> (Hugo van der Merwe's message of "Wed, 13 Nov 2002 12:06:33 +0200") References: <015801c28aa6$ebc844d0$8c564eca@kim> <20021113100633.GA8172@vervet.localnet> Message-ID: Hugo van der Merwe writes: > On Wed, Nov 13, 2002 at 07:54:32AM +0800, Joel de Guzman wrote: >> Sure. Thanks for your comment, Scott. If there are some more things >> you wish from the tutorial, feel free to post them here. I'm taking notes >> and collecting a TODO list. > > Another idea for the tutorial: > > I do not recall seeing an example in the new tutorial about returning > tuples. It might be worthwhile adding an example for wrapping a > function returning more than one value via references by writing a > wrapper function that uses make_tuple. Good idea. Perhaps you could come up with some examples for us? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Peter.Bienstman at rug.ac.be Wed Nov 13 15:09:19 2002 From: Peter.Bienstman at rug.ac.be (Peter Bienstman) Date: Wed, 13 Nov 2002 15:09:19 +0100 Subject: [C++-sig] enum_::export Message-ID: <200211131509.22155.Peter.Bienstman@rug.ac.be> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, Some time ago, there was talk of implementing an export function for enums, which would dump all of its values in the enclosing scope: http://mail.python.org/pipermail/c++-sig/2002-September/002053.html Has this made it into BPL? I cannot seem to find a reference to it in the documentation. Thanks! Peter - ------------------------------------------------ Peter Bienstman Ghent University, Dep. of Information Technology Sint-Pietersnieuwstraat 41, B-9000 Gent, Belgium tel: +32 9 264 34 45, fax: +32 9 264 35 93 email: Peter.Bienstman at rug.ac.be - ------------------------------------------------ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE90l0R4dgPAIjyquoRApfHAJwICHQN+MZVq1SmR+xSmSplUDf74QCeKdgq eQ56aYGqjpIHaP0YVe3ths4= =53Lg -----END PGP SIGNATURE----- From dave at boost-consulting.com Wed Nov 13 15:10:04 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 09:10:04 -0500 Subject: [C++-sig] call_method In-Reply-To: <003601c28af4$151387d0$f6784fcb@hare> ("Brett Calcott"'s message of "Wed, 13 Nov 2002 22:07:23 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28af4$151387d0$f6784fcb@hare> Message-ID: "Brett Calcott" writes: >> >> > The problem is I wanted to expose agent and py_agent, >> >> Why? >> > > Here is some context: > I am writing a multi-agent simulation. I have done a bit of this in C++, but > this time I want to write just the core engine in C++ and use python for all > the surrounding framework. I want to be able to create agents, save them, > query them, all using a commandline or gui in python (wx probably). However, > when it comes to the actual simulation I want this to happen in C++. It's a > bit like Numeric - the workhorse calls involving iteration across lots of > data happen in C. However, for experimental purposes, I want to be able > create a python agent which inherits all of the features of the normal > agent - but allows me to override certain things. Once I get something > right, I can push the python code back into C++ for speed. > > So - I wanted agent to be exposed to python so I can create pure C++ agents, > and py_agent exposed so I can choose to override the default compiled > behaviour and sacrifice some speed whilst I mess around with new features. For that you just need to expose agent, using py_agent as a Holder. There's no need to expose py_agent itself. > Actually (although it no longer matters with the solution I have no using > to_python converters) I needed to expose agent otherwise the the python > calls involving agent_ptr would not work. > > Koenig lookup. Sigh... You forget about that sort of thing after using the > same broken compiler for 4 years. 'Whatever works' becomes your motto. Heh, I understand. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 13 15:11:21 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 09:11:21 -0500 Subject: [C++-sig] enum_::export In-Reply-To: <200211131509.22155.Peter.Bienstman@rug.ac.be> (Peter Bienstman's message of "Wed, 13 Nov 2002 15:09:19 +0100") References: <200211131509.22155.Peter.Bienstman@rug.ac.be> Message-ID: Peter Bienstman writes: > Hi, > > Some time ago, there was talk of implementing an export function for enums, > which would dump all of its values in the enclosing scope: > > http://mail.python.org/pipermail/c++-sig/2002-September/002053.html > > Has this made it into BPL? Not yet. Patches welcome! > I cannot seem to find a reference to it in the documentation. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ssmith at magnet.fsu.edu Wed Nov 13 18:28:38 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Wed, 13 Nov 2002 12:28:38 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: Message-ID: > David wrote: > How about return_value_policy? > Is it important to avoid copying the resulting string? No, copying is fine. Use of return_value_policy did the job, I just didn't read through the reference manual far enough. > Joel wrote: > Scott. If there are some more things > you wish from the tutorial, feel free to post them here. I'm taking notes > and collecting a TODO list. Just a few things as I go through the tutorial. On this page http://www.boost.org/libs/python/doc/tutorial/doc/default_arguments.html there is a nice discussion as to how one deals with functions that have default arguments. As for overloaded functions, things are a litte more cryptic. Where it says to use the described methods when the functions "are overloaded with a common sequence of initial arguments" I guess that indicates that 1.) The function return types are the same? 2.) The ordering of the arguments are very much the same i.e. (int), (int, string), (int, string, double) but then NOT (string,double,int)? 3.) If any overload is significantly dissimilar do not use this method? If that is true, then I think the text should discuss overloaded functions a little better since many (most) overloads will have such dissimilarities. In such cases then I assume one must still use thin wrappers? I think the page should have a link to the additional information in the reference manual. http://www.boost.org/libs/python/doc/v2/overloads.html#BOOST_PYTHON_FUNCTION _OVERLOADS-spec While the above reference page does show how to do overloads of the function "f", but these are quite different than dealing with say two different class Y member functions named f that have different argument types. This is what I am trying to do at the moment and, after quite a bit of time trying to figure how out to use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS I have now decided that I must use thin wrappers? Also, there is a small type on the above page which should probably be fixed: stryct Y {}; Regards, Scott From djowel at gmx.co.uk Wed Nov 13 18:53:27 2002 From: djowel at gmx.co.uk (Joel de Guzman) Date: Thu, 14 Nov 2002 01:53:27 +0800 Subject: [C++-sig] A couple of simple BP V2 questions References: Message-ID: <005101c28b3d$b7ecca90$a8564eca@kim> ----- Original Message ----- From: "Scott A. Smith" > Just a few things as I go through the tutorial. > > On this page > > http://www.boost.org/libs/python/doc/tutorial/doc/default_arguments.html > > there is a nice discussion as to how one deals with functions that have > default arguments. As for overloaded functions, things are a litte more > cryptic. > Where it says to use the described methods when the functions > > "are overloaded with a common sequence of initial arguments" > > I guess that indicates that > > 1.) The function return types are the same? > 2.) The ordering of the arguments are very much the same > i.e. (int), (int, string), (int, string, double) > but then NOT (string,double,int)? > 3.) If any overload is significantly dissimilar do not use this method? > > If that is true, then I think the text should discuss overloaded functions a > little > better since many (most) overloads will have such dissimilarities. In such > cases > then I assume one must still use thin wrappers? No, not really. You can still use the overloads mechanism without using thin wrappers for overloads with different signatures. You'll just need another BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS call for each set of overload signature. See boost/libs/python/defaults.cpp for examples. There you'll see a class X with: object foo(std::string a, bool b=false) const; object foo(list a, list b, bool c=false) const; And: BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) > I think the page should have a link to the additional information in the > reference manual. > > http://www.boost.org/libs/python/doc/v2/overloads.html#BOOST_PYTHON_FUNCTION > _OVERLOADS-spec Ok. > While the above reference page does show how to do overloads of the function > "f", but these > are quite different than dealing with say two different class Y member > functions named f that > have different argument types. This is what I am trying to do at the moment > and, after quite a bit > of time trying to figure how out to use > BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS I > have now decided that I must use thin wrappers? I hope not. The overloads facility is there precisely to help us in these situations... Again, see above. HTH, --Joel From ssmith at magnet.fsu.edu Wed Nov 13 19:54:20 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Wed, 13 Nov 2002 13:54:20 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: <005101c28b3d$b7ecca90$a8564eca@kim> Message-ID: Hi Joel, > No, not really. You can still use the overloads mechanism without > using thin wrappers for overloads with different signatures. You'll > just need another BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS > call for each set of overload signature. > > See boost/libs/python/defaults.cpp for examples. Just be be clear. In boost/libs/python/test/defaults.cpp there is 1.) struct X with member functions: object foo(int a, bool b=false) const object foo(std::string a, bool b=false) const object foo(list a, list b, bool c=false) const 2.) BP overloading BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_2_stubs, foo, 1, 2) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_foo_3_stubs, foo, 2, 3) 3.) BP function exports .def("foo", (object(X::*)(std::string, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(int, bool) const)0, X_foo_2_stubs()) .def("foo", (object(X::*)(list, list, bool) const)0, X_foo_3_stubs()) which helps out a lot in clarifying things. Use of .def here deviates quite a bit from that shown in the tutorial (anywhere), but I guess you can't show everything. What is the 0 following const) in the above three lines for? I cannot find this even in the reference manual. Scott From djowel at gmx.co.uk Wed Nov 13 20:11:01 2002 From: djowel at gmx.co.uk (Joel de Guzman) Date: Thu, 14 Nov 2002 03:11:01 +0800 Subject: [C++-sig] A couple of simple BP V2 questions References: Message-ID: <00b601c28b48$7f575050$a8564eca@kim> ----- Original Message ----- From: "Scott A. Smith" > 3.) BP function exports > > .def("foo", (object(X::*)(std::string, bool) const)0, > X_foo_2_stubs()) > .def("foo", (object(X::*)(int, bool) const)0, > X_foo_2_stubs()) > .def("foo", (object(X::*)(list, list, bool) const)0, > X_foo_3_stubs()) > > which helps out a lot in clarifying things. Use of .def here deviates quite > a > bit from that shown in the tutorial (anywhere), but I guess you can't show > everything. > What is the 0 following const) in the above three lines for? I cannot find > this even > in the reference manual. The 0? It's an easter egg :-) No..., seriously, it's casting a null (0) pointer. This is safe because the pointer is actually never used but is needed only to pass on the type information. Dave, is this idiom common? Maybe we can add a chapter on common boost python idioms in the tutorial. Many programmers (including me) rely on common, tried and true, idioms. Then again, we need to compile a list of these idioms. Thoughts? Regards, --Joel From dave at boost-consulting.com Wed Nov 13 20:53:34 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 14:53:34 -0500 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: <00b601c28b48$7f575050$a8564eca@kim> ("Joel de Guzman"'s message of "Thu, 14 Nov 2002 03:11:01 +0800") References: <00b601c28b48$7f575050$a8564eca@kim> Message-ID: "Joel de Guzman" writes: > ----- Original Message ----- > From: "Scott A. Smith" > > >> 3.) BP function exports >> >> .def("foo", (object(X::*)(std::string, bool) const)0, >> X_foo_2_stubs()) >> .def("foo", (object(X::*)(int, bool) const)0, >> X_foo_2_stubs()) >> .def("foo", (object(X::*)(list, list, bool) const)0, >> X_foo_3_stubs()) >> >> which helps out a lot in clarifying things. Use of .def here deviates quite >> a >> bit from that shown in the tutorial (anywhere), but I guess you can't show >> everything. >> What is the 0 following const) in the above three lines for? I cannot find >> this even >> in the reference manual. > > The 0? It's an easter egg :-) > > No..., seriously, it's casting a null (0) pointer. This is safe > because the pointer is actually never used but is needed > only to pass on the type information. > > Dave, is this idiom common? I doubt it. Most C++ programmers never touch (much less declare) a pointer-to-member. ;-) It's going to be common for Boost.Python programmers, though. > Maybe we can add a chapter on common boost python idioms in the > tutorial. Sounds like a good idea. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From djowel at gmx.co.uk Wed Nov 13 21:43:23 2002 From: djowel at gmx.co.uk (Joel de Guzman) Date: Thu, 14 Nov 2002 04:43:23 +0800 Subject: [C++-sig] A couple of simple BP V2 questions References: <00b601c28b48$7f575050$a8564eca@kim> Message-ID: <012701c28b55$6f1d56f0$a8564eca@kim> ----- Original Message ----- From: "David Abrahams" > > No..., seriously, it's casting a null (0) pointer. This is safe > > because the pointer is actually never used but is needed > > only to pass on the type information. > > > > Dave, is this idiom common? > > I doubt it. Most C++ programmers never touch (much less declare) a > pointer-to-member. ;-) > > It's going to be common for Boost.Python programmers, though. Yeah, that's what I mean: common idiom for boost python programmers. > > Maybe we can add a chapter on common boost python idioms in the > > tutorial. > > Sounds like a good idea. I'll check the samples and I'll compile as we go. Suggestions welcome. --Joel From dave at boost-consulting.com Wed Nov 13 21:34:13 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 15:34:13 -0500 Subject: [C++-sig] News page/Projects Message-ID: Hi Everyone, I'm starting a Boost.Python News page in the CVS which will be used as basically a library-wide changelog. It's intended to document only significant changes. Also, there seem to be quite a few new people out there using Boost.Python! I'd like to start a page which compiles a list of our users with links to their projects. If you haven't yet sent me your info, and you don't mind being listed on our webpage, please send/post: 1. The name of your project 2. A web link to your project or organization 3. What you're using Boost.Python for, specifically 4. Any other remarks, testimonials, whatever! Thanks, Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Wed Nov 13 23:31:58 2002 From: mike at bindkey.com (Mike Rovner) Date: Wed, 13 Nov 2002 14:31:58 -0800 Subject: [C++-sig] Re: wrapping complex attributes References: Message-ID: David, Thanks for your invaluable help. You fast answers greatly smooth BPL leaning curve. As you suggested many times before I first experimented with pure Python code first. So I have two working variants of what I want: 1) with implicit self class cTcn: # suppose it's some c++ member functions def getX(self,n): print 'getX(%s)'%n def delX(self,n): print 'delX(%s)'%n def newX(self,n): print 'newX(%s)'%n def getXall(self):print '[getXall()]' def getY(self,n): print 'getY(%s)'%n def delY(self,n): print 'delY(%s)'%n def newY(self,n): print 'newY(%s)'%n def getYall(self):print '[getYall()]' def getZ(self,n): print 'getZ(%s)'%n def delZ(self,n): print 'delZ(%s)'%n def newZ(self,n): print 'newZ(%s)'%n def getZall(self):print '[getZall()]' # now I want 3 more members def __init__(self): self.x=tcn_helper(self.getX, self.delX, self.newX, self.getXall) self.y=tcn_helper(self.getY, self.delY, self.newY, self.getYall) self.z=tcn_helper(self.getZ, self.delZ, self.newZ, self.getZall) class tcn_helper: def __init__(self,get,del_,new,all): self.__getitem__=get self.__delitem__=del_ self._newitem=new self.__iter__=all def new(self,n): return self._newitem(n) usage: t=cTcn() t.x['a'] >>> getX(a) 2) with explicit self class cTcn: def getX(self,n): print 'getX(%s)'%n def delX(self,n): print 'delX(%s)'%n def newX(self,n): print 'newX(%s)'%n def getXall(self):print '[getXall()]' def getY(self,n): print 'getY(%s)'%n def delY(self,n): print 'delY(%s)'%n def newY(self,n): print 'newY(%s)'%n def getYall(self):print '[getYall()]' def getZ(self,n): print 'getZ(%s)'%n def delZ(self,n): print 'delZ(%s)'%n def newZ(self,n): print 'newZ(%s)'%n def getZall(self):print '[getZall()]' class Tcn(cTcn): def __init__(self): self.x=tcn_helper(self,cTcn.getX, cTcn.delX, cTcn.newX, cTcn.getXall) self.y=tcn_helper(self,cTcn.getY, cTcn.delY, cTcn.newY, cTcn.getYall) self.z=tcn_helper(self,cTcn.getZ, cTcn.delZ, cTcn.newZ, cTcn.getZall) class tcn_helper2: def __init__(self,base,get,del_,new,all): self.base=base self.__getitem__=get self.__delitem__=del_ self._newitem=new self.__iter__=all def __getitem__(self,n): return self._getitem(self.base,n) def __delitem__(self,n): self._delitem(self.base,n) def __iter__(self): return self._iter(self.base) def new(self,n): return self._newitem(self.base,n) usage: t=cTcn() t.x['a'] >>> getX(a) Now I have some problems translating that code to C++. "David Abrahams" wrote in message news:uadkes7p4.fsf at boost-consulting.com... > "Mike Rovner" writes: > > > Here is another dark corner: > > > > I have a complex C++ object: > > > > class Heavy { > > void SetX(const char *name, const T1& val); > > T1 GetX(const char *name); > > void DelX(const char *name); > > Iter EnumX(); > > > > void SetY(const char *name, const T2& val); > > T2 GetY(const char *name); > > void DelY(const char *name); > > Iter EnumY(); > > > > void SetZ(const char *name, const T3& val); > > T3 GetZ(const char *name); > > void DelZ(const char *name); > > Iter EnumZ(); > > } > > > > It seems natural to expose class Heavy with 3 attributes: x,y and z which > > will behave like dictionaries. > > How to do that? > > Use the add_property member of class_<>: 'add_property' is not sufficient as it suggest only get/set. I want to use 'setattr' instead. class_("Tcn") .setattr("x", class_ .def("__getitem__", &Heavy::GetX, return_value_policy() ) // line 138 () ) .setattr("y", class_ .def("__getitem__", &Heavy::GetY, return_value_policy<...>() ) () ) .setattr("z", class_ .def("__getitem__", &Heavy::GetZ, return_value_policy<...>() ) () ) ; However I have a problem with passing 'self' and designing tcn_helper class. With 'empty' tcn_helper class I got gcc error: PyTcn.cpp:138: no matching function for call to ` boost::python::class_ ::def(const char[2], , boost::python::return_value_policy)' I even don't understand why &Heavy::GetX is unknown. Can you help me? Mike From dave at boost-consulting.com Wed Nov 13 23:33:02 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 17:33:02 -0500 Subject: [C++-sig] Re: wrapping complex attributes In-Reply-To: ("Mike Rovner"'s message of "Wed, 13 Nov 2002 14:31:58 -0800") References: Message-ID: "Mike Rovner" writes: > David, > > Thanks for your invaluable help. You fast answers greatly smooth BPL leaning > curve. > > As you suggested many times before I first experimented with pure Python > code first. > > So I have two working variants of what I want: > > 1) with implicit self > > class cTcn: > # suppose it's some c++ member functions > def getX(self,n): print 'getX(%s)'%n > def delX(self,n): print 'delX(%s)'%n > def newX(self,n): print 'newX(%s)'%n > def getXall(self):print '[getXall()]' > > def getY(self,n): print 'getY(%s)'%n > def delY(self,n): print 'delY(%s)'%n > def newY(self,n): print 'newY(%s)'%n > def getYall(self):print '[getYall()]' > > def getZ(self,n): print 'getZ(%s)'%n > def delZ(self,n): print 'delZ(%s)'%n > def newZ(self,n): print 'newZ(%s)'%n > def getZall(self):print '[getZall()]' > > # now I want 3 more members > def __init__(self): > self.x=tcn_helper(self.getX, self.delX, self.newX, self.getXall) > self.y=tcn_helper(self.getY, self.delY, self.newY, self.getYall) > self.z=tcn_helper(self.getZ, self.delZ, self.newZ, self.getZall) In order for the Pure Python code to help you with the C++ version, you need to use the same idioms. You'll need x,y, and z to be properties on the class instead of attributes on the instance. Make them into properties and try again. See http://www.python.org/doc/current/whatsnew/sect-rellinks.html#SECTION000340000000000000000 If you need a description of properties -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 13 23:43:08 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 17:43:08 -0500 Subject: [C++-sig] Re: wrapping complex attributes In-Reply-To: (David Abrahams's message of "Wed, 13 Nov 2002 17:33:02 -0500") References: Message-ID: David Abrahams writes: > See > > http://www.python.org/doc/current/whatsnew/sect-rellinks.html#SECTION000340000000000000000 > > If you need a description of properties Or, maybe better: http://www.python.org/2.2.2/descrintro.html#property -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dnuffer at sco.com Thu Nov 14 00:11:02 2002 From: dnuffer at sco.com (Dan Nuffer) Date: Wed, 13 Nov 2002 16:11:02 -0700 Subject: [C++-sig] Re: News page/Projects Message-ID: <3DD2DC06.2080105@sco.com> I'm using Boost.Python to wrap the client API of OpenWBEM (http://openwbem.sourceforge.net/) This will make it easier to do rapid prototyping, testing, and scripting when developing management solutions that use WBEM. --Dan Nuffer From dave at boost-consulting.com Thu Nov 14 02:29:01 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 20:29:01 -0500 Subject: [C++-sig] Boost.Python v2 - auto_ptr support added Message-ID: I just added full support for auto_ptr to Boost.Python. See libs/python/test/auto_ptr.[py/cpp] for details. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Thu Nov 14 02:49:30 2002 From: mike at bindkey.com (Mike Rovner) Date: Wed, 13 Nov 2002 17:49:30 -0800 Subject: [C++-sig] Re: Re: wrapping complex attributes References: Message-ID: "David Abrahams" wrote in message news:ud6p93xsx.fsf at boost-consulting.com... > > # now I want 3 more members > > def __init__(self): > > self.x=tcn_helper(self.getX, self.delX, self.newX, self.getXall) > > self.y=tcn_helper(self.getY, self.delY, self.newY, self.getYall) > > self.z=tcn_helper(self.getZ, self.delZ, self.newZ, self.getZall) > > In order for the Pure Python code to help you with the C++ version, > you need to use the same idioms. You'll need x,y, and z to be > properties on the class instead of attributes on the instance. Make > them into properties and try again. See I don't want them to be properties. I hope I'm not forced :) If I recall correctly 'setattr' add attributes to object dictionary. I want x,y,z to behave the way I want, not to be something. ;) Regards, Mike From ssmith at magnet.fsu.edu Thu Nov 14 03:11:12 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Wed, 13 Nov 2002 21:11:12 -0500 Subject: [C++-sig] Limit On No. Of Constructors? In-Reply-To: <00b601c28b48$7f575050$a8564eca@kim> Message-ID: Is there a limit on the number of constructors allowed for a single class? I have several defined for one of my classes: // The Class class_("SinglePar", init<>()) // Constructors .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) and during compilation (MSVC 6) this will produce the error C:\PROGRAM FILES\BOOST\BOOST_1_29_0\boost/type_traits/is_arithmetic.hpp(38) : fatal error C1204: compiler limit : internal structure overflow C:\PROGRAM FILES\BOOST\BOOST_1_29_0\boost/type_traits/is_scalar.hpp(30) : see reference to class template instantiation 'boost::is_arithmetic' being compiled ....... Microsoft has provided no documentation as to what C1204 means. But if I comment out one or two of the above constructors, then the build works with out problems. It does not seem to matter which of them I comment out, other than I need only comment out 1 if I choose the 2nd or 5th overload above, but I need to comment out two if stopping use of any of the others. If there are no intrinsic limits I'll keep looking and try to make a simple example of how this failure occurs. The actual errors produced always reference classes deeper in my module, perhaps this indicates it is not a problem with BP but with some other code, but it is quite odd that the build errors disappear when I declare fewer constructors (but not any one of them in particular). Scott From dave at boost-consulting.com Thu Nov 14 02:53:54 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 20:53:54 -0500 Subject: [C++-sig] Limit On No. Of Constructors? In-Reply-To: ("Scott A. Smith"'s message of "Wed, 13 Nov 2002 21:11:12 -0500") References: Message-ID: "Scott A. Smith" writes: > Is there a limit on the number of constructors allowed > for a single class? None in the library. It's your compiler which is hosing you. > I have several defined for one of my classes: > > // The Class > > class_("SinglePar", init<>()) > > // Constructors > > .def(init()) > .def(init std::string&>()) > .def(init std::string&>()) > .def(init std::string&>()) > .def(init std::string&>()) > .def(init()) > > and during compilation (MSVC 6) this will produce the error > C:\PROGRAM FILES\BOOST\BOOST_1_29_0\boost/type_traits/is_arithmetic.hpp(38) > : fatal error C1204: compiler limit : internal structure overflow > C:\PROGRAM > FILES\BOOST\BOOST_1_29_0\boost/type_traits/is_scalar.hpp(30) : see reference > to class template instantiation 'boost::is_arithmetic const >' being compiled ....... > > Microsoft has provided no documentation as to what C1204 means. But if I > comment out one or two of > the above constructors, then the build works with out problems. It does not > seem to matter which > of them I comment out, other than I need only comment out 1 if I choose the > 2nd or 5th overload > above, but I need to comment out two if stopping use of any of the others. > > If there are no intrinsic limits I'll keep looking and try to make a simple > example of how > this failure occurs. The actual errors produced always reference classes > deeper in my module, > perhaps this indicates it is not a problem with BP but with some other code, > but it is quite > odd that the build errors disappear when I declare fewer constructors (but > not any one of them > in particular). You need to either get a better compiler (even vc7 would be an improvement), or split your module code across translation units (source files). To do that, declare a function in another source file taking a class_& parameter, and move some of your .def() calls there. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Nov 14 02:54:52 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 13 Nov 2002 20:54:52 -0500 Subject: [C++-sig] Re: Re: wrapping complex attributes In-Reply-To: ("Mike Rovner"'s message of "Wed, 13 Nov 2002 17:49:30 -0800") References: Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:ud6p93xsx.fsf at boost-consulting.com... >> > # now I want 3 more members >> > def __init__(self): >> > self.x=tcn_helper(self.getX, self.delX, self.newX, self.getXall) >> > self.y=tcn_helper(self.getY, self.delY, self.newY, self.getYall) >> > self.z=tcn_helper(self.getZ, self.delZ, self.newZ, self.getZall) >> >> In order for the Pure Python code to help you with the C++ version, >> you need to use the same idioms. You'll need x,y, and z to be >> properties on the class instead of attributes on the instance. Make >> them into properties and try again. See > > I don't want them to be properties. I hope I'm not forced :) Oh, well. I tried to help. > If I recall correctly 'setattr' add attributes to object dictionary. > > I want x,y,z to behave the way I want, not to be something. ;) Good luck to you! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From hugo at adept.co.za Thu Nov 14 06:36:53 2002 From: hugo at adept.co.za (Hugo van der Merwe) Date: Thu, 14 Nov 2002 07:36:53 +0200 Subject: [C++-sig] A couple of simple BP V2 questions In-Reply-To: References: <015801c28aa6$ebc844d0$8c564eca@kim> <20021113100633.GA8172@vervet.localnet> Message-ID: <20021114053653.GA16542@vervet.localnet> On Wed, Nov 13, 2002 at 08:40:34AM -0500, David Abrahams wrote: > Hugo van der Merwe writes: > > > Another idea for the tutorial: > > > > I do not recall seeing an example in the new tutorial about returning > > tuples. It might be worthwhile adding an example for wrapping a > > function returning more than one value via references by writing a > > wrapper function that uses make_tuple. > > Good idea. Perhaps you could come up with some examples for us? OK, will do. (In exams at the moment, so am not sure when I'll do it. Probably soon, possibly the weekend after this one.) (Of course, it'll not be nearly as nifty as that last "Exception Translation" example, that one made my day! ;) Hugo van der Merwe From hugo at adept.co.za Thu Nov 14 06:39:40 2002 From: hugo at adept.co.za (Hugo van der Merwe) Date: Thu, 14 Nov 2002 07:39:40 +0200 Subject: [C++-sig] Static, again... In-Reply-To: References: <20021112100724.GA26115@vervet.localnet> <20021113065112.GA539@vervet.localnet> <20021113072548.GB539@vervet.localnet> Message-ID: <20021114053940.GB16542@vervet.localnet> On Wed, Nov 13, 2002 at 08:19:53AM -0500, David Abrahams wrote: > Hugo van der Merwe writes: > > Yes, but I'll leave it as an "exercise for the reader". Properties are > a Python 2.2 thing, not a Boost.Python feature. Try it in pure > Python. If you can get that to work, you can probably get it to work > in Boost.Python. Hint: you'll need a proxy class. > Ah, thanks! Curious: should the tutorial remain small, or can it grow indefinately large given enough contributions from other people? Hugo van der Merwe From dave at boost-consulting.com Thu Nov 14 12:19:07 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Nov 2002 06:19:07 -0500 Subject: [C++-sig] Static, again... In-Reply-To: <20021114053940.GB16542@vervet.localnet> (Hugo van der Merwe's message of "Thu, 14 Nov 2002 07:39:40 +0200") References: <20021112100724.GA26115@vervet.localnet> <20021113065112.GA539@vervet.localnet> <20021113072548.GB539@vervet.localnet> <20021114053940.GB16542@vervet.localnet> Message-ID: Hugo van der Merwe writes: > On Wed, Nov 13, 2002 at 08:19:53AM -0500, David Abrahams wrote: >> Hugo van der Merwe writes: >> >> Yes, but I'll leave it as an "exercise for the reader". Properties are >> a Python 2.2 thing, not a Boost.Python feature. Try it in pure >> Python. If you can get that to work, you can probably get it to work >> in Boost.Python. Hint: you'll need a proxy class. >> > > Ah, thanks! > > Curious: should the tutorial remain small, or can it grow indefinately > large given enough contributions from other people? We are definitely interested in contributions! The more tutorial material, the better... contributions/modifications to the reference documentation (e.g. the examples) are also appreciated. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From gaoyakun at sina.com Thu Nov 14 04:00:26 2002 From: gaoyakun at sina.com (gaoyakun) Date: Thu, 14 Nov 2002 11:00:26 +0800 Subject: [C++-sig] operator problem Message-ID: <20021114030026.22461.qmail@sina.com> I have exported my point3 class to python, with many overloaded operators. it works fine for me except the *= operator. it always tell me "can't multiply sequence with non int type". but if i use p1.__imul__(p2) instead of p1 *= p2, it successfully executed my code. what's wrong with me? this is some code of my point3 class class point3 { .. ... point3 & operator *= (const point3 &p) { v[0] *= p.v[0]; v[1] *= p.v[1]; v[2] *= p.v[2]; return *this; } point3 & operator *= (float t) { v[0] *= t; v[1] *= t; v[2] *= t; return *this; } .... }; in to_python.cpp: class_("point3") ... ... .def(self *= self) .def(self * self) .def(self *= other()) .def(self * other()) ... ... what's the problem? ______________________________________ =================================================================== ????????????15M???????? ?????????? (http://vip.sina.com/sol_mail/promotion/pro_men.html) ?????????????????????????????????????????? (http://classad.sina.com.cn/2shou/) ?????????????????????????????????????????????????? (http://sms.sina.com.cn/cgi-bin/sms/smspic.cgi) From ssmith at magnet.fsu.edu Thu Nov 14 16:48:09 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Thu, 14 Nov 2002 10:48:09 -0500 Subject: [C++-sig] Limit On No. Of Constructors? In-Reply-To: Message-ID: Hi Dave, > You need to either get a better compiler (even vc7 would be an > improvement), or split your module code across translation units > (source files). To do that, declare a function in another source file > taking a class_& parameter, and move some of your .def() > calls there. In another message you wrote: > Split up your file into multiple translation units (separate source > files). Your module initialization function can call a function > defined in another source file to expose additional functionality. Ouch. It'll be a while before I can upgrade to .NET, but I am trying to build my modules multiplatform so I run with GCC using CygWin & Linux (& one day perhaps even OSX). But for now, I am hoping you can clarify your statements on how to deal with the vc6 problem. 1.) When I declare a class: class_("MyClass", init<>()) ... class constructors and functions ; it would seem that all .def() calls for the class must reside before the semi-colon used for the class end. Hence, I don't see how I can move any of these into a separate file. I have no problems moving entire classes into individual files. I don't understand how I can use a class_& parameter in a different file then continue putting in .def() calls that are part of the class MyClass. Could you give me a brief example? 2.) Is it possible to blend modules. That is, make a Python module that has class A, one that has class B, then somehow blend the two into a single module. Then only the summed moduled is imported into Python rather than all of the individual ones? 3.) I keep all my BP functions in separate files, except those functions that needed to be part of a class (e.g. for weak wrapping using V1). I have always done this using header files, so the structure of my code is quite different from all of the tutorial examples. I am wondering if, for whatever reasons, I should be keeping my BP functions in (.cpp) files instead? Currenty I have a single header file that contains, among other things, BOOST_PYTHON_MODULE(MyModule) { # include # include . . } Is there a better, or more standardized, way of organizing my code while keeping what is related to BP largely away from what is my project's usual C++ code? Thanks, Scott From ssmith at magnet.fsu.edu Thu Nov 14 19:06:28 2002 From: ssmith at magnet.fsu.edu (Scott A. Smith) Date: Thu, 14 Nov 2002 13:06:28 -0500 Subject: [C++-sig] Function Overload Problems In-Reply-To: <005101c28b3d$b7ecca90$a8564eca@kim> Message-ID: Try as I might, I still cannot get function overloading to work. Here is an example that I hope someone can correct: struct X { std::string Xstr; X() {} void myname(const std::string& N) { Xstr = N; } std::string myname(double xx) const { xx += 3.0; return Xstr; } std::string myname() const { return Xstr; } }; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Xname, myname, 0, 1) BOOST_PYTHON_MODULE(MyModule) { class_("X") .def("name", ( void(X::*) (const std::string&) )0, Xname()) .def("name", (std::string(X::*) (double) const)0, Xname()) .def("name", (std::string(X::*) () const)0, Xname()) ; } The first two work fine, the last one does not. What is wrong with this? Is this the right way to use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS? Is there an alternative way of doing exposing these overladed functions? Thanks, Scott From gideon at computer.org Thu Nov 14 19:50:10 2002 From: gideon at computer.org (gideon may) Date: Thu, 14 Nov 2002 19:50:10 +0100 Subject: [C++-sig] Limit On No. Of Constructors? In-Reply-To: References: Message-ID: <12916833.1037303410@localhost> I am not Dave ;) but I've come across the same problem. --On Thursday, November 14, 2002 10:48 AM -0500 "Scott A. Smith" wrote: > Hi Dave, > > perhaps even OSX). But for now, I am hoping you can clarify your > statements on how to deal with the vc6 problem. > > 1.) When I declare a class: > > class_("MyClass", init<>()) > ... class constructors and functions > ; > > it would seem that all .def() calls for the class must reside before > the semi-colon used for the class end. Hence, I don't see how I can > move any > of these into a separate file. I have no problems moving entire > classes into individual files. I don't understand how I can use a > class_& > parameter in a different file then continue putting in .def() calls > that are part of the class MyClass. Could you give me a brief example? The def method of class_ returns a reference to the class object. This allows chaining of the method calls. To split the def calls over multiple functions you can do something like : void second_definition(class_ & my_class) { my_class .def("method2", &MyClass::method2) ; } void first_definition() { class_ my_class("MyClass") .def("method1", &MyClass::method1) ; } > 2.) Is it possible to blend modules. That is, make a Python module that > has class A, one that has class B, then somehow blend the two into a > single module. Then only the summed moduled is imported into Python > rather than all of the individual ones? > > 3.) I keep all my BP functions in separate files, except those functions > that > needed to be part of a class (e.g. for weak wrapping using V1). I have > always done this using header files, so the structure of my code is > quite > different from all of the tutorial examples. I am wondering if, for > whatever > reasons, I should be keeping my BP functions in (.cpp) files instead? > Currenty I have a single header file that contains, among other > things, > > BOOST_PYTHON_MODULE(MyModule) > { ># include ># include > . > . > } > > Is there a better, or more standardized, way of organizing my code > while keeping what is related to BP largely away from what is my > project's usual C++ code? Why not something like this : FileA_impl.cpp ==================================== #include void ClassA_impl() { class_ class_a("ClassA") . . . } FileB_impl.cpp ===================================== #include void ClassB_impl() { class_ class_b("ClassB") . . . } FileWrapper.cpp =============================== void ClassA_impl(); void ClassB_impl(); BOOST_PYTHON_MODULE(MyModule) { ClassA_impl(); ClassB_impl(); } -------------------------------------------- This way you have a nice separation between the class wrapper implementations. HTH gideon From dave at boost-consulting.com Thu Nov 14 19:41:04 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Nov 2002 13:41:04 -0500 Subject: [C++-sig] operator problem In-Reply-To: <20021114030026.22461.qmail@sina.com> (gaoyakun's message of "Thu, 14 Nov 2002 11:00:26 +0800") References: <20021114030026.22461.qmail@sina.com> Message-ID: gaoyakun writes: > I have exported my point3 class to python, with many overloaded > operators. it works fine for me except the *= operator. it always tell > me "can't multiply sequence with non int type". but if i use > p1.__imul__(p2) instead of p1 *= p2, it successfully executed my > code. what's wrong with me? Nothing. It's a Python 2.2.1 bug. Upgrade to Python 2.2.2 and it will go away. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Thu Nov 14 19:50:31 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Nov 2002 13:50:31 -0500 Subject: [C++-sig] Limit On No. Of Constructors? In-Reply-To: ("Scott A. Smith"'s message of "Thu, 14 Nov 2002 10:48:09 -0500") References: Message-ID: "Scott A. Smith" writes: > Hi Dave, > >> You need to either get a better compiler (even vc7 would be an >> improvement), or split your module code across translation units >> (source files). To do that, declare a function in another source file >> taking a class_& parameter, and move some of your .def() >> calls there. > > In another message you wrote: > >> Split up your file into multiple translation units (separate source >> files). Your module initialization function can call a function >> defined in another source file to expose additional functionality. > > Ouch. It'll be a while before I can upgrade to .NET, but I am trying to > build my modules multiplatform so I run with GCC using CygWin & Linux (& one > day > perhaps even OSX). We're looking for a workaround for this VC6 bug. Maybe Monday (but maybe never). > But for now, I am hoping you can clarify your statements > on how to deal with the vc6 problem. > > 1.) When I declare a class: > > class_("MyClass", init<>()) > ... class constructors and functions > ; > > it would seem that all .def() calls for the class must reside before > the semi-colon used for the class end. Hence, I don't see how I can move > any > of these into a separate file. See http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#c1204 > I have no problems moving entire classes > into individual files. I don't understand how I can use a > class_& > parameter in a different file then continue putting in .def() calls that > are part of the class MyClass. Could you give me a brief example? > > 2.) Is it possible to blend modules. That is, make a Python module that has > class A, one that has class B, then somehow blend the two into a single > module. Then only the summed moduled is imported into Python rather than > all of the individual ones? No, but you don't need two module definitions. > 3.) I keep all my BP functions in separate files, except those functions > that > needed to be part of a class (e.g. for weak wrapping using V1). I have > always done this using header files, so the structure of my code is > quite > different from all of the tutorial examples. I am wondering if, for > whatever > reasons, I should be keeping my BP functions in (.cpp) files instead? > Currenty I have a single header file that contains, among other things, > > BOOST_PYTHON_MODULE(MyModule) > { > # include > # include > . > . > } > > Is there a better, or more standardized, way of organizing my code while > keeping what is related to BP largely away from what is my project's > usual C++ code? Generally speaking, #including headers into the interior of Boost.Python module initialization functions won't work out well. Maybe you should try: // module file extern void wrap1(); extern void wrap2(); BOOST_PYTHON_MODULE(MyModule) { wrap1(); wrap2(); } // wrap1.cpp #include void wrap1 { ... // wrapping code for header1.h } // wrap2.cpp #include void wrap2() { ... // wrapping code for header2.h } But note: this is not a Boost.Python question, it's a C++ question. There's nothing special about file organization for Boost.Python projects that doesn't apply to run-of-the-mill C++ (except for freaky compiler limitations like c1204). If you have more questions about this, please consider asking them in a general C++ forum. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Thu Nov 14 22:04:47 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 14 Nov 2002 13:04:47 -0800 (PST) Subject: [C++-sig] Function Overload Problems In-Reply-To: Message-ID: <20021114210447.41791.qmail@web20208.mail.yahoo.com> --- "Scott A. Smith" wrote: > Try as I might, I still cannot get function overloading to work. > Here is an example that I hope someone can correct: > > struct X { > std::string Xstr; > > X() {} > > void myname(const std::string& N) > { Xstr = N; } > > std::string myname(double xx) const > { xx += 3.0; return Xstr; } > > std::string myname() const > { return Xstr; } > > }; > > BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Xname, myname, 0, 1) > > BOOST_PYTHON_MODULE(MyModule) > { > class_("X") > .def("name", ( void(X::*) (const std::string&) )0, > Xname()) > .def("name", (std::string(X::*) (double) const)0, > Xname()) > .def("name", (std::string(X::*) () const)0, > Xname()) > ; > } > > The first two work fine, At face value, but you are .def'ing the overload with 0 arguments twice. > the last one does not. Because you promise to the macro that it will be used with a function taking up to 1 arguments, but you are giving it one which takes no arguments. What you want is most likely similar to: class_("X") // one overload directly .def("name", ( void(X::*) (const std::string&) ) &x::myname) // two overloads by way of using the macro .def("name", (std::string(X::*) (double) const)0, Xname()) ; Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From dave at boost-consulting.com Thu Nov 14 18:30:15 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Nov 2002 12:30:15 -0500 Subject: [C++-sig] contained structure access In-Reply-To: (David Abrahams's message of "05 Nov 2002 16:37:18 -0500") References: <1036526295.30267.23.camel@ida.astro.washington.edu> Message-ID: David Abrahams writes: > Graeme Lufkin writes: > >> I've found some strange (I think) behavior in Boost.Python, and I've >> boiled it down to the example below. > >> I can create variables of type Atom, and get/set it's 'x' member >> variable fine. I can also create variables of type Holder, and get/set >> its 'a' member variable (of type Atom). However, when I try to modify >> the 'x' of the Holder's Atom, it is ignored. I can recreate this >> situation using regular 100% Python classes, and it works as expected. >> So, what am I doing wrong? > > you'll see that make_getter with one argument uses the default call > policies, which copy of all return values. What's happening is that > the x member is getting set in the copy. > > Instead, you could use > > this->add_property( > name > , make_getter(&Holder::a, return_internal_reference<>()) > , make_setter(&Holder::a)); > > Which should get you the behavior you want. I'll look into fixing it > so this is no longer needed, if I can find a few minutes to spend on > it. Done. See http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/data_members.html#make_getter-spec -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dirk at gerrits.homeip.net Thu Nov 14 22:39:05 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 14 Nov 2002 22:39:05 +0100 Subject: [C++-sig] Creating an instance of a Python class in C++: PyRun_String? Message-ID: Hi. I have an abstract base class and one concrete derivative in C++ and I have wrapped the base class with Boost.Python. Now I want to define another derived class, but I want to do this in Python. With the Boost.Python wrapper, this is easy. But now comes the hard part: I want to create an instance of this Python class and use it in C++. The first thing I did was searching the latest posts on this mailing list which gave me 2 clues: - the example at the bottom of: http://www.boost.org/libs/python/doc/v2/extract.html - PyRun_String Here's what I came up with: #include // The abstract base class class Base { public: virtual ~Base() {}; virtual void f() = 0; }; // The C++ derived class class CppDerived : public Base { public: virtual ~CppDerived() {} void f() { std::cout << "CppDerived::f()\n"; } }; //-------------------------------------------------------// #include #include namespace python = boost::python; namespace { // Boost.Python wrapper for Base struct BaseWrap : public Base { BaseWrap(PyObject* self_) : self(self_) {} void f() { return python::call_method(self, "f"); } PyObject* self; }; } BOOST_PYTHON_MODULE(pythontest) { python::class_("Base", python::no_init) ; } //-------------------------------------------------------// int main() { // Register the wrapper module PyImport_AppendInittab("pythontest", initpythontest); // Initialize the interpreter Py_Initialize(); // Create and use an instance of the C++ derived class boost::shared_ptr cpp(new CppDerived); cpp->f(); // Define the Python derived class PyRun_SimpleString( "from pythontest import *\n" "class PythonDerived(Base):\n" " def __init__(self):\n" " pass\n" " def f(self):\n" " print \"PythonDerived::f()\"\n" ); // Create and use an instance of the Python derived class Base& py = python::extract( PyRun_String("PythonDerived()\n", ???, ???, ???); py.f(); std::cout << "\nPress to quit..."; std::cin.get(); // Release the Python interpreter Py_Finalize(); } I feel like I'm almost there, but I just can't get this to work. Firstly, I don't know which arguments to feed into PyRun_String. The python.org docs didn't really help me that much: I don't have any dictionaries of globals and locals, and what exactly is a start token? I tried 0s for all 3 arguments and then compiling, but that brought me to the second issue: The 'Base& py = ...' line gave a compilation error saying that a python::extract could not be converted to a Base&. Then I tried replacing both Base& with Base*, which compiled but gave an access violation. Can anyone help me out? Thanks in advance, Dirk Gerrits From mike at bindkey.com Thu Nov 14 23:10:12 2002 From: mike at bindkey.com (Mike Rovner) Date: Thu, 14 Nov 2002 14:10:12 -0800 Subject: [C++-sig] Re: Re: Re: wrapping complex attributes References: Message-ID: "David Abrahams" wrote in message news:uadkc29w3.fsf at boost-consulting.com... > "Mike Rovner" writes: > > I don't want them to be properties. I hope I'm not forced :) > > Oh, well. I tried to help. > > > If I recall correctly 'setattr' add attributes to object dictionary. > > I want x,y,z to behave the way I want, not to be something. ;) > > Good luck to you! I'm sorry that my post looks rude. I apologies. No offense meant. Mike From dirk at gerrits.homeip.net Thu Nov 14 23:00:39 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Thu, 14 Nov 2002 23:00:39 +0100 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: References: Message-ID: Dirk Gerrits wrote: > Firstly, I don't know which arguments to feed into PyRun_String. The > python.org docs didn't really help me that much: I don't have any > dictionaries of globals and locals, and what exactly is a start token? Upon further RTFMing on start tokens, I tried this: // Create and use an instance of the Python derived class Base* py = python::extract( PyRun_String("PythonDerived()\n", Py_eval_input, 0, 0)); py->f(); This gives an access violation in find_instance_impl which is called by extract_pointer::extract_pointer(PyObject* obj) as far as I can tell. And the Base& version wouldn't compile as I said. What (else) am I doing wrong? Dirk PS I forgot to mention that I'm using Intel C++ Compiler 6.0 on Windows 2000 SP2 with Boost 1.29.0. From BPettersen at NAREX.com Fri Nov 15 00:23:17 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Thu, 14 Nov 2002 16:23:17 -0700 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? Message-ID: <60FB8BB7F0EFC7409B75EEEC13E201920177489E@admin56.narex.com> > From: Dirk Gerrits [mailto:dirk at gerrits.homeip.net] [...] > Upon further RTFMing on start tokens, I tried this: > > // Create and use an instance of the Python derived class > Base* py = python::extract( > PyRun_String("PythonDerived()\n", Py_eval_input, 0, 0)); > py->f(); I don't know what's happening whith your extract, but you need to define your previous statements in a module/namespace and feed this to PyRun_String, e.g.: PyObject* mainmod = PyImport_AddModule("__main__"); ns = PyModule_GetDict(mainmod); Py_INCREF(ns); // add your definitions to the namespace PyObject* x = PyRun_String("..your classdef here..", Py_file_input, ns, ns); Py_XDECREF(x); // it doesn't contain anything useful PyObject* res = PyRun_String("PythonDerived()\n", Py_eval_input, ns, ns); hth, -- bjorn From dave at boost-consulting.com Fri Nov 15 01:07:01 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Nov 2002 19:07:01 -0500 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: (Dirk Gerrits's message of "Thu, 14 Nov 2002 23:00:39 +0100") References: Message-ID: Dirk Gerrits writes: > Dirk Gerrits wrote: > >> Firstly, I don't know which arguments to feed into PyRun_String. The >> python.org docs didn't really help me that much: I don't have any >> dictionaries of globals and locals, and what exactly is a start >> token? > > Upon further RTFMing on start tokens, I tried this: > > // Create and use an instance of the Python derived class > Base* py = python::extract( > PyRun_String("PythonDerived()\n", Py_eval_input, 0, 0)); > py->f(); > > This gives an access violation in find_instance_impl which is called > by extract_pointer::extract_pointer(PyObject* obj) as far as I > can tell. And the Base& version wouldn't compile as I said. > > What (else) am I doing wrong? Does http://www.boost.org/libs/python/doc/v2/extract.html#examples help? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dlp at fractaltechnologies.com Fri Nov 15 01:55:51 2002 From: dlp at fractaltechnologies.com (Daniel Paull) Date: Fri, 15 Nov 2002 08:55:51 +0800 Subject: [C++-sig] Limit On No. Of Constructors? In-Reply-To: Message-ID: <001c01c28c41$bee53350$0a01a8c0@fractalgraphics.com.au> I've used the approach below to get around the VC6 limitations. It worked without any problems, so I'd recommend doing it that way. Cheers, Daniel Paull -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of David Abrahams Sent: Friday, 15 November 2002 2:51 AM To: c++-sig at python.org Subject: Re: [C++-sig] Limit On No. Of Constructors? ... Generally speaking, #including headers into the interior of Boost.Python module initialization functions won't work out well. Maybe you should try: // module file extern void wrap1(); extern void wrap2(); BOOST_PYTHON_MODULE(MyModule) { wrap1(); wrap2(); } // wrap1.cpp #include void wrap1 { ... // wrapping code for header1.h } // wrap2.cpp #include void wrap2() { ... // wrapping code for header2.h } From dave at boost-consulting.com Fri Nov 15 01:58:22 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 14 Nov 2002 19:58:22 -0500 Subject: [C++-sig] Re: Re: Re: wrapping complex attributes In-Reply-To: ("Mike Rovner"'s message of "Thu, 14 Nov 2002 14:10:12 -0800") References: Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:uadkc29w3.fsf at boost-consulting.com... >> "Mike Rovner" writes: >> > I don't want them to be properties. I hope I'm not forced :) >> >> Oh, well. I tried to help. >> >> > If I recall correctly 'setattr' add attributes to object dictionary. >> > I want x,y,z to behave the way I want, not to be something. ;) >> >> Good luck to you! > > I'm sorry that my post looks rude. I apologies. No offense meant. Why don't you read this thread: http://aspn.activestate.com/ASPN/Mail/Message/C++-sig/1430241 And see if you're trying to solve the same problem as Hugo van der Merwe. If your problem is different, I probably have not understood you well enough. If it's the same, maybe the two of you can work together to come up with a solution. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Fri Nov 15 02:43:32 2002 From: mike at bindkey.com (Mike Rovner) Date: Thu, 14 Nov 2002 17:43:32 -0800 Subject: [C++-sig] Re: Static, again... References: <20021112100724.GA26115@vervet.localnet> <20021113065112.GA539@vervet.localnet> <20021113072548.GB539@vervet.localnet> <20021114053940.GB16542@vervet.localnet> Message-ID: "Hugo van der Merwe" wrote in message news:20021114053940.GB16542 at vervet.localnet... > On Wed, Nov 13, 2002 at 08:19:53AM -0500, David Abrahams wrote: > > Hugo van der Merwe writes: > > > > Yes, but I'll leave it as an "exercise for the reader". Properties are > > a Python 2.2 thing, not a Boost.Python feature. Try it in pure > > Python. If you can get that to work, you can probably get it to work > > in Boost.Python. Hint: you'll need a proxy class. If I understand correctly Pythons x.a[3]=1 will go through __setitem__(__getattr__(x,"a"), 3, 1) If so, it shall be easy (untested): struct proxy { GetItem(); SetItem(): }; struct X { proxy a; } class_("proxy") .def("__getitem__", &proxy::GetItem) .def("__setitem__", &proxy::SetItem) ; class_("X") .add_property("a", &X::a) ; Right? From dirk at gerrits.homeip.net Fri Nov 15 08:53:58 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Fri, 15 Nov 2002 08:53:58 +0100 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: References: Message-ID: David Abrahams wrote: > Dirk Gerrits writes: > > > >Dirk Gerrits wrote: > > > > > >>Firstly, I don't know which arguments to feed into PyRun_String. The > >>python.org docs didn't really help me that much: I don't have any > >>dictionaries of globals and locals, and what exactly is a start > >>token? > > > >Upon further RTFMing on start tokens, I tried this: > > > >// Create and use an instance of the Python derived class > >Base* py = python::extract( > > PyRun_String("PythonDerived()\n", Py_eval_input, 0, 0)); > >py->f(); > > > >This gives an access violation in find_instance_impl which is called > >by extract_pointer::extract_pointer(PyObject* obj) as far as I > >can tell. And the Base& version wouldn't compile as I said. > > > >What (else) am I doing wrong? > > > Does > > http://www.boost.org/libs/python/doc/v2/extract.html#examples > > help? I looked at that one, as I said in my initial post. However the example creates a new python::object instance of a wrapped C++ class. Not of a Python class. Is there some way to create a class_ object from a Python class that I'm not aware of? I don't really see how the example would compile BTW, because value is declared a non-const member function and it is called through the const reference x. Dirk From dirk at gerrits.homeip.net Fri Nov 15 09:05:29 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Fri, 15 Nov 2002 09:05:29 +0100 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E201920177489E@admin56.narex.com> References: <60FB8BB7F0EFC7409B75EEEC13E201920177489E@admin56.narex.com> Message-ID: Bjorn Pettersen wrote: > I don't know what's happening whith your extract, but you need to define > your previous statements in a module/namespace and feed this to > PyRun_String, e.g.: > > PyObject* mainmod = PyImport_AddModule("__main__"); > ns = PyModule_GetDict(mainmod); > Py_INCREF(ns); > // add your definitions to the namespace > PyObject* x = PyRun_String("..your classdef here..", > Py_file_input, ns, ns); > Py_XDECREF(x); // it doesn't contain anything useful > PyObject* res = PyRun_String("PythonDerived()\n", Py_eval_input, ns, > ns); Thanks, this makes sense. However, the extract still won't work. The line: Base* py = python::extract(res); seems to trigger a "Microsoft C++ exception: boost::python::error_already_set" from: (throw_no_pointer_from_python) in extract_pointer::operator()() const. Dirk From dave at boost-consulting.com Fri Nov 15 13:09:03 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 07:09:03 -0500 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: (Dirk Gerrits's message of "Fri, 15 Nov 2002 08:53:58 +0100") References: Message-ID: Dirk Gerrits writes: > David Abrahams wrote: > >> Dirk Gerrits writes: >> >> >> >Dirk Gerrits wrote: >> > >> > >> >>Firstly, I don't know which arguments to feed into PyRun_String. The >> >>python.org docs didn't really help me that much: I don't have any >> >>dictionaries of globals and locals, and what exactly is a start >> >>token? >> > >> >Upon further RTFMing on start tokens, I tried this: >> > >> >// Create and use an instance of the Python derived class >> >Base* py = python::extract( >> > PyRun_String("PythonDerived()\n", Py_eval_input, 0, 0)); >> >py->f(); >> > >> >This gives an access violation in find_instance_impl which is called >> >by extract_pointer::extract_pointer(PyObject* obj) as far as I >> >can tell. And the Base& version wouldn't compile as I said. >> > >> >What (else) am I doing wrong? >> >> >> Does >> >> http://www.boost.org/libs/python/doc/v2/extract.html#examples >> >> help? > > I looked at that one, as I said in my initial post. However the > example creates a new python::object instance of a wrapped C++ > class. Not of a Python class. Is there some way to create a class_ > object from a Python class that I'm not aware of? > > I don't really see how the example would compile BTW, because value is > declared a non-const member function and it is called through the > const reference x. Oops! Good point, fixed. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 15 13:21:27 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 07:21:27 -0500 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: (Dirk Gerrits's message of "Fri, 15 Nov 2002 08:53:58 +0100") References: Message-ID: Dirk Gerrits writes: > David Abrahams wrote: > >> Dirk Gerrits writes: >> >> >> >Dirk Gerrits wrote: >> > >> > >> >>Firstly, I don't know which arguments to feed into PyRun_String. The >> >>python.org docs didn't really help me that much: I don't have any >> >>dictionaries of globals and locals, and what exactly is a start >> >>token? >> > >> >Upon further RTFMing on start tokens, I tried this: >> > >> >// Create and use an instance of the Python derived class >> >Base* py = python::extract( >> > PyRun_String("PythonDerived()\n", Py_eval_input, 0, 0)); >> >py->f(); >> > >> >This gives an access violation in find_instance_impl which is called >> >by extract_pointer::extract_pointer(PyObject* obj) as far as I >> >can tell. And the Base& version wouldn't compile as I said. >> > >> >What (else) am I doing wrong? >> >> >> Does >> >> http://www.boost.org/libs/python/doc/v2/extract.html#examples >> >> help? > > I looked at that one, as I said in my initial post. However the > example creates a new python::object instance of a wrapped C++ > class. Not of a Python class. Is there some way to create a class_ > object from a Python class that I'm not aware of? No. However, if you can arrange to pass the class object from Python to C++ in an object instance, you can avoid all of the problems you're having with PyRun_String. Also, if your compiler is having trouble with: object inst = klass(); Base& py = python::extract(inst); you can always use: Base& py = python::extract(inst)(); ^^ to help it. You must be using MSVC, eh? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 15 13:28:29 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 07:28:29 -0500 Subject: [C++-sig] Re: Static, again... In-Reply-To: ("Mike Rovner"'s message of "Thu, 14 Nov 2002 17:43:32 -0800") References: <20021112100724.GA26115@vervet.localnet> <20021113065112.GA539@vervet.localnet> <20021113072548.GB539@vervet.localnet> <20021114053940.GB16542@vervet.localnet> Message-ID: "Mike Rovner" writes: > "Hugo van der Merwe" wrote in message > news:20021114053940.GB16542 at vervet.localnet... >> On Wed, Nov 13, 2002 at 08:19:53AM -0500, David Abrahams wrote: >> > Hugo van der Merwe writes: >> > >> > Yes, but I'll leave it as an "exercise for the reader". Properties are >> > a Python 2.2 thing, not a Boost.Python feature. Try it in pure >> > Python. If you can get that to work, you can probably get it to work >> > in Boost.Python. Hint: you'll need a proxy class. > > If I understand correctly > Pythons > x.a[3]=1 > will go through > __setitem__(__getattr__(x,"a"), 3, 1) > > If so, it shall be easy (untested): > > struct proxy { > GetItem(); > SetItem(): > }; > struct X { > proxy a; > } > > class_("proxy") > .def("__getitem__", &proxy::GetItem) > .def("__setitem__", &proxy::SetItem) > ; > > class_("X") > .add_property("a", &X::a) > ; > > Right? No, object(&X::a) doesn't do anything useful (see the add_property docs for why this is relevant). .def_readonly("a",&X::a) would work, but I didn't think that was what you wanted. Did you really want to modify your C++ X instance by adding a data member, just to get the Python to work? I had in mind: proxy getter(X&) { return proxy(); } ... class_("X") .add_property("a", getter) ; -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 15 14:28:03 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 08:28:03 -0500 Subject: [C++-sig] Support, Thanks! Message-ID: I just want to publicly thank all of you who have been posting answers to support questions on this list. This makes a huge difference to me. I didn't expect interest in the library to go up so sharply after its release, and have been quite overwhelmed with the number of support requests. In order to actually get some work done, and because many of you seem to be able to help one-another, I'm going to scale back the time I spend answering questions here on a non-contract basis. In practice, that means it may be a few days before I get around to answering any unanswered questions, and I'll be relying more on the community to fill in the gaps. Thanks for using Boost.Python, Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dirk at gerrits.homeip.net Fri Nov 15 15:38:14 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Fri, 15 Nov 2002 15:38:14 +0100 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: References: Message-ID: David Abrahams wrote: > >>Does > >> > >> http://www.boost.org/libs/python/doc/v2/extract.html#examples > >> > >>help? > > > >I looked at that one, as I said in my initial post. However the > >example creates a new python::object instance of a wrapped C++ > >class. Not of a Python class. Is there some way to create a class_ > >object from a Python class that I'm not aware of? > > > No. However, if you can arrange to pass the class object from Python > to C++ in an object instance, you can avoid all of the problems you're > having with PyRun_String. This sounds very interesting! I don't know how to do it though. I'm very, very new to the Python/C API, if you hadn't guessed so already. ;) Can you give me some pointers on this one? > Also, if your compiler is having trouble > with: > > object inst = klass(); > Base& py = python::extract(inst); > > you can always use: > > Base& py = python::extract(inst)(); > ^^ > to help it. You must be using MSVC, eh? That compiles, thanks! I'm using Intel 6.0 though, not MSVC. However, I'm still getting the run-time error for the extraction. I think I now know what is causing it though. I'm now doing this: python::extract extractor(res); if (!extractor.check()) std::cout << "Check returns false and "; try { Base& py = extractor(); py.f(); } catch(python::error_already_set const&) { std::cout << "the extraction throws an exception: " << std::flush; PyErr_Print(); } OUTPUT: Check returns false and the extraction throws an exception: TypeError: No registered converter was able to extract a C++ reference to type class Base from this Python object of type PythonDerived This reminded me of something I read in a post by Nicolas Lelong. He calls python::converter::initialize_builtin_converters() just after Py_Initialize(). So I tried that, but the linker complained: unresolved external symbol "void __cdecl boost::python::converter::initialize_builtin_converters(void)" Any idea why that might be? Dirk From patrick at vrac.iastate.edu Fri Nov 15 18:14:55 2002 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 15 Nov 2002 11:14:55 -0600 Subject: [C++-sig] Polymorphism between Python and C++ Message-ID: <3DD52B8F.7070906@vrac.iastate.edu> I'm doing some experimenting with Boost.Python v2, and I have run into a problem I just can't seem to solve. I want to define an abstract base class in C++, derive a Python class from that base, and then use the derived Python class polymorphically where the abstract C++ class can be used. I have attached the simplest code I could come up with that demonstrates the problem. When I run test.py, I get the following output: I'm Derived1! Traceback (most recent call last): File "./test.py", line 18, in ? handler.setObj(derived2) TypeError: bad argument type for built-in operation I have been over the documentation (both on boost.org and on the PythonInfo Wiki), but I can't figure out what I am doing wrong. It seems like I am close, but there must be some detail I'm missing. -Patrick -- Patrick L. Hartling | Research Assistant, VRAC patrick at vrac.iastate.edu | 2624 Howe Hall: 1.515.294.4916 http://www.137.org/patrick/ | http://www.vrac.iastate.edu/ -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Simple.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.py URL: From dave at boost-consulting.com Fri Nov 15 18:16:21 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 12:16:21 -0500 Subject: [C++-sig] Projects Page Message-ID: The Projects page is now started. You can view its current state at: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/projects.html Additional entries would be much appreciated! Thanks, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 15 18:29:46 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 12:29:46 -0500 Subject: [C++-sig] MacOSX building... of shared libraries... Message-ID: This update from Matt Austern, who works on Apple's C++ tools team... -------------- next part -------------- An embedded message was scrubbed... From: Matt Austern Subject: Re: ["Ralf W. Grosse-Kunstleve" ] Re: [C++-sig] MacOSX building... of shared libraries... Date: Fri, 15 Nov 2002 09:20:33 -0800 Size: 2039 URL: -------------- next part -------------- -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 15 18:52:18 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 12:52:18 -0500 Subject: [C++-sig] Polymorphism between Python and C++ In-Reply-To: <3DD52B8F.7070906@vrac.iastate.edu> (Patrick Hartling's message of "Fri, 15 Nov 2002 11:14:55 -0600") References: <3DD52B8F.7070906@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > I'm doing some experimenting with Boost.Python v2, and I have run into > a problem I just can't seem to solve. I want to define an abstract > base class in C++, derive a Python class from that base, and then use > the derived Python class polymorphically where the abstract C++ class > can be used. I have attached the simplest code I could come up with > that demonstrates the problem. When I run test.py, I get the > following output: > > I'm Derived1! > Traceback (most recent call last): > File "./test.py", line 18, in ? > handler.setObj(derived2) > TypeError: bad argument type for built-in operation > > I have been over the documentation (both on boost.org and on the > PythonInfo Wiki) Wow, I forgot about that Wiki. Is it worth linking http://www.python.org/cgi-bin/moinmoin/boost_2epython into the Boost web pages? Most of the info appears to be outdated... > but I can't figure out what I am doing wrong. It > seems like I am close, but there must be some detail I'm missing. Yep. The detail is that Derived2.__init__() needs to call Base.__init__(). Otherwise there will be no C++ Base object in the Python object, and the conversion to Base* will fail. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Fri Nov 15 21:31:40 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Fri, 15 Nov 2002 12:31:40 -0800 Subject: [C++-sig] Newbie type conversion question Message-ID: I am wrapping part of DirectX and have run into an number of variations of the problem described below. In struct IntHwnd; HWND is a pointer. What I pass to the wrapper from python is an int representation of the pointer so I need to cast the int from python to a pointer in C++. I need to do the reverse when getting the attribute. How do I accomplish this? struct IntHwnd { HWND w; }; Thanks in advance, Mark From BPettersen at NAREX.com Fri Nov 15 21:42:15 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Fri, 15 Nov 2002 13:42:15 -0700 Subject: [C++-sig] Newbie type conversion question Message-ID: <60FB8BB7F0EFC7409B75EEEC13E20192017748F8@admin56.narex.com> > From: Mark Russell [mailto:mrussell8081 at pacbell.net] > > I am wrapping part of DirectX and have run into an number of > variations of the problem described below. > > In struct IntHwnd; HWND is a pointer. What I pass to the > wrapper from python is an int representation of the pointer > so I need to cast the int from python to a pointer in C++. I > need to do the reverse when getting the attribute. How do I > accomplish this? I'm not sure if this works, but it's worth a try: struct HWND_PyInt { static PyObject* convert(const HWND& h) { return PyInt_FromLong((long) h); } }; BOOST_PYTHON_MODULE(nrx) { to_python_converter(); .... } I'm sort of curious why you need to access the HWND as an int though... -- bjorn From patrick at vrac.iastate.edu Fri Nov 15 22:11:21 2002 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 15 Nov 2002 15:11:21 -0600 Subject: [C++-sig] Polymorphism between Python and C++ References: <3DD52B8F.7070906@vrac.iastate.edu> Message-ID: <3DD562F9.5030505@vrac.iastate.edu> David Abrahams wrote: > Patrick Hartling writes: > > >>I'm doing some experimenting with Boost.Python v2, and I have run into >>a problem I just can't seem to solve. I want to define an abstract >>base class in C++, derive a Python class from that base, and then use >>the derived Python class polymorphically where the abstract C++ class >>can be used. I have attached the simplest code I could come up with >>that demonstrates the problem. When I run test.py, I get the >>following output: >> >>I'm Derived1! >>Traceback (most recent call last): >> File "./test.py", line 18, in ? >> handler.setObj(derived2) >>TypeError: bad argument type for built-in operation >> >>I have been over the documentation (both on boost.org and on the >>PythonInfo Wiki) > > > Wow, I forgot about that Wiki. Is it worth linking > http://www.python.org/cgi-bin/moinmoin/boost_2epython into the Boost > web pages? Most of the info appears to be outdated... I found it somewhat helpful. There are a lot of pages that still need to be written, and I was careful to look at examples that were up to date with the V2 syntax. >> but I can't figure out what I am doing wrong. It >>seems like I am close, but there must be some detail I'm missing. > > > Yep. The detail is that Derived2.__init__() needs to call > Base.__init__(). Otherwise there will be no C++ Base object in the > Python object, and the conversion to Base* will fail. Does that mean that I need to have a constructor in my Base class? Since it is abstract, I didn't expect to have it get instantiated. OTOH, I'm relatively new to Python, so maybe I am just misunderstading what I need to change. If I just add Simple.Base.__init__() without modifying the C++, I get an error saying that Simple.Base cannot be instantiated from Python. -Patrick -- Patrick L. Hartling | Research Assistant, VRAC patrick at vrac.iastate.edu | 2624 Howe Hall: 1.515.294.4916 http://www.137.org/patrick/ | http://www.vrac.iastate.edu/ From mrussell8081 at pacbell.net Fri Nov 15 22:58:26 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Fri, 15 Nov 2002 13:58:26 -0800 Subject: [C++-sig] re: Newbie type conversion question Message-ID: Bjorn, Thanks for your response, this works great going from c++ to python so now I'm trying to workout how to get from python to c++. I am wrapping parts of DirectX8 for a game prototype and am using Mark Hammonds win32ui module which wraps mfc to create the winapp. To create a device in DirectX I need to pass the HWND of my game window. Win32ui represents this as an int in python. To create a device I need to wrap a presentation parameters struct and the target window attribute is an HWND. So I need to go from python (int)-->presentation param (HWND) and back. Actually in this case I just need to get a converted value to the presentation param struct but this case comes up frequently in other areas. Thanks to your help I have a good idea how to go from c++ to python. I am looking at implicitly_convertible to go from python to c++. Is this the right approach?? Thanks again, Mark > From: Mark Russell [mailto:mrussell8081 at pacbell.net]=20 >=20 > I am wrapping part of DirectX and have run into an number of=20 > variations of the problem described below. >=20 > In struct IntHwnd; HWND is a pointer. What I pass to the=20 > wrapper from python is an int representation of the pointer=20 > so I need to cast the int from python to a pointer in C++. I=20 > need to do the reverse when getting the attribute. How do I=20 > accomplish this? I'm not sure if this works, but it's worth a try: struct HWND_PyInt { static PyObject* convert(const HWND& h) { return PyInt_FromLong((long) h); } }; BOOST_PYTHON_MODULE(nrx) { to_python_converter(); .... } I'm sort of curious why you need to access the HWND as an int though... -- bjorn From dave at boost-consulting.com Fri Nov 15 23:04:52 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 17:04:52 -0500 Subject: [C++-sig] Newbie type conversion question In-Reply-To: (Mark Russell's message of "Fri, 15 Nov 2002 12:31:40 -0800") References: Message-ID: Mark Russell writes: > I am wrapping part of DirectX and have run into an number of variations of > the problem described below. > > In struct IntHwnd; HWND is a pointer. What I pass to the wrapper from > python is an int representation of the pointer so I need to cast the int > from python to a pointer in C++. I need to do the reverse when getting the > attribute. How do I accomplish this? > > struct IntHwnd > { > HWND w; > }; > This seems like a similar problem: http://aspn.activestate.com/ASPN/Mail/Message/1411366 Does that help at all? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Fri Nov 15 23:51:55 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Fri, 15 Nov 2002 14:51:55 -0800 Subject: [C++-sig] Newbie type conversion question Message-ID: Dave, Yes this helps I just want to check my understanding of converters and what I think I need to do for this case. From the thread you sent me: -snip-- You need to register an lvalue converter for FILE. Something like: struct pyfile_to_FILE { static File& execute(PyObject& o) { return *PyFile_AsFile(&o); } } // In your module init function lvalue_from_pytype(); --snip-- So I need to write a converter that makes the cast from int to HWND based on the model above. Now I don't want every int converted so I think I need to write an HWND object wrapper in python with the int I want converted as an attribute then my converter will convert these as desired. Is this correct? Thanks for the quick replies boost python is a blast to work with. --Mark Mark Russell writes: > I am wrapping part of DirectX and have run into an number of variations of > the problem described below. > > In struct IntHwnd; HWND is a pointer. What I pass to the wrapper from > python is an int representation of the pointer so I need to cast the int > from python to a pointer in C++. I need to do the reverse when getting the > attribute. How do I accomplish this? > > struct IntHwnd > { > HWND w; > }; > This seems like a similar problem: http://aspn.activestate.com/ASPN/Mail/Message/1411366 Does that help at all? From dave at boost-consulting.com Sat Nov 16 00:31:27 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 18:31:27 -0500 Subject: [C++-sig] Automatic support for operator[] and operator() Message-ID: I started to write this: --schnipp-- It would be great to support .def(self[int] = double()) // defines '__setitem__' method .def(self[int()] = double()) // defines '__getitem__' method .def(self(int(),double(),double())) --schnapp-- But then I remembered that we need to provide a way for (and encourage) people to supply bounds-checking code which will raise the appropriate IndexError or KeyError exception for the [] operator. And the function-call example is a bit unweildy. More on that later. Maybe the way to go here is to supply an interface like: .def_getsetitem(&X::operator[], _2 < boost::lambda::bind(&X::size, _1)) Or, for those of us with broken compilers that don't support Boost.Lambda: .def_getsetitem(&X::operator[], boost::bind(std::less(), _2, boost::bind(&X::size, _1))) I'm not sure this is the best interface direction; I'm interested in other ideas. The one part I think is valuable is the passing of a function object to help with range detection. However, I note that there's no way for the user to specify IndexError or KeyError here. So maybe handcrafted __get/setitem__ methods are really best after all. Regarding the function-call example, I don't think the above provides significant benefit over the existing facilities for defining "__call__". However, it did get me thinking: we don't need to specify the return type in these operator expressions; maybe our BOOST_PYTHON_[MEMBER]_FUNCTION_OVERLOADS() macros should take advantage of the same techniques so that users don't have to supply the return type of their overload set(s). I'm not sure there's much to be gained here, but it's worth a thought. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From djowel at gmx.co.uk Sat Nov 16 01:03:30 2002 From: djowel at gmx.co.uk (Joel de Guzman) Date: Sat, 16 Nov 2002 08:03:30 +0800 Subject: [C++-sig] Automatic support for operator[] and operator() References: Message-ID: <019401c28d03$af06ec40$88564eca@kim> ----- Original Message ----- From: "David Abrahams" > Regarding the function-call example, I don't think the above provides > significant benefit over the existing facilities for defining > "__call__". However, it did get me thinking: we don't need to specify > the return type in these operator expressions; maybe our > BOOST_PYTHON_[MEMBER]_FUNCTION_OVERLOADS() macros should take > advantage of the same techniques so that users don't have to supply > the return type of their overload set(s). I'm not sure there's much to > be gained here, but it's worth a thought. Hmmm. Perhaps I'm still sleepy "-}, but what technique were you referring to? --Joel From dave at boost-consulting.com Sat Nov 16 03:33:49 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 15 Nov 2002 21:33:49 -0500 Subject: [C++-sig] Automatic support for operator[] and operator() In-Reply-To: <019401c28d03$af06ec40$88564eca@kim> ("Joel de Guzman"'s message of "Sat, 16 Nov 2002 08:03:30 +0800") References: <019401c28d03$af06ec40$88564eca@kim> Message-ID: "Joel de Guzman" writes: > ----- Original Message ----- > From: "David Abrahams" > >> Regarding the function-call example, I don't think the above provides >> significant benefit over the existing facilities for defining >> "__call__". However, it did get me thinking: we don't need to specify >> the return type in these operator expressions; maybe our >> BOOST_PYTHON_[MEMBER]_FUNCTION_OVERLOADS() macros should take >> advantage of the same techniques so that users don't have to supply >> the return type of their overload set(s). I'm not sure there's much to >> be gained here, but it's worth a thought. > > Hmmm. Perhaps I'm still sleepy "-}, but what technique were > you referring to? Whatever technique allows us to infer the return type ;-) See the use of convert_result<> in operators.hpp. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Sat Nov 16 05:47:12 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 16 Nov 2002 17:47:12 +1300 Subject: [C++-sig] call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare><003601c28af4$151387d0$f6784fcb@hare> Message-ID: <018201c28d2b$4927cb10$f6784fcb@hare> > > For that you just need to expose agent, using py_agent as a > Holder. There's no need to expose py_agent itself. > Okay. I *finally* get this. Thanks Brett From brett.calcott at paradise.net.nz Sat Nov 16 06:03:07 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 16 Nov 2002 18:03:07 +1300 Subject: [C++-sig] Re: call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare><003601c28a76$dc2e96d0$1d00a8c0@pdimov2><003501c28af1$de7b9e30$f6784fcb@hare> Message-ID: <018301c28d2d$765c4b40$f6784fcb@hare> > > >> Now /that's/ starting to sound intriguing. I wonder if it's possible > >> to derive our U class from boost::python::objects::instance<>, and > >> automatically generate shared_ptr<> converters for it. > >> > >> Maybe the whole idea of holding a shared_ptr is bogus from the get-go. > >> > > > > I'm not sure what it buys you either. If I have to derive the U > > class from boost::python::objects::instance<> then I have already > > given away non-intrusiveness. > > Which really doesn't matter at all because the U class is > purpose-built. The immediate advantage of the shared_ptr is that it is entirely external - you can use it on objects without changing the source. I thought this was the main advantage -- but as you point out below, there are others... > > > Are there some other advantages to using shared_ptr? > > Oh, yes: many, many. For example, shared_ptr -> shared_ptr is a > legitimate conversion, even though you haven't intruded on U. And > probably more-importantly, shared_ptr<> interoperates seamlessly in > many contexts and serves as a "one-stop shop" for nearly all smart > pointer needs. Just see the enclosed document for reasons why. > > Wow - mind-expanding material. But I still cannot see a way to using shared_ptr. The customer release function passed in the constructor doesn't give you enough control to do the "crazy" counting stuff. How did you want to progress this? Is it worth trying to put something like this back into the library -- or should it just go into the documentation as a "technique"? Cheers, Brett From datafeed at SoftHome.net Sat Nov 16 06:29:11 2002 From: datafeed at SoftHome.net (M. Evans) Date: Fri, 15 Nov 2002 22:29:11 -0700 Subject: [C++-sig] Psycho about performance Message-ID: <7341404756.20021115222911@SoftHome.net> Runs unmodified Python. Maybe an alternative to C++ interfacing in some situations. -M http://psyco.sourceforge.net/introduction.html From dave at boost-consulting.com Sat Nov 16 07:00:40 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 01:00:40 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: <018301c28d2d$765c4b40$f6784fcb@hare> ("Brett Calcott"'s message of "Sat, 16 Nov 2002 18:03:07 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> <003501c28af1$de7b9e30$f6784fcb@hare> <018301c28d2d$765c4b40$f6784fcb@hare> Message-ID: "Brett Calcott" writes: >> > Are there some other advantages to using shared_ptr? >> >> Oh, yes: many, many. For example, shared_ptr -> shared_ptr is a >> legitimate conversion, even though you haven't intruded on U. And >> probably more-importantly, shared_ptr<> interoperates seamlessly in >> many contexts and serves as a "one-stop shop" for nearly all smart >> pointer needs. Just see the enclosed document for reasons why. >> >> > > Wow - mind-expanding material. But I still cannot see a way to using > shared_ptr. The customer release function passed in the constructor doesn't > give you enough control to do the "crazy" counting stuff. You don't need to do the "crazy" counting stuff! (read on...) > How did you want to progress this? Is it worth trying to put something like > this back into the library -- or should it just go into the documentation as > a "technique"? I'm thinking we should do this: 1. Set up Boost.Python so that shared_ptr can be extracted from any Python object from which we can extract T*... no matter how it's held! You can do this by using a custom deleter that holds the Python object and keeps it alive. See the section titled: "Using a shared_ptr to Hold Another Shared Ownership Smart Pointer" I find this very exciting, and can't believe I didn't think of it earlier!! 2. Prepare a special "self_base" class that can be used as a base of "callback" classes like BaseWrap from the examples. This base would hold the "self" pointer. It would also provide a family of convenience functions which implement call_method<> on the held self pointer without having to explicitly mention it (hmm, I'm not sure I can make this work out on msvc6. But that's another issue). Most-importantly, when references and (smart) pointers to polymorphic classes are converted to python, we will attempt to downcast to "self_base", and if successful, we'll return the contained self pointer instead of a new object. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Sat Nov 16 09:18:10 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sat, 16 Nov 2002 21:18:10 +1300 Subject: [C++-sig] Re: call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare><003601c28a76$dc2e96d0$1d00a8c0@pdimov2><003501c28af1$de7b9e30$f6784fcb@hare><018301c28d2d$765c4b40$f6784fcb@hare> Message-ID: <001b01c28d48$bb24ad60$f6784fcb@hare> > > I'm thinking we should do this: > > 1. Set up Boost.Python so that shared_ptr can be extracted from any > Python object from which we can extract T*... no matter how it's > held! You can do this by using a custom deleter that holds the Python > object and keeps it alive. See the section titled: > > "Using a shared_ptr to Hold Another Shared Ownership Smart Pointer" > > I find this very exciting, and can't believe I didn't think of it > earlier!! > > 2. Prepare a special "self_base" class that can be used as a base of > "callback" classes like BaseWrap from the examples. This base would > hold the "self" pointer. It would also provide a family of > convenience functions which implement call_method<> on the held > self pointer without having to explicitly mention it (hmm, I'm not > sure I can make this work out on msvc6. But that's another > issue). Most-importantly, when references and (smart) pointers to > polymorphic classes are converted to python, we will attempt to > downcast to "self_base", and if successful, we'll return the > contained self pointer instead of a new object. > Ok, I understand 2. This gets around having to create to_python converters. But I don't yet see how 1. can work. Is the 'other shared pointer' the Python reference count? Or the shared_ptr declared in class_<...>? Can you elucidate? Cheers, Brett From dave at boost-consulting.com Sat Nov 16 14:06:28 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 08:06:28 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: <001b01c28d48$bb24ad60$f6784fcb@hare> ("Brett Calcott"'s message of "Sat, 16 Nov 2002 21:18:10 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> <003501c28af1$de7b9e30$f6784fcb@hare> <018301c28d2d$765c4b40$f6784fcb@hare> <001b01c28d48$bb24ad60$f6784fcb@hare> Message-ID: "Brett Calcott" writes: >> >> I'm thinking we should do this: >> >> 1. Set up Boost.Python so that shared_ptr can be extracted from any >> Python object from which we can extract T*... no matter how it's >> held! You can do this by using a custom deleter that holds the Python >> object and keeps it alive. See the section titled: >> >> "Using a shared_ptr to Hold Another Shared Ownership Smart Pointer" >> >> I find this very exciting, and can't believe I didn't think of it >> earlier!! >> >> 2. Prepare a special "self_base" class that can be used as a base of >> "callback" classes like BaseWrap from the examples. This base would >> hold the "self" pointer. It would also provide a family of >> convenience functions which implement call_method<> on the held >> self pointer without having to explicitly mention it (hmm, I'm not >> sure I can make this work out on msvc6. But that's another >> issue). Most-importantly, when references and (smart) pointers to >> polymorphic classes are converted to python, we will attempt to >> downcast to "self_base", and if successful, we'll return the >> contained self pointer instead of a new object. >> > > Ok, I understand 2. This gets around having to create to_python > converters. > But I don't yet see how 1. can work. Is the 'other shared pointer' the > Python reference count? Yes. > Or the shared_ptr declared in class_<...>? No, that's my point: we can do it /no matter how the T is held/. First imagine using handle<> as the 'other shared ptr' . Then you can easily replace it with PyObject* : struct pyobject_deleter { pyobject_deleter(handle<> p): p_(p) { } void operator()(void const *) { p_.reset(); } private: handle<> p_; }; template shared_ptr make_shared(PyObject* p) { extract x(p); if (x) { return shared_ptr px(x(), pyobject_deleter(handle<>(borrowed(p))))); } else { // conversion failed } } -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sat Nov 16 14:35:32 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 08:35:32 -0500 Subject: [C++-sig] Psycho about performance In-Reply-To: <7341404756.20021115222911@SoftHome.net> ("M. Evans"'s message of "Fri, 15 Nov 2002 22:29:11 -0700") References: <7341404756.20021115222911@SoftHome.net> Message-ID: "M. Evans" writes: > Runs unmodified Python. Maybe an alternative to C++ interfacing in > some situations. -M > > http://psyco.sourceforge.net/introduction.html Yeah Psyco is _way_ cool. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From achim at procoders.net Sat Nov 16 16:20:13 2002 From: achim at procoders.net (Achim Domma) Date: Sat, 16 Nov 2002 16:20:13 +0100 Subject: [C++-sig] container_conversions.h with VC7 Message-ID: Hi, using Ralfs container_conversion.h with VC7 I get an internal compiler error. The problem seems to be the loop in the lines 165 to 176: for(;;i++) { handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get()))); if (PyErr_Occurred()) { PyErr_Clear(); return 0; } if (!py_elem_hdl.get()) break; // end of iteration object py_elem_obj(py_elem_hdl); extract elem_proxy(py_elem_obj); if (!elem_proxy.check()) return 0; if (is_range) break; // in a range all elements are of the same type } If I comment out the body of the loop, everyting works fine. An older version of bpl_utils had an workaround for VC6 in this function, but I can't get it to work. Does anybody know a workaround? regards, Achim From datafeed at SoftHome.net Sat Nov 16 20:16:48 2002 From: datafeed at SoftHome.net (M. Evans) Date: Sat, 16 Nov 2002 12:16:48 -0700 Subject: [C++-sig] Re: Psycho about performance In-Reply-To: <7341404756.20021115222911@SoftHome.net> References: <7341404756.20021115222911@SoftHome.net> Message-ID: <1106572721.20021116121648@SoftHome.net> >> Runs unmodified Python. Maybe an alternative to C++ interfacing in >> some situations. -M >> >> http://psyco.sourceforge.net/introduction.html > > Yeah Psyco is _way_ cool. > > -- > David Abrahams I hope he does a backend for .NET (slash MONO), which seems appropriate given the capabilities he already has. Mark From dave at boost-consulting.com Sat Nov 16 20:45:26 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 14:45:26 -0500 Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: ("Achim Domma"'s message of "Sat, 16 Nov 2002 16:20:13 +0100") References: Message-ID: "Achim Domma" writes: > Hi, > > using Ralfs container_conversion.h with VC7 I get an internal compiler > error. Which versions of the source (Boost and Ralf's stuff) are you working with? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sat Nov 16 23:31:52 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 17:31:52 -0500 Subject: [C++-sig] Polymorphism Message-ID: I have just completed an analysis of the runtime polymorphism cases we want to handle in Boost.Python. It's at: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/polymorphism.txt It ends by concluding that we need to do basically what we did in Boost.Python v1 to handle this... which is what I expected. I'd be interested if anyone sees other interesting alternatives, though. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Sun Nov 17 00:15:23 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Sat, 16 Nov 2002 15:15:23 -0800 Subject: [C++-sig] problems with lvalue_from_pytype Message-ID: I'm trying to reconstruct the example for lvalue_from_pytype and am having a few problems. I implemented the example as follows as I could not find reference.hpp--I just want an identity function anyway just to know that I can read the type I am trying to convert. I built noddy from the python docs. The following builds just fine but when I try to use is_noddy a get a -- TypeError: bad argument for built-in operation -- Where am I going wrong? #include using namespace boost::python; //defines PyTypeObject noddy_NoddyType; typedef struct { PyObject_HEAD } noddy_NoddyObject; //identity function bool is_noddy(noddy_NoddyObject* x) { if (typeid(noddy_NoddyObject*) == typeid(x)) return true; return false; } BOOST_PYTHON_MODULE(cn) { def("is_noddy", is_noddy); lvalue_from_pytype, &noddy_NoddyType>(); } From dave at boost-consulting.com Sun Nov 17 00:12:06 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 18:12:06 -0500 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: (Mark Russell's message of "Sat, 16 Nov 2002 15:15:23 -0800") References: Message-ID: Mark Russell writes: > I'm trying to reconstruct the example for lvalue_from_pytype and am having a > few problems. I implemented the example as follows as I could not find > reference.hpp-- Oops! Fixed in CVS, thanks. > I just want an identity function anyway just to know that I can read > the type I am trying to convert. I built noddy from the python docs. > The following builds just fine but when I try to use is_noddy a get > a -- TypeError: bad argument for built-in operation -- Where am I > going wrong? you defined noddy_NoddyType again in this Python module. In order for lvalue_from_pytype to work, the PyTypeObject* you pass as a 2nd argument must point to the one used to define the Noddy Python type. To do that, you need to link this Python module to the one which defines noddy_NoddyType (statically or dynamically). > #include > using namespace boost::python; > > //defines > PyTypeObject noddy_NoddyType; > typedef struct > { > PyObject_HEAD > } noddy_NoddyObject; > > //identity function > bool is_noddy(noddy_NoddyObject* x) > { > if (typeid(noddy_NoddyObject*) == typeid(x)) return true; BTW, this probably doesn't do anything useful. It could easily compile away to nothing, since the test can be determined to be true at compile-time. A more-interesting test would be to stick a magic number in your Noddy objects and check it here. > return false; > } > > BOOST_PYTHON_MODULE(cn) > { > def("is_noddy", is_noddy); > lvalue_from_pytype, > &noddy_NoddyType>(); > } -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Sun Nov 17 00:42:57 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 17 Nov 2002 12:42:57 +1300 Subject: [C++-sig] Re: call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare><003601c28a76$dc2e96d0$1d00a8c0@pdimov2><003501c28af1$de7b9e30$f6784fcb@hare><018301c28d2d$765c4b40$f6784fcb@hare><001b01c28d48$bb24ad60$f6784fcb@hare> Message-ID: <004401c28dc9$e4e85710$f6784fcb@hare> > > No, that's my point: we can do it /no matter how the T is held/. > > First imagine using handle<> as the 'other shared ptr' . Then you > can easily replace it with PyObject* : > > struct pyobject_deleter > { > pyobject_deleter(handle<> p): p_(p) > { > } > > void operator()(void const *) > { > p_.reset(); > } > private: > handle<> p_; > }; > > template > shared_ptr make_shared(PyObject* p) > { > extract x(p); > if (x) > { > return shared_ptr px(x(), pyobject_deleter(handle<>(borrowed(p))))); > } > else > { > // conversion failed > } > } > > Ok, make_shared() increments the PyObject refcount, and the pyobject deleter decrements it. But I still don't get the full picture -- can I put this back in the context of my project. Assumption: I have a c++ library and I want to layer the python stuff on top with minimal intrusion. It looks like this: class agent { public: virtual void do_something() { cout << "in c++"; } }; typedef shared_ptr agent_ptr; typedef vector agents; class engine { agents m_agents; public: void add_agent(agent_ptr const &a) { m_agents.push_back(a); } void do_stuff_with_agents() { for_each(m_agents.begin(), m_agents.end(), mem_fun(agent::do_something)); } }; Note that I am using shared_ptr here for my own purpose *unrelated* to python implementation. Now, what do I need to do to expose my C++ lib to python and make agent::do_something overrideable in python code? in python I want: from xxxx import * class py_agent(agent): def do_something(): print 'in python' e = engine() e.add_agent(agent()) e.add_agent(py_agent()) e.do_stuff_with_agents() It seems I have to touch the source code - so we are intruding on the c++ lib. Not the best, but unavoidable in this situation I think. The 'crazy pointer' solution required inheriting agent from a base class and adding a constructor with PyObject *. But we can easily use some #ifdef's to compile a pythonized-or-not version of the library. Now the solution that you are proposing requires a call to make_shared. I'm not sure where this is happening. Does Boost.Python do it for me? Am I required to call it whenever I need to access the elements in m_agents? I can't see how the solution you have can work without causing me to change significantly the underlying c++ lib. Maybe I just don't get it yet. Cheers, Brett From achim.domma at syynx.de Sun Nov 17 00:47:14 2002 From: achim.domma at syynx.de (Achim Domma) Date: Sun, 17 Nov 2002 00:47:14 +0100 Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: Message-ID: > -----Original Message----- > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > Behalf Of David Abrahams > Which versions of the source (Boost and Ralf's stuff) are you working > with? Boost is version 1.29 and Ralf's stuff is the current version from CVS. From dave at boost-consulting.com Sun Nov 17 00:44:37 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 18:44:37 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: <004401c28dc9$e4e85710$f6784fcb@hare> ("Brett Calcott"'s message of "Sun, 17 Nov 2002 12:42:57 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> <003501c28af1$de7b9e30$f6784fcb@hare> <018301c28d2d$765c4b40$f6784fcb@hare> <001b01c28d48$bb24ad60$f6784fcb@hare> <004401c28dc9$e4e85710$f6784fcb@hare> Message-ID: "Brett Calcott" writes: > Ok, make_shared() increments the PyObject refcount, and the pyobject deleter > decrements it. But I still don't get the full picture -- can I put this back > in the context of my project. Let's try. > Assumption: I have a c++ library and I want to layer the python stuff on top > with minimal intrusion. That's a Boost.Python design premise. > It looks like this: > > class agent > { > public: > virtual void do_something() > { > cout << "in c++"; > } > }; > typedef shared_ptr agent_ptr; > typedef vector agents; > > class engine > { > agents m_agents; > public: > void add_agent(agent_ptr const &a) > { > m_agents.push_back(a); > } > > void do_stuff_with_agents() > { > for_each(m_agents.begin(), m_agents.end(), > mem_fun(agent::do_something)); > } > }; > > Note that I am using shared_ptr here for my own purpose *unrelated* to > python implementation. Yup. You probably want a virtual destructor in agent. > Now, what do I need to do to expose my C++ lib to python and make > agent::do_something overrideable in python code? Just the usual stuff. Make a py_agent class like this: struct agent_callback : agent { agent_callback(PyObject* self) : m_self(self) {} void do_something() { call_method(self, "do_something"); } // expose this as "do_something" static void default_do_something(agent& a) { a.agent::do_something(); } PyObject* m_self; }; ... class("agent") .def("do_something", &agent_callback::default_do_something) ; > in python I want: > > from xxxx import * > class py_agent(agent): > def do_something(): > print 'in python' > > e = engine() > e.add_agent(agent()) > e.add_agent(py_agent()) > e.do_stuff_with_agents() > > It seems I have to touch the source code Why? How? > - so we are intruding on the c++ > lib. Not the best, but unavoidable in this situation I think. ?? > The 'crazy pointer' solution required inheriting agent from a base > class and adding a constructor with PyObject *. But we can easily > use some #ifdef's to compile a pythonized-or-not version of the > library. Shouldn't be neccessary. > Now the solution that you are proposing requires a call to > make_shared. I'm not sure where this is happening. Does Boost.Python > do it for me? Yes, or at least it will once we make the right changes. > Am I required to call it whenever I need to access the > elements in m_agents? No, why would you? Those are shared_ptrs. > I can't see how the solution you have can work without causing me to > change significantly the underlying c++ lib. Maybe I just don't get > it yet. HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From achim at procoders.net Sun Nov 17 01:02:57 2002 From: achim at procoders.net (Achim Domma) Date: Sun, 17 Nov 2002 01:02:57 +0100 Subject: [C++-sig] function as custom ctor Message-ID: Hi, I have a class which I don't want to change, with an ctor like this: class Blob { public: Blob(const char* data, const long length); }; From mike at bindkey.com Sun Nov 17 01:12:33 2002 From: mike at bindkey.com (Mike Rovner) Date: Sat, 16 Nov 2002 16:12:33 -0800 Subject: [C++-sig] Re: function as custom ctor References: Message-ID: "Achim Domma" wrote in message > I have a class which I don't want to change, with an ctor like this: > > class Blob { > public: > Blob(const char* data, const long length); > }; > > From Python I want to pass the binary data in a string, so I want to use a > wrapper like > > Blob createBlob(const std::string data) { > return Blob(data.str(),data.size()); > } What about class_("Blob", no_init); def("Blob", createBlob); > and then from Python: > > data = "a string with data to be passed to the blob" > blob = Blob(data) From dave at boost-consulting.com Sun Nov 17 00:55:16 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 18:55:16 -0500 Subject: [C++-sig] Re: Creating an instance of a Python class in C++: PyRun_String? In-Reply-To: (Dirk Gerrits's message of "Fri, 15 Nov 2002 15:38:14 +0100") References: Message-ID: Dirk Gerrits writes: > David Abrahams wrote: > >> >>Does >> >> >> >> http://www.boost.org/libs/python/doc/v2/extract.html#examples >> >> >> >>help? >> > >> >I looked at that one, as I said in my initial post. However the >> >example creates a new python::object instance of a wrapped C++ >> >class. Not of a Python class. Is there some way to create a class_ >> >object from a Python class that I'm not aware of? >> >> >> No. However, if you can arrange to pass the class object from Python >> to C++ in an object instance, you can avoid all of the problems you're >> having with PyRun_String. > > > This sounds very interesting! I don't know how to do it though. I'm > very, very new to the Python/C API, if you hadn't guessed so > already. ;) Can you give me some pointers on this one? Urm, all I meant was: void f(object class_object) // wrap this function { object instance = class_object(param1, param2, ...); Base& = python::extract(instance); ... } Pass the class from Python to the wrapped version of f(). > Check returns false and the extraction throws an exception: > TypeError: No registered converter was able to extract a C++ > reference to type class Base from this Python object of type > PythonDerived > > > This reminded me of something I read in a post by Nicolas Lelong. He > calls python::converter::initialize_builtin_converters() just after > Py_Initialize(). So I tried that, but the linker complained: > > unresolved external symbol "void __cdecl > boost::python::converter::initialize_builtin_converters(void)" > > Any idea why that might be? Because it's not an exported symbol. He was probably linking Boost.Python's sources directly into his application, or was using Unix. You could try something like: #include ... boost::python::converter::registry::query(type_id()) Which will call that function. When we get embedding support officially set up, you won't have to resort to this sort of hack anymore. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 17 01:00:19 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 19:00:19 -0500 Subject: [C++-sig] function as custom ctor In-Reply-To: ("Achim Domma"'s message of "Sun, 17 Nov 2002 01:02:57 +0100") References: Message-ID: "Achim Domma" writes: > Hi, > > I have a class which I don't want to change, with an ctor like this: > > class Blob { > public: > Blob(const char* data, const long length); > }; > > From Python I want to pass the binary data in a string, so I want to use a > wrapper like > > Blob createBlob(const std::string data) { > return Blob(data.str(),data.size()); > } > > Can I pass this funktion to boost.python in a way, that I could be used as > ctor? Something like this: > > class_("Blob",init<>()) > .def( ??? , createBlob ); > > and then from Python: > > data = "a string with data to be passed to the blob" > blob = Blob(data) Not quite, but you can fake it: First expose your class with no_init, then expose createBlob as "Blob". -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Sun Nov 17 03:03:46 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 17 Nov 2002 15:03:46 +1300 Subject: [C++-sig] Re: call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare><003601c28a76$dc2e96d0$1d00a8c0@pdimov2><003501c28af1$de7b9e30$f6784fcb@hare><018301c28d2d$765c4b40$f6784fcb@hare><001b01c28d48$bb24ad60$f6784fcb@hare><004401c28dc9$e4e85710$f6784fcb@hare> Message-ID: <002501c28ddd$9091d380$f6784fcb@hare> > > > > class agent > > { > > public: > > virtual void do_something() > > { > > cout << "in c++"; > > } > > }; > > typedef shared_ptr agent_ptr; > > typedef vector agents; > > > > class engine > > { > > agents m_agents; > > public: > > void add_agent(agent_ptr const &a) > > { > > m_agents.push_back(a); > > } > > > > void do_stuff_with_agents() > > { > > for_each(m_agents.begin(), m_agents.end(), > > mem_fun(agent::do_something)); > > } > > }; > > > > Note that I am using shared_ptr here for my own purpose *unrelated* to > > python implementation. > > Yup. You probably want a virtual destructor in agent. Okay. That would lessen my debugging time :) > > > Now, what do I need to do to expose my C++ lib to python and make > > agent::do_something overrideable in python code? > > Just the usual stuff. Make a py_agent class like this: > > struct agent_callback : agent > { > agent_callback(PyObject* self) : m_self(self) {} > > void do_something() { call_method(self, "do_something"); } > > // expose this as "do_something" > static void default_do_something(agent& a) > { a.agent::do_something(); } > > PyObject* m_self; > }; > *Just* like this? A couple of posts back you said: >> 2. Prepare a special "self_base" class that can be used as a base of >> "callback" classes like BaseWrap from the examples. This base would >> hold the "self" pointer. Where is this base class in here? > > It seems I have to touch the source code > > Why? How? Cos' you need this base class to be a base of agent. Right? Or are you multiply-inheriting? ie. struct agent_callback : agent, boost::python::self_base { ... }; But this suggests that agent is derived directly from self_base: > Most-importantly, when references and (smart) pointers to > polymorphic classes are converted to python, we will attempt to > downcast to "self_base", and if successful, we'll return the > contained self pointer instead of a new object > > No, why would you? Those are shared_ptrs. > I know that. I thought the solution you were proposing meant I had to change this. > > I can't see how the solution you have can work without causing me to > > change significantly the underlying c++ lib. Maybe I just don't get > > it yet. > > HTH, > I'm still lost. Oh! (light bulb glimmers). Hang on. (reads shared_ptr code) 1) invoking add_agent() from python passes a shared_ptr constructed using the custom delete functor. 2) whereas if I call add_agent() from c++, it is just the 'default' shared_ptr, using the checked_delete<> functor. My blind spot was not properly understanding shared_ptr. Wow, it is *extremely* cool. Ok, now I am getting it. The inheritance is still not clear to me. From dave at boost-consulting.com Sun Nov 17 05:40:24 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 16 Nov 2002 23:40:24 -0500 Subject: [C++-sig] Re: call_method In-Reply-To: <002501c28ddd$9091d380$f6784fcb@hare> ("Brett Calcott"'s message of "Sun, 17 Nov 2002 15:03:46 +1300") References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare> <001e01c2878d$26a34d10$2e6e4fcb@hare> <001901c287e7$792e7c80$2e6e4fcb@hare> <007501c2887b$0e508c70$2e6e4fcb@hare> <001601c28a32$6862f9b0$2e6e4fcb@hare> <003601c28a76$dc2e96d0$1d00a8c0@pdimov2> <003501c28af1$de7b9e30$f6784fcb@hare> <018301c28d2d$765c4b40$f6784fcb@hare> <001b01c28d48$bb24ad60$f6784fcb@hare> <004401c28dc9$e4e85710$f6784fcb@hare> <002501c28ddd$9091d380$f6784fcb@hare> Message-ID: "Brett Calcott" writes: >> > Now, what do I need to do to expose my C++ lib to python and make >> > agent::do_something overrideable in python code? >> >> Just the usual stuff. Make a py_agent class like this: >> >> struct agent_callback : agent >> { >> agent_callback(PyObject* self) : m_self(self) {} >> >> void do_something() { call_method(self, "do_something"); } >> >> // expose this as "do_something" >> static void default_do_something(agent& a) >> { a.agent::do_something(); } >> >> PyObject* m_self; >> }; >> > > *Just* like this? A couple of posts back you said: > >>> 2. Prepare a special "self_base" class that can be used as a base of >>> "callback" classes like BaseWrap from the examples. This base would >>> hold the "self" pointer. > > Where is this base class in here? Yeah, yeah, sure. You'd do that if you want to make sure the identity of the Python instance is preserved when you hold it by shared_ptr and then pass it back to Python. I wasn't sure you needed that functionality for your application... but maybe you do. >> > It seems I have to touch the source code >> >> Why? How? > > Cos' you need this base class to be a base of agent. Right? ...no... > Or are you multiply-inheriting? ie. > > struct agent_callback : agent, boost::python::self_base { ... }; Yeah, that's the ticket. > But this suggests that agent is derived directly from self_base: > >> Most-importantly, when references and (smart) pointers to >> polymorphic classes are converted to python, we will attempt to >> downcast to "self_base", and if successful, we'll return the >> contained self pointer instead of a new object I did say "downcast" didn't I? Inheritance DAGs are usually written with derived classes at the bottom. So, if agent is polymorphic, we can use dynamic_cast(&x) to see if there's an associated Python object. > I'm still lost. Oh! (light bulb glimmers). Hang on. (reads > shared_ptr code) > > 1) invoking add_agent() from python passes a shared_ptr constructed using > the custom delete functor. > > 2) whereas if I call add_agent() from c++, it is just the 'default' > shared_ptr, using the checked_delete<> functor. Yup. > My blind spot was not properly understanding shared_ptr. Wow, it is > *extremely* cool. Is it not? IS IT NOT?! I am more and more impressed with Peter's design the more I look at it. > Ok, now I am getting it. The inheritance is still not clear to me. > > From a previous post: >> Most-importantly, when references and (smart) pointers to >> polymorphic classes are converted to python, we will attempt to >> downcast to "self_base", and if successful, we'll return the >> contained self pointer instead of a new object > > This suggests that agent is derived from self_base, not multiply-inherited > in agent_callback. I don't know what suggests that. > The agent might have been created from the c++ side - so the > self_pointer might be null. How do we deal with this case? If it was created from the C++ side, the downcast to self_base will fail because there is no associated Python object. In that case you just create a new Python object around the C++ object. We can also think about doing some deleter introspection to get even more power out of this. See http://aspn.activestate.com/ASPN/Mail/Message/boost/1437090. We can do this without any changes to the shared_ptr library, but it requires some hacks, and I'd rather convince Peter to make it part of the public interface. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Sun Nov 17 06:07:53 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 16 Nov 2002 21:07:53 -0800 (PST) Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: Message-ID: <20021117050753.84054.qmail@web20208.mail.yahoo.com> I am using container_conversions.h with VC7 all the time (I stopped using VC 6 a while ago). What is your container type? Which policy are you using? What is the ICE? Ralf --- Achim Domma wrote: > > -----Original Message----- > > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > > Behalf Of David Abrahams > > > Which versions of the source (Boost and Ralf's stuff) are you working > > with? > > Boost is version 1.29 and Ralf's stuff is the current version from CVS. __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From brett.calcott at paradise.net.nz Sun Nov 17 06:23:16 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Sun, 17 Nov 2002 18:23:16 +1300 Subject: [C++-sig] Re: call_method References: <003501c2864c$fe7ff3b0$2e6e4fcb@hare><001e01c2878d$26a34d10$2e6e4fcb@hare><001901c287e7$792e7c80$2e6e4fcb@hare><007501c2887b$0e508c70$2e6e4fcb@hare><001601c28a32$6862f9b0$2e6e4fcb@hare><003601c28a76$dc2e96d0$1d00a8c0@pdimov2><003501c28af1$de7b9e30$f6784fcb@hare><018301c28d2d$765c4b40$f6784fcb@hare><001b01c28d48$bb24ad60$f6784fcb@hare><004401c28dc9$e4e85710$f6784fcb@hare><002501c28ddd$9091d380$f6784fcb@hare> Message-ID: <000f01c28df9$7096f670$f6784fcb@hare> > > > > *Just* like this? A couple of posts back you said: > > > >>> 2. Prepare a special "self_base" class that can be used as a base of > >>> "callback" classes like BaseWrap from the examples. This base would > >>> hold the "self" pointer. > > > > Where is this base class in here? > > Yeah, yeah, sure. You'd do that if you want to make sure the identity > of the Python instance is preserved when you hold it by > shared_ptr and then pass it back to Python. I wasn't sure you > needed that functionality for your application... but maybe you do. > I don't know I need it *right now*, but I suspect it will come back and bite me if there is not python object identity. > > > But this suggests that agent is derived directly from self_base: > > > >> Most-importantly, when references and (smart) pointers to > >> polymorphic classes are converted to python, we will attempt to > >> downcast to "self_base", and if successful, we'll return the > >> contained self pointer instead of a new object > > > I did say "downcast" didn't I? Inheritance DAGs are usually written > with derived classes at the bottom. > Not the first time I've got this round the wrong :( > > > My blind spot was not properly understanding shared_ptr. Wow, it is > > *extremely* cool. > > Is it not? IS IT NOT?! > > I am more and more impressed with Peter's design the more I look at > it. Likewise. My handrolled smart_ptr's of yesteryear look pretty naive now... > > > Ok, now I am getting it. The inheritance is still not clear to me. > > > > From a previous post: > >> Most-importantly, when references and (smart) pointers to > >> polymorphic classes are converted to python, we will attempt to > >> downcast to "self_base", and if successful, we'll return the > >> contained self pointer instead of a new object > > > > This suggests that agent is derived from self_base, not multiply-inherited > > in agent_callback. > > I don't know what suggests that. More downcast blundering on my part here. > > > The agent might have been created from the c++ side - so the > > self_pointer might be null. How do we deal with this case? > > If it was created from the C++ side, the downcast to self_base will > fail because there is no associated Python object. In that case you > just create a new Python object around the C++ object. > So, in python, getting the same C++ agent twice won't give us the same python object? I can live with that... > We can also think about doing some deleter introspection to get even > more power out of this. See > http://aspn.activestate.com/ASPN/Mail/Message/boost/1437090. We can do > this without any changes to the shared_ptr library, but it requires > some hacks, and I'd rather convince Peter to make it part of the > public interface. > This is getting better and better... Cheers, Brett From rwgk at yahoo.com Sun Nov 17 06:30:51 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Sat, 16 Nov 2002 21:30:51 -0800 (PST) Subject: [C++-sig] function as custom ctor In-Reply-To: Message-ID: <20021117053051.85717.qmail@web20208.mail.yahoo.com> --- David Abrahams wrote: > "Achim Domma" writes: > > I have a class which I don't want to change, with an ctor like this: > > > > class Blob { > > public: > > Blob(const char* data, const long length); > > }; > > > > From Python I want to pass the binary data in a string, so I want to use a > > wrapper like > > > > Blob createBlob(const std::string data) { > > return Blob(data.str(),data.size()); > > } > > > > Can I pass this funktion to boost.python in a way, that I could be used as > > ctor? Something like this: > > > > class_("Blob",init<>()) > > .def( ??? , createBlob ); > > > > and then from Python: > > > > data = "a string with data to be passed to the blob" > > blob = Blob(data) > > Not quite, but you can fake it: > > First expose your class with no_init, then expose createBlob as > "Blob". Not quite? I think I am doing what Achim is looking for. It goes along the lines of (untested!): struct BlopPlus : Blob { // Additional constructor(s) here BlopPlus(PyObject*, std::string const& s) : Blop(s.c_str(), s.size()) {} // Don't forget the constructor that converts a Blob to a BlopPlus BlopPlus(PyObject*, Blop const& b) : Blop(b) {} }; class_("Blop", no_init) .def(init()) .def(init()) ; I believe this is re/mis-using the virtual function support, but it works great for me. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From achim at procoders.net Sun Nov 17 19:22:05 2002 From: achim at procoders.net (Achim Domma) Date: Sun, 17 Nov 2002 19:22:05 +0100 Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: <20021117050753.84054.qmail@web20208.mail.yahoo.com> Message-ID: > -----Original Message----- > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > Behalf Of Ralf W. Grosse-Kunstleve > > > I am using container_conversions.h with VC7 all the time (I > stopped using VC 6 > a while ago). What is your container type? Which policy are you > using? What is > the ICE? > Ralf Here is the orginal call. Magick::Image is a class from ImageMagick, which is the library I'm creating a wrapper for: scitbx::boost_python::container_conversions::from_python_sequence< std::list, scitbx::boost_python::container_conversions::linked_list_policy>(); Which details do you want to know about the ICE? Beside the sourcefile of the compiler, I have no additional information. Achim From achim at procoders.net Sun Nov 17 19:31:08 2002 From: achim at procoders.net (Achim Domma) Date: Sun, 17 Nov 2002 19:31:08 +0100 Subject: [C++-sig] string conversion / passing binary data Message-ID: Hi, my ctor for Blob works now (thanks to Dave, Ralf and Mark) and is implemented like this: Blob createBlob(std::string const& s) { // debug output, see below std::cout << "Stringsize:" << s.size() << std::endl; return Blob(s.c_str(),s.size()); } void add_class_Blob_to_module() { class_("Blob",no_init) ; def("Blob",createBlob); } But now it seems that the conversion to std::string has problems with zeros in the python-string. Here is an example python session: >>> import PythonMagick >>> data = open('01.jpg','rb').read() >>> b = PythonMagick.Blob(data) Stringsize:4 >>> print len(data) 18337 >>> As far as I know, std::string is allowed to contain zeros, so is this a bug or my fault? Is there a better datatype to pass binary data from python to C++? regards, Achim From dave at boost-consulting.com Sun Nov 17 19:23:33 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 17 Nov 2002 13:23:33 -0500 Subject: [C++-sig] string conversion / passing binary data In-Reply-To: ("Achim Domma"'s message of "Sun, 17 Nov 2002 19:31:08 +0100") References: Message-ID: "Achim Domma" writes: > Hi, > > my ctor for Blob works now (thanks to Dave, Ralf and Mark) and is > implemented like this: > > Blob createBlob(std::string const& s) { > // debug output, see below > std::cout << "Stringsize:" << s.size() << std::endl; > return Blob(s.c_str(),s.size()); > } > > void add_class_Blob_to_module() { > class_("Blob",no_init) > ; > def("Blob",createBlob); > } > > But now it seems that the conversion to std::string has problems with zeros > in the python-string. Here is an example python session: > >>>> import PythonMagick >>>> data = open('01.jpg','rb').read() >>>> b = PythonMagick.Blob(data) > Stringsize:4 >>>> print len(data) > 18337 >>>> > > As far as I know, std::string is allowed to contain zeros, so is this a bug > or my fault? Is there a better datatype to pass binary data from python to > C++? IIRC this bug has been fixed in the Boost CVS. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From achim at procoders.net Mon Nov 18 08:21:51 2002 From: achim at procoders.net (Achim Domma) Date: Mon, 18 Nov 2002 08:21:51 +0100 Subject: [C++-sig] string conversion / passing binary data In-Reply-To: Message-ID: > -----Original Message----- > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > Behalf Of David Abrahams > IIRC this bug has been fixed in the Boost CVS. Trying to use the current CVS state, I get the following errors: E:\cvsroot\boost\boost\mpl\aux_\has_rebind.hpp(27) : error C2065: 'has_rebind_impl' : undeclared identifier E:\cvsroot\boost\boost\mpl\aux_\has_rebind.hpp(27) : error C2065: 'rebind' : undeclared identifier E:\cvsroot\boost\boost\mpl\aux_\has_rebind.hpp(29) : error C2501: 'BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF' : missing storage-class or type specifiers E:\cvsroot\boost\boost\mpl\aux_\has_rebind.hpp(29) : error C2078: too many initializers E:\cvsroot\boost\boost\mpl\aux_\has_rebind.hpp(29) : error C2143: syntax error : missing ';' before ''template<'' Do I have to checkout a special version of mpl? regards, Achim From agurtovoy at meta-comm.com Mon Nov 18 08:34:00 2002 From: agurtovoy at meta-comm.com (Aleksey Gurtovoy) Date: Mon, 18 Nov 2002 01:34:00 -0600 Subject: [C++-sig] string conversion / passing binary data Message-ID: <4034600A4760D411B8720001031D84FB0109653D@postoffice.office.meta> Achim Domma wrote: > Trying to use the current CVS state, I get the following errors: [mpl's errors skipped] Err, sorry, that was me - forgot to check in a header. Fixed now, please try again. Aleksey From achim at procoders.net Mon Nov 18 10:49:51 2002 From: achim at procoders.net (Achim Domma) Date: Mon, 18 Nov 2002 10:49:51 +0100 Subject: [C++-sig] string conversion / passing binary data In-Reply-To: <4034600A4760D411B8720001031D84FB0109653D@postoffice.office.meta> Message-ID: > -----Original Message----- > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > Behalf Of Aleksey Gurtovoy > Err, sorry, that was me - forgot to check in a header. Fixed now, > please try > again. Thanks, it works now! From achim.domma at syynx.de Mon Nov 18 11:53:47 2002 From: achim.domma at syynx.de (Achim Domma) Date: Mon, 18 Nov 2002 11:53:47 +0100 Subject: [C++-sig] string conversion / passing binary data In-Reply-To: Message-ID: > -----Original Message----- > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > Behalf Of David Abrahams > IIRC this bug has been fixed in the Boost CVS. Yes, it works. Thanks! Achim From warkid at hotbox.ru Mon Nov 18 18:14:43 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Mon, 18 Nov 2002 20:14:43 +0300 (MSK) Subject: [C++-sig] Passing C++ arrays as arguments Message-ID: <200211181714.gAIHEhrN018740@www5.mailru.com> Hello. I'm exposing to Python some third party library wich has an API like this: struct Abstract{ virtual void f(float[16])=0; }; Abstract *createInstance(); with this code: def("createInstance", createInstance, return_value_policy()); class_("Abstract", no_init) .def("f", Abstract::f); Can I simply define some from python tuple to float [16] converter so that I can call object returned from createInstance like this: createInstance().f((0,)*16) ? Best regards, Kerim From dave at boost-consulting.com Mon Nov 18 18:52:12 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 18 Nov 2002 12:52:12 -0500 Subject: [C++-sig] Mail Problems Message-ID: I seem to suddenly be losing lots of my incoming mail. I think I can recover some of it, but if you've sent me mail this morning which you think I really need to see, you might want to resend it. Regards, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Mon Nov 18 19:50:31 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 18 Nov 2002 10:50:31 -0800 (PST) Subject: [C++-sig] Passing C++ arrays as arguments In-Reply-To: <200211181714.gAIHEhrN018740@www5.mailru.com> Message-ID: <20021118185031.66953.qmail@web20209.mail.yahoo.com> --- Kerim Borchaev wrote: > Can I simply define some from python tuple to float > [16] converter so > that I can call object returned from createInstance > like this: > createInstance().f((0,)*16) ? IIUC, the information about the size is ignored by the compiler. Your declaration is equivalent to void f(float*). But you can use a thin wrapper with a boost::array const& in the signature, in combination with the scitbx container conversion header (which has no dependencies other than Boost.Python V2). Here is the header: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/include/scitbx/boost_python/container_conversions.h Here is a regression test/example: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/cctbx/scitbx/array_family/boost_python/regression_test_ext.cpp Look for, e.g. boost_array_3 and scitbx::boost_python::container_conversions::from_python_sequence< boost::array, scitbx::boost_python::container_conversions::fixed_size_policy>(); Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From rwgk at yahoo.com Mon Nov 18 20:14:48 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 18 Nov 2002 11:14:48 -0800 (PST) Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: Message-ID: <20021118191448.32680.qmail@web20206.mail.yahoo.com> --- Achim Domma wrote: > scitbx::boost_python::container_conversions::from_python_sequence< > std::list, > scitbx::boost_python::container_conversions::linked_list_policy>(); My regression test with std::list doesn't cause any problems with VC7. > Which details do you want to know about the ICE? The output from the compiler could be useful. I'd try this: To test if the ICE is connected to differences in the use of compiler options, replace Magick::Image by double. If double works, put back the Magick::Image and then keep rearranging the code in the container conversions header until it works (e.g. break up the statements, dispatch to a new function to do part of the work, anything else you can think of). Send me the revised header once it works for you. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From mrussell8081 at pacbell.net Mon Nov 18 20:44:51 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Mon, 18 Nov 2002 11:44:51 -0800 Subject: [C++-sig] more problems with lvalue_from_pytype Message-ID: David, Thanks for your response to my email on lvalue_from_pytype over the weekend. I am using the changes you made is cvs and have the following questions. I am mainly a python programmer and know just enough c++ to get by, so please excuse these questions if they are very basic. I am using msvc 6.5 for this project; you might remember that I am wrapping DirectX8 so far boost.python is making this work laughably easy. There is one part I am stuck on. In DirectX there are gobs of structs more of which are no problem to wrap in boost. A windows handle (HWND) is a data member that appears in a number of these structs. I am using Mark Hammods win32ui lib for the windows frame in python. This handle is a pointer in c++ and is represented as an int in python--so I need to convert this. As it turns out the win32ui class that creates the window is put together as a python type--ui_type. My plan is to register a converter for this type in boost as follows: struct PyCWnd_to_HWND { static HWND& execute(PyObject& o) { static HWND w; PyObject* pylong = PyObject_CallMethod(&o, "GetSafeHwnd", NULL); long hwndlong = PyLong_AsLong(pylong); w = reinterpret_cast(hwndlong); return w; } }; I am having trouble linking to the PyTypeObject and am working with the example in lvalue_from_pytype to understand how to do this. I am working with the following: #include extern PyTypeObject noddy_NoddyType; typedef struct { PyObject_HEAD } noddy_NoddyObject; using namespace boost::python; static handle<> cache; bool is_cached(noddy_NoddyObject* x) { return x == cache.get(); } void set_cache(noddy_NoddyObject* x) { cache = handle<>(borrowed(x)); } BOOST_PYTHON_MODULE(noddy_cache) { // register Noddy lvalue converter lvalue_from_pytype,&noddy_NoddyType>(); def("is_cached", is_cached); def("set_cache", set_cache); } I am statically linking this at the moment and will dynamically link next. Your example does not declare noddy_NoddyType but I can't get this to compile so use the extern declaration. When I compile I get the following error: Compiling... nc.cpp C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(14) : error C2446: '==' : no conversion from 'struct _object *' to 'noddy_NoddyObject *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(14) : error C2230: '==' : indirection to different types Error executing cl.exe. noddy cache.dll - 2 error(s), 0 warning(s) What am I missing?? Many thanks for all your help. --Mark From dirk at gerrits.homeip.net Mon Nov 18 22:44:30 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Mon, 18 Nov 2002 22:44:30 +0100 Subject: [C++-sig] Contributing an embedding example (after a bugfix ;) Message-ID: After receiving a lot of help in another thread (thanks!) I was able to get my little Boost.Python program using embedding to compile and run. It works great! But upon deinitialization with Py_Finalize(), I get an error: Fatal Python error: PyThreadState_Get: no current thread I don't really know what is causing this, so I am asking for your help again. :) After having fixed this though, I'd be willing to contribute this as an example for Boost.Python, if there is interest. I thought it was a pretty neat technique myself. ;) Before that, I'd need to Boostify the code a bit though, and I am wondering if all of it is necessary. For example, BaseWrap seems a bit superfluous since I'm only using Base's polymorphism from the C++ side. Any comments on this? Regards, Dirk Gerrits -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: main.cpp URL: From achim.domma at syynx.de Mon Nov 18 22:52:29 2002 From: achim.domma at syynx.de (Achim Domma) Date: Mon, 18 Nov 2002 22:52:29 +0100 Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: <20021118191448.32680.qmail@web20206.mail.yahoo.com> Message-ID: > -----Original Message----- > From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On > Behalf Of Ralf W. Grosse-Kunstleve > My regression test with std::list doesn't cause any > problems with VC7. The attached example crashes even with std::list. You can find the output in out.txt. My compiler shows version number 13.00.9466 and I'm working on Win2K Server with SP2. Because I have very few simple functions which has lists as parameters, I managed to use boost::python::list. So I do not depend on your code, but I will try to help finding the problem, if you are interested in. I will follow your advice to decompose the function and will let you know if it works for me. regards, Achim -------------- next part -------------- A non-text attachment was scrubbed... Name: ContainerTest.zip Type: application/x-zip-compressed Size: 3520 bytes Desc: not available URL: From rwgk at yahoo.com Tue Nov 19 00:46:34 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 18 Nov 2002 15:46:34 -0800 (PST) Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: Message-ID: <20021118234634.40507.qmail@web20202.mail.yahoo.com> --- Achim Domma wrote: > The attached example crashes even with std::list. You can find the > output in out.txt. My compiler shows version number 13.00.9466 and I'm > working on Win2K Server with SP2. The version number is exactly the same here, but we only have the standard edition without the optimizer. I am not sure about the SP. Here are the compile flags that I am using: cl /nologo /MD /GR /GX /Zm800 -DBOOST_PYTHON_MAX_ARITY=12 -DBOOST_PYTHON_MAX_BASES=2 /Ilibtbx\include /IR:\dist\libtbx\include /IR:\dist\scitbx\include /IR:\dist\boost /IC:\Python22\include /c R:\dist\scitbx\array_family\boost_python\regression_test_ext.cpp /Foscitbx\array_family\boost_python\regression_test_ext.obj > Because I have very few simple functions which has lists as parameters, I > managed to use boost::python::list. So I do not depend on your code, but I > will try to help finding the problem, if you are interested in. I will > follow your advice to decompose the function and will let you know if it > works for me. What happens if you take out the optimization flags? Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From cleung at eos.ubc.ca Tue Nov 19 01:30:11 2002 From: cleung at eos.ubc.ca (cleung at eos.ubc.ca) Date: Mon, 18 Nov 2002 16:30:11 -0800 (PST) Subject: [C++-sig] Using bjam Outside of the Boost Directory Message-ID: <33112.137.82.23.136.1037665811.squirrel@webmail.eos.ubc.ca> Hi, I've been trying to build my extension modules using bjam in the libs/python directory and it works well. However, when I try compiling the modules outside of Boost root, bjam gives me some problems. I've already set the BOOST_BUILD_PATH and BOOST_ROOT environment variables. For example, when I try building the "hello world" module in a directory outside of libs/python, I wrote a Jamfile as following: # Include definitions needed for Python modules SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; extension hello : hello.cpp $(BOOST_ROOT)/libs/python/build/boost_python : $(BOOST_ROOT) ; It gives me the following error... /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/boost-base.jam:1470: in find-compatible-subvariant *** argument error * rule is-link-compatible ( feature : value1 : value2 ) * called with: ( : PYD : ) * missing argument value2 /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/boost-base.jam:1416:see definition of rule 'is-link-compatible' being called /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/boost-base.jam:1517: in link-libraries /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/boost-base.jam:1754: in subvariant-target /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/boost-base.jam:1839: in main-target /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/boost-base.jam:1330: in declare-local-target /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/python.jam:302: in extension Jamfile:13: in load-jamfiles /nfs/kite/users/cleung/install/boost_gcc3.2/tools/build/bootstrap.jam:15: in boost-build /nfs/kite/users/cleung/install/boost_gcc3.2/boost-build.jam:17: in module scope Using print statements, I figured that the subvariant is not set correctly Does anyone know how to fix this or where I can find more information/examples in using bjam outside of boost/libs? Thanks, Charles From warkid at hotbox.ru Tue Nov 19 10:29:31 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Tue, 19 Nov 2002 12:29:31 +0300 (MSK) Subject: [C++-sig] Passing C++ arrays as arguments Message-ID: <200211190929.gAJ9TVR6039674@www1.mailru.com> Hello Ralf, how can I wrap a third patry abstract class that is returned by their function? Except than, say, wrapping this function to return a delegate of this class? Best regards, Kerim mailto:warkid at hotbox.ru Monday, November 18, 2002, 9:50:31 PM, you wrote: RWGK> --- Kerim Borchaev wrote: >> Can I simply define some from python tuple to float >> [16] converter so >> that I can call object returned from createInstance >> like this: >> createInstance().f((0,)*16) ? RWGK> IIUC, the information about the size is ignored by the compiler. Your RWGK> declaration is equivalent to void f(float*). But you can use a thin wrapper RWGK> with a boost::array const& in the signature, in combination with the RWGK> scitbx container conversion header (which has no dependencies other than RWGK> Boost.Python V2). RWGK> Here is the header: RWGK> http://cvs.sourceforge.net/cgi- bin/viewcvs.cgi/cctbx/scitbx/include/scitbx/boost_pyth on/container_conversions.h RWGK> Here is a regression test/example: RWGK> http://cvs.sourceforge.net/cgi- bin/viewcvs.cgi/cctbx/scitbx/array_family/boost_python /regression_test_ext.cpp RWGK> Look for, e.g. boost_array_3 and RWGK> scitbx::boost_python::container_conversions::from_pyth on_sequence< RWGK> boost::array, RWGK> scitbx::boost_python::container_conversions::fixed_siz e_policy>(); RWGK> Ralf RWGK> __________________________________________________ RWGK> Do you Yahoo!? RWGK> Yahoo! Web Hosting - Let the expert host your site RWGK> http://webhosting.yahoo.com RWGK> _______________________________________________ RWGK> C++-sig mailing list RWGK> C++-sig at python.org RWGK> http://mail.python.org/mailman/listinfo/c++-sig From dave at boost-consulting.com Tue Nov 19 13:57:49 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 07:57:49 -0500 Subject: [C++-sig] Using bjam Outside of the Boost Directory In-Reply-To: <33112.137.82.23.136.1037665811.squirrel@webmail.eos.ubc.ca> ('s message of "Mon, 18 Nov 2002 16:30:11 -0800 (PST)") References: <33112.137.82.23.136.1037665811.squirrel@webmail.eos.ubc.ca> Message-ID: writes: > Hi, > > I've been trying to build my extension modules using bjam in the > libs/python directory and it works well. However, when I try compiling > the modules outside of Boost root, bjam gives me some problems. I've > already set the BOOST_BUILD_PATH and BOOST_ROOT environment variables. > > For example, when I try building the "hello world" module in a directory > outside of libs/python, I wrote a Jamfile as following: > > > > # Include definitions needed for Python modules > SEARCH on python.jam = $(BOOST_BUILD_PATH) ; > > include python.jam ; > > extension hello : hello.cpp $(BOOST_ROOT)/libs/python/build/boost_python > : $(BOOST_ROOT) > ; > That won't work with Boost.Build v1. We're working on Boost.Build v2, which will allow that sort of thing. In the meantime, please see: http://www.boost.org/libs/python/doc/building.html#building_ext The section starting "If you can't modify or copy your boost installation" has the information you need. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Tue Nov 19 16:57:20 2002 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Tue, 19 Nov 2002 07:57:20 -0800 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: <20021118234634.40507.qmail@web20202.mail.yahoo.com> References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> Message-ID: <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. My Python extension module fails to intialize. From the function generated by the macro BOOST_PYTHON_MODULE_INIT(hippo) the assertion in BOOST_FUNCTION_FUNCTION::operator() assert(!this->empty()); fails. With same source code, I do not have the problem with gcc 2.95.3 with boost 1.25.0 or gcc 3.2 with boost 1.28.0 under RedHat Linux. Also didn't have the problem with VC++ 6.0 sp 5. Any clues? Known problem? From Shayne.FLETCHER at rbos.com Tue Nov 19 17:56:48 2002 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Tue, 19 Nov 2002 16:56:48 -0000 Subject: [C++-sig] gcc-3.0.4, SunOS import module error Message-ID: Hi all: I'm having trouble reflecting inheritance hierarchies with gcc 3.0.4 on SunOS 5.8. Basically, a module like: struct bar{}; struct baz{}; struct foo : bar, baz {}; BOOST_PYTHON_MODULE(test_derivation) { class_("bar") ; class_("baz") ; class_ >("foo") ; } gives a bus error when the module is loaded from the interpreter e.g. Python 2.2.1 (#1, Sep 17 2002, 17:26:18) [C] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> import test_derivation Interestingly, the same thing happens with "cltree.so" from the boost.python tests when loaded from the interpreter as above i.e. Python 2.2.1 (#1, Sep 17 2002, 17:26:18) [C] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> import cltree causes a bus error, but not when executed as part of the bjam build and test procedure - i.e. $bjam -sTOOLS=gcc -sPYTHON_TEST_ARGS=-v test produces output // ... running... python-test-target ../../../libs/python/test/bin/pearu1.test/gcc/debug/runtime-link-dynamic/pea ru1.test b= cltree.basic() s= c= cltree.constant() v= cltree.wrapped_variable() ok // ... Any ideas? - Shayne. ******************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority ******************************************************************** From rwgk at yahoo.com Tue Nov 19 18:01:12 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 19 Nov 2002 09:01:12 -0800 (PST) Subject: [C++-sig] function as custom ctor In-Reply-To: Message-ID: <20021119170112.11649.qmail@web20204.mail.yahoo.com> --- David Abrahams wrote: > > Can I pass this funktion to boost.python in a way, that I could be used as > > ctor? Something like this: > > > > class_("Blob",init<>()) > > .def( ??? , createBlob ); > > > > and then from Python: > > > > data = "a string with data to be passed to the blob" > > blob = Blob(data) > > Not quite, but you can fake it: > > First expose your class with no_init, then expose createBlob as > "Blob". Can there be both a class_("Blob", ...) /with constructors/ and a free factory function def("Blob", ...)? Can there even be multiple constructors and factory functions? Is the order of the class_<> and free def statements important? Thanks, Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From dave at boost-consulting.com Tue Nov 19 18:00:20 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 12:00:20 -0500 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Tue, 19 Nov 2002 07:57:20 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: > Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. > > My Python extension module fails to intialize. From the function > generated by the macro > > BOOST_PYTHON_MODULE_INIT(hippo) > > the assertion in BOOST_FUNCTION_FUNCTION::operator() > > assert(!this->empty()); > > fails. With same source code, I do not have the problem with gcc > 2.95.3 with boost 1.25.0 or gcc 3.2 with boost 1.28.0 under RedHat > Linux. Also didn't have the problem with VC++ 6.0 sp 5. > > Any clues? Known problem? Sorry, nope. I can only suggest an upgrade to a current Boost.Python v2. It's much better tested than 1.28.0. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From BPettersen at NAREX.com Tue Nov 19 18:01:59 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Tue, 19 Nov 2002 10:01:59 -0700 Subject: [C++-sig] Problem with vc++ 7 Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> > From: Paul F. Kunz [mailto:Paul_Kunz at SLAC.Stanford.EDU] > > Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. > > My Python extension module fails to intialize. [...] A number of incompatibilities between Python built with VC6 and extensions built with VC7 has been reported due to different run-time libraries. The Python developers are aware of this, however they're unlikely to move to VC7 until at least some of the most common extensions are ported. (Besides, they don't have a VC7 optimizing compiler yet, which makes it kind of difficult ;-) You can always compile Python with VC7 yourself, although you'll probably have to get some files from cvs... -- bjorn From dave at boost-consulting.com Tue Nov 19 18:04:09 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 12:04:09 -0500 Subject: [C++-sig] gcc-3.0.4, SunOS import module error In-Reply-To: ("FLETCHER, Shayne, FM"'s message of "Tue, 19 Nov 2002 16:56:48 -0000") References: Message-ID: "FLETCHER, Shayne, FM" writes: > Hi all: > > I'm having trouble reflecting inheritance hierarchies with gcc 3.0.4 on > SunOS 5.8. > Basically, a module like: > > struct bar{}; > struct baz{}; > struct foo : bar, baz {}; > > BOOST_PYTHON_MODULE(test_derivation) > { > class_("bar") > ; > class_("baz") > ; > class_ >("foo") > ; > } > > gives a bus error when the module is loaded from the interpreter e.g. > > Python 2.2.1 (#1, Sep 17 2002, 17:26:18) [C] on sunos5 > Type "help", "copyright", "credits" or "license" for more information. >>>> import test_derivation Probably you don't have your PYTHONPATH or LD_LIBRARY_PATH set up properly. > Interestingly, the same thing happens with "cltree.so" from the boost.python > tests when loaded from the interpreter as above i.e. > Python 2.2.1 (#1, Sep 17 2002, 17:26:18) [C] on sunos5 > Type "help", "copyright", "credits" or "license" for more information. >>>> import cltree > > causes a bus error, > > but not when executed as part of the bjam build and test procedure - i.e. > $bjam -sTOOLS=gcc -sPYTHON_TEST_ARGS=-v test > > produces output > // ... > > running... > python-test-target > ../../../libs/python/test/bin/pearu1.test/gcc/debug/runtime-link-dynamic/pea > ru1.test > b= cltree.basic() > s= > c= cltree.constant() > v= cltree.wrapped_variable() > ok > > // ... > > Any ideas? try bjam -sTOOLS=gcc -sPYTHON_TEST_ARGS=-v -n -a test to see what commands it's executing. You may be missing something important when you try to build/run "by hand". -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Tue Nov 19 18:07:52 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 19 Nov 2002 09:07:52 -0800 (PST) Subject: [C++-sig] Slow gcc 3.2 links Message-ID: <20021119170752.96503.qmail@web20208.mail.yahoo.com> When linking my Boost.Python V2 extension modules with gcc 3.2 under Linux 7.3 and 8.0 I have to wait up to 10 minutes per link command to finish. gcc <= 3.0.4 never had this problem. The machine does not run out of core memory when linking with 3.2, but uses 99% of a CPU all the time. Do others have similar observations, or is it just me doing something stupid? Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From dave at boost-consulting.com Tue Nov 19 18:06:56 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 12:06:56 -0500 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> ("Bjorn Pettersen"'s message of "Tue, 19 Nov 2002 10:01:59 -0700") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: >> From: Paul F. Kunz [mailto:Paul_Kunz at SLAC.Stanford.EDU] >> >> Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. >> >> My Python extension module fails to intialize. > [...] > > A number of incompatibilities between Python built with VC6 and > extensions built with VC7 has been reported due to different run-time > libraries. The Python developers are aware of this, however they're > unlikely to move to VC7 until at least some of the most common > extensions are ported. (Besides, they don't have a VC7 optimizing > compiler yet, which makes it kind of difficult ;-) You can always > compile Python with VC7 yourself, although you'll probably have to get > some files from cvs... FWIW I have never had any problems testing Boost extensions built with VC7 against a vc6 build of Python. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Tue Nov 19 18:12:09 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 12:12:09 -0500 Subject: [C++-sig] Slow gcc 3.2 links In-Reply-To: <20021119170752.96503.qmail@web20208.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Tue, 19 Nov 2002 09:07:52 -0800 (PST)") References: <20021119170752.96503.qmail@web20208.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > When linking my Boost.Python V2 extension modules with gcc 3.2 under Linux 7.3 > and 8.0 I have to wait up to 10 minutes per link command to finish. gcc <= > 3.0.4 never had this problem. The machine does not run out of core memory when > linking with 3.2, but uses 99% of a CPU all the time. Do others have similar > observations, or is it just me doing something stupid? Is this new? I've never observed this before. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From BPettersen at NAREX.com Tue Nov 19 18:19:12 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Tue, 19 Nov 2002 10:19:12 -0700 Subject: [C++-sig] Problem with vc++ 7 Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD738@admin56.narex.com> > From: David Abrahams [mailto:dave at boost-consulting.com] > > "Bjorn Pettersen" writes: > > >> From: Paul F. Kunz [mailto:Paul_Kunz at SLAC.Stanford.EDU] > >> > >> Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. > >> > >> My Python extension module fails to intialize. > > [...] > > > > A number of incompatibilities between Python built with VC6 and > > extensions built with VC7 has been reported due to different run-time > > libraries. The Python developers are aware of this, however they're > > unlikely to move to VC7 until at least some of the most common > > extensions are ported. (Besides, they don't have a VC7 optimizing > > compiler yet, which makes it kind of difficult ;-) You can always > > compile Python with VC7 yourself, although you'll probably have to get > > some files from cvs... > > FWIW I have never had any problems testing Boost extensions > built with VC7 against a vc6 build of Python. Thanks for that info, it could potentially make my life a lot easier . Looking over my emails again it seems the problem was with Python built with VC7 and extensions built with VC6. Martin von Loewis and Thomas Heller both reported crashes in this scenario. Tim Peters is also intimately involved with this issue, so if anyone has any insight it might be worth it to report it to PythonDev... -- bjorn From greglandrum at mindspring.com Tue Nov 19 18:24:11 2002 From: greglandrum at mindspring.com (greg Landrum) Date: Tue, 19 Nov 2002 09:24:11 -0800 Subject: [C++-sig] Slow gcc 3.2 links In-Reply-To: <20021119170752.96503.qmail@web20208.mail.yahoo.com> Message-ID: <5.1.0.14.2.20021119092122.01bab0c8@mail.mindspring.com> At 09:07 AM 11/19/2002, Ralf W. Grosse-Kunstleve wrote: >When linking my Boost.Python V2 extension modules with gcc 3.2 under Linux 7.3 >and 8.0 I have to wait up to 10 minutes per link command to finish. gcc <= >3.0.4 never had this problem. The machine does not run out of core memory when >linking with 3.2, but uses 99% of a CPU all the time. Do others have similar >observations, or is it just me doing something stupid? I've also noticed both long link times and big memory use (>200MB) using BPLv2 and g++ 3.2 under RH8.0 (mmm, alphanumeric soup). Of course, I could also be playing in the "something stupid" pool. However, since I haven't done a build using BPLv1 recently, I'm not sure this is BPLv2 specific. -greg From rwgk at yahoo.com Tue Nov 19 18:47:10 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 19 Nov 2002 09:47:10 -0800 (PST) Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: Message-ID: <20021119174710.80970.qmail@web20206.mail.yahoo.com> --- David Abrahams wrote: > "Bjorn Pettersen" writes: > > >> From: Paul F. Kunz [mailto:Paul_Kunz at SLAC.Stanford.EDU] > >> > >> Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. > >> > >> My Python extension module fails to intialize. > > [...] > > > > A number of incompatibilities between Python built with VC6 and > > extensions built with VC7 has been reported due to different run-time > > libraries. The Python developers are aware of this, however they're > > unlikely to move to VC7 until at least some of the most common > > extensions are ported. (Besides, they don't have a VC7 optimizing > > compiler yet, which makes it kind of difficult ;-) You can always > > compile Python with VC7 yourself, although you'll probably have to get > > some files from cvs... > > FWIW I have never had any problems testing Boost extensions built with > VC7 against a vc6 build of Python. FWIW2, we have quite a complex system now with >20 extension modules. There are all kinds of little nasty problems on all kinds of platforms, except our VC7 build which has been rock solid (once we got past the notorious ICE and internal structure overflows). But our experience is limited a bit because we only have the non-optimizing VC7 edition. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From mike at bindkey.com Tue Nov 19 19:42:40 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 19 Nov 2002 10:42:40 -0800 Subject: [C++-sig] Re: gcc-3.0.4, SunOS import module error References: Message-ID: > I'm having trouble reflecting inheritance hierarchies with gcc 3.0.4 on > SunOS 5.8. I stopped using 3.0.4 and moved to 3.2 due to numerous compiler errors. From mike at bindkey.com Tue Nov 19 20:10:52 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 19 Nov 2002 11:10:52 -0800 Subject: [C++-sig] abstract base class Message-ID: I have a pure virtual base class: class LayerOperation { public: virtual ~LayerOperation(void); virtual LayerOperation* Clone(void) const = 0; virtual void GetInvolvedLayers(LayerList* pLayers) const = 0; }; When I try to wrap it class_("Operation", no_init); // line 169 in order to use as base for real class class_ >("SET", init()); I get an error: PyTcn.cpp:169: instantiated from here /boost_1_29_0/boost/python/object/value_holder.hpp:36: cannot declare field ` boost::python::objects::value_holder::m_held' to be of type `Tcn::LayerOperation' /boost_1_29_0/boost/python/object/value_holder.hpp:36: because the following virtual functions are abstract: /src/Technology/TcnLayerOperation.h:43: virtual void Tcn::LayerOperation::GetInvolvedLayers(Tcn::LayerList*) const /src/Technology/TcnLayerOperation.h:38: virtual Tcn::LayerOperation* Tcn::LayerOperation::Clone() const What I'm doing wrong? Thanks, Mike From n_lelong at hotmail.com Tue Nov 19 20:27:03 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Tue, 19 Nov 2002 20:27:03 +0100 Subject: [C++-sig] abstract base class References: Message-ID: Hi > [...] > class_("Operation", no_init); // line 169 You should try : class_("Operation", no_init); It works for me :) Hope this helps, Nicolas. From mike at bindkey.com Tue Nov 19 21:14:44 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 19 Nov 2002 12:14:44 -0800 Subject: [C++-sig] Re: abstract base class References: Message-ID: "Nicolas Lelong" wrote in message news:DAV39n1YcEBdyFj9ZYh00008290 at hotmail.com... > Hi > > > [...] > > class_("Operation", no_init); // line 169 > > You should try : > > class_("Operation", no_init); > > It works for me :) > > Hope this helps, Thank you. That works for me too ;) But I'm curious (a) why that happened? (b) error message is inadequate. Truly yours, Mike From achim.domma at syynx.de Tue Nov 19 21:38:40 2002 From: achim.domma at syynx.de (Achim Domma) Date: Tue, 19 Nov 2002 21:38:40 +0100 Subject: [C++-sig] container_conversions.h with VC7 In-Reply-To: <20021118234634.40507.qmail@web20202.mail.yahoo.com> Message-ID: > What happens if you take out the optimization flags? The debug version compiles without problems. I will investigate the problem further, but I will be on holiday next week, so you might hear from me in about 2 weeks. Achim From mike at bindkey.com Tue Nov 19 21:59:13 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 19 Nov 2002 12:59:13 -0800 Subject: [C++-sig] debuging Message-ID: Howdy, folks. How do you debug BPL applications? I just got 'TypeError: bad argument type for built-in operation' and have absolutely no idea what to do next. Best wishes, Mike From BPettersen at NAREX.com Tue Nov 19 22:28:01 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Tue, 19 Nov 2002 14:28:01 -0700 Subject: [C++-sig] debuging Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD75F@admin56.narex.com> > From: Mike Rovner [mailto:mike at bindkey.com] > > Howdy, folks. > > How do you debug BPL applications? > > I just got 'TypeError: bad argument type for built-in > operation' and have absolutely no idea what to do next. Sounds like you need to get the traceback... Here's how I do it (you'll probably want to modify it to throw a more standard exception ;-) -- bjorn std::string getTraceback() { std::string result; PyObject *exception, *v, *traceback; PyErr_Fetch(&exception, &v, &traceback); PyErr_NormalizeException(&exception, &v, &traceback); /* import traceback lst = traceback.format_exception(exception, v, traceback) for line in lst: result += line */ PyObject* tbstr = PyString_FromString("traceback"); PyObject* tbmod = PyImport_Import(tbstr); if (!tbmod) throw new NException("Unable to import traceback module. Is your Python installed?", N_EX_NULL); PyObject* tbdict = PyModule_GetDict(tbmod); PyObject* formatFunc = PyDict_GetItemString(tbdict, "format_exception"); if (!formatFunc) throw new NException("Can't find traceback.format_exception", N_EX_NULL); if (!traceback) { traceback = Py_None; Py_INCREF(Py_None); } PyObject* args = Py_BuildValue("(OOO)", exception, v, traceback); PyObject* lst = PyObject_CallObject(formatFunc, args); for (int i=0; i Message-ID: "Bjorn Pettersen" wrote in message > I just got 'TypeError: bad argument type for built-in > operation' and have absolutely no idea what to do next. Sounds like you need to get the traceback... Here's how I do it (you'll probably want to modify it to throw a more standard exception ;-) -- bjorn Thank you for the code. Apparently I'm still sleepy 'cause I don't know how to use it. Let me start from the beginning: I wrapped cpp class and instantiated it from python. When I tried it's method I got: >>> import My >>> a=My.Obj('a') >>> a # faked >>> a.name Traceback (most recent call last): File "", line 1, in ? TypeError: bad argument type for built-in operation I certainly would like to have cpp traceback through BPL library code (I'm using debug version) but I don't know how. I feel like having a key to the chamber with gold but see no lock around, only walls. ;) Please guide me a couple steps further. Mike From rwgk at yahoo.com Tue Nov 19 23:28:15 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 19 Nov 2002 14:28:15 -0800 (PST) Subject: [C++-sig] Re: debuging In-Reply-To: Message-ID: <20021119222815.41802.qmail@web20206.mail.yahoo.com> --- Mike Rovner wrote: > >>> a.name > Traceback (most recent call last): > File "", line 1, in ? > TypeError: bad argument type for built-in operation > > I certainly would like to have cpp traceback through BPL library code (I'm > using debug version) but I don't know how. I have doubts that the C++ traceback will help very much. I normally solve these problems by staring at the function signature for a moment. If you are using more than one extension module, also consider if you need to load any other modules in order to have the required converters registered. For your entertainment: if it gets more involved (i.e. if there are real bugs) I resort to print statements. Clearly very low tech, but incredibly portable. Ralf BTW: It would be nice if Boost.Python gave a more specific error message as it did in version 1, but then there is to problem with gcc's (and other compilers?) mangled names. We need a volunteer with enough time to address this issue... __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From mike at bindkey.com Tue Nov 19 23:42:21 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 19 Nov 2002 14:42:21 -0800 Subject: [C++-sig] Re: Re: debuging References: <20021119222815.41802.qmail@web20206.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" wrote in message news:20021119222815.41802.qmail at web20206.mail.yahoo.com... > --- Mike Rovner wrote: > > >>> a.name > > Traceback (most recent call last): > > File "", line 1, in ? > > TypeError: bad argument type for built-in operation > > > > I certainly would like to have cpp traceback through BPL library code (I'm > > using debug version) but I don't know how. > > I have doubts that the C++ traceback will help very much. I normally solve > these problems by staring at the function signature for a moment. If you are > using more than one extension module, also consider if you need to load any > other modules in order to have the required converters registered. Nope. One module. (strarring..........................................................;) I vaguly recall that probably one error was fixed in cvs regarding that. I have struct X { std::string Name() { return name;} private: std::string name; }; struct Obj : X { ... }; class_("Obj").add_property("name", &Obj::Name); and in that case I have to cast Obj::Name to something as workaround. Can't find it. :( But I have several such places and wondered about generic technique. > BTW: It would be nice if Boost.Python gave a more specific error message as it > did in version 1, but then there is to problem with gcc's (and other > compilers?) mangled names. We need a volunteer with enough time to address this > issue... What is the problem? Write the demangler? Can you explain it a little, please? Regards, Mike From dave at boost-consulting.com Tue Nov 19 23:55:25 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 17:55:25 -0500 Subject: [C++-sig] Re: debuging In-Reply-To: <20021119222815.41802.qmail@web20206.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Tue, 19 Nov 2002 14:28:15 -0800 (PST)") References: <20021119222815.41802.qmail@web20206.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- Mike Rovner wrote: >> >>> a.name >> Traceback (most recent call last): >> File "", line 1, in ? >> TypeError: bad argument type for built-in operation >> >> I certainly would like to have cpp traceback through BPL library code (I'm >> using debug version) but I don't know how. > > I have doubts that the C++ traceback will help very much. Well, it's actually a Python traceback that Bjorn is collecting, and converting to a std::string... but I agree with you that it probably won't help very much. > I normally solve these problems by staring at the function signature > for a moment. If you are using more than one extension module, also > consider if you need to load any other modules in order to have the > required converters registered. > > For your entertainment: if it gets more involved (i.e. if there are > real bugs) I resort to print statements. Clearly very low tech, but > incredibly portable. > > Ralf > > BTW: It would be nice if Boost.Python gave a more specific error > message as it did in version 1, but then there is to problem with > gcc's (and other compilers?) mangled names. We need a volunteer with > enough time to address this issue... ...or funding for Boost Consulting to work on it... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 20 00:05:13 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 18:05:13 -0500 Subject: [C++-sig] Re: Re: debuging In-Reply-To: ("Mike Rovner"'s message of "Tue, 19 Nov 2002 14:42:21 -0800") References: <20021119222815.41802.qmail@web20206.mail.yahoo.com> Message-ID: "Mike Rovner" writes: > Nope. One module. > (strarring..........................................................;) > I vaguly recall that probably one error was fixed in cvs regarding that. > I have > > struct X { > std::string Name() { return name;} > private: > std::string name; > }; > > struct Obj : X { ... }; > > class_("Obj").add_property("name", &Obj::Name); > > and in that case I have to cast Obj::Name to something as workaround. Can't > find it. :( Yeah, you either need to expose X and make it a base of Obj, or cast: (std::string (Obj::*)())&Obj::Name > But I have several such places and wondered about generic technique. I think Boost.Python should handle this for you, though ;-/ >> BTW: It would be nice if Boost.Python gave a more specific error message > as it >> did in version 1, but then there is to problem with gcc's (and other >> compilers?) mangled names. We need a volunteer with enough time to address > this >> issue... > > What is the problem? Write the demangler? Can you explain it a > little, please? That's part of it. See: http://mail.python.org/pipermail/c++-sig/2002-June/001277.html Of course, we also need some code to build error messages... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Wed Nov 20 00:47:09 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 19 Nov 2002 15:47:09 -0800 (PST) Subject: [C++-sig] Slow gcc 3.2 links In-Reply-To: Message-ID: <20021119234709.51837.qmail@web20204.mail.yahoo.com> --- David Abrahams wrote: > "Ralf W. Grosse-Kunstleve" writes: > > > When linking my Boost.Python V2 extension modules with gcc 3.2 under Linux > 7.3 > > and 8.0 I have to wait up to 10 minutes per link command to finish. gcc <= > > 3.0.4 never had this problem. The machine does not run out of core memory > when > > linking with 3.2, but uses 99% of a CPU all the time. Do others have > similar > > observations, or is it just me doing something stupid? > > Is this new? I've never observed this before. I just started with gcc 3.2, so I cannot be sure if it is new. Luckily, the slowness disappears when I switch from using -g to using -O3. Ralf From burley at tabq.com.au Wed Nov 20 02:15:40 2002 From: burley at tabq.com.au (Greg Burley) Date: 20 Nov 2002 11:15:40 +1000 Subject: [C++-sig] Re: debuging In-Reply-To: References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD75F@admin56.narex.com> Message-ID: Hi Mike, What's wrong with using gdb and stepping through your code. See notes that follow ... Debugging BPL Extensions ======================== Once you have created a boost python extension for your c++ library or class, you may need to debug the code. Afterall this is one of the reasons for wrapping the library in python. An expected side-effect or benefit of using BPL is that debugging should be isolated to the c++ library that is under test, given that python code is minimal and boost::python either works or it doesn't. (ie. While errors can occur when the wrapping method is invalid, most errors are caught by the compiler ;-). The basic steps required to initiate a gdb session to debug a c++ library via python are shown here. Note, however that you should start the gdb session in the directory that contains your BPL my_ext.so module. (gdb) target exec python (gdb) run >>> from my_ext import * >>> [C-c] (gdb) break MyClass::MyBuggyFunction (gdb) cont >>> pyobj = MyClass() >>> pyobj.MyBuggyFunction() Breakpoint 1, MyClass::MyBuggyFunction ... Current language: auto; currently c++ (gdb) do debugging stuff hope this helps, greg "Mike Rovner" writes: > "Bjorn Pettersen" wrote in message > > > I just got 'TypeError: bad argument type for built-in > > operation' and have absolutely no idea what to do next. > > Sounds like you need to get the traceback... Here's how I do it (you'll > probably want to modify it to throw a more standard exception ;-) > > -- bjorn > > Thank you for the code. > Apparently I'm still sleepy 'cause I don't know how to use it. > > Let me start from the beginning: > > I wrapped cpp class and instantiated it from python. > When I tried it's method I got: > >>> import My > >>> a=My.Obj('a') > >>> a > # faked > >>> a.name > Traceback (most recent call last): > File "", line 1, in ? > TypeError: bad argument type for built-in operation > > I certainly would like to have cpp traceback through BPL library code (I'm > using debug version) but I don't know how. > I feel like having a key to the chamber with gold but see no lock around, > only walls. ;) > Please guide me a couple steps further. > > Mike > > > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From dave at boost-consulting.com Wed Nov 20 02:24:59 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 19 Nov 2002 20:24:59 -0500 Subject: [C++-sig] Re: Re: debuging In-Reply-To: (David Abrahams's message of "Tue, 19 Nov 2002 18:05:13 -0500") References: <20021119222815.41802.qmail@web20206.mail.yahoo.com> Message-ID: David Abrahams writes: > "Mike Rovner" writes: >> struct X { >> std::string Name() { return name;} >> private: >> std::string name; >> }; >> >> struct Obj : X { ... }; >> >> class_("Obj").add_property("name", &Obj::Name); >> >> and in that case I have to cast Obj::Name to something as workaround. Can't >> find it. :( > > Yeah, you either need to expose X and make it a base of Obj, or cast: > > (std::string (Obj::*)())&Obj::Name > >> But I have several such places and wondered about generic technique. > > I think Boost.Python should handle this for you, though ;-/ ...and now it does. See the latest CVS. We still desperately need someone to work on or fund better runtime error messages. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Wed Nov 20 04:32:07 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Tue, 19 Nov 2002 19:32:07 -0800 Subject: [C++-sig] problems with lvalue_from_pytype Message-ID: I have modified the noddy example from the python docs to store a magic number. I am trying to build a wrapper that will convert the magic number of the noddy object to a win32 hwnd and back. So from python I want to following behavior: magicSt is a structure that has an HWND member magicnum >> import noddy, cn >> n = noddy.noddy() >> m = cn.magicSt() >> m.magicnum = n >> print m.magicnum 453311 >> In c++ magicnum would be an HWND. The following compiles and I can get the magicnum but when I try to set it I get:: TypeError: bad agrument type fro built-in operation. I have a version of this that just converts the magic number to long and this works just fine. What am I missing?? Many thanks in advance. --Mark #include #include using namespace boost::python; //declarations extern "C" _declspec(dllimport) PyTypeObject noddy_NoddyType; typedef struct { PyObject_HEAD long magicNum; } noddy_NoddyObject; //magic structure typedef struct _magic { HWND magicnum; } magicSt; //converters struct HWND_PyInt { static PyObject* convert(const HWND& h) { return PyInt_FromLong((long) h); } }; struct convertNoddy { static HWND& execute(PyObject& o) { static long magic = call_method(&o, "getMagicNum"); static HWND hmagic = reinterpret_cast(magic); return hmagic; } }; BOOST_PYTHON_MODULE(cn) { lvalue_from_pytype(); to_python_converter(); class_("magicSt") .def_readwrite("magicnum", &magicSt::magicnum); } From hupp at cs.wisc.edu Wed Nov 20 04:34:34 2002 From: hupp at cs.wisc.edu (Adam Hupp) Date: Tue, 19 Nov 2002 21:34:34 -0600 Subject: [C++-sig] Re: Re: debuging In-Reply-To: References: <20021119222815.41802.qmail@web20206.mail.yahoo.com> Message-ID: <20021120033434.GA31687@upl.cs.wisc.edu> On Tue, Nov 19, 2002 at 06:05:13PM -0500, David Abrahams wrote: > > > > What is the problem? Write the demangler? Can you explain it a > > little, please? > > That's part of it. See: > > http://mail.python.org/pipermail/c++-sig/2002-June/001277.html Unless I'm missing something, with g++ >= 3.1 you can use abi::__cxa_demangle to do this. Attached is an example. Docs can be found at http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.2/namespaceabi.html -Adam -------------- next part -------------- #include #include #include #include #include #include using namespace boost; using namespace std; ostream& operator<<(ostream& os, const python::type_info& type) { int status; char* demangle = abi::__cxa_demangle(type.name(), 0, 0, &status); if(status == 0) { os << demangle; free(demangle); } else if(status == -2) os << "Error: " << type.name() << " is not a valid name under the C++ ABI mangling rules"; else if(status == -1) throw bad_alloc(); return os; } void printType(const python::type_info& type) { cout << type.name() << " => "; ::operator<<(cout, type) << endl; } void test() { const char* b; printType(python::type_info(typeid(b))); vector c; printType(python::type_info(typeid(c))); printType(python::type_info(typeid(&printType))); } BOOST_PYTHON_MODULE(test_debug) { python::def("test", &test); } From Peter.Bienstman at rug.ac.be Wed Nov 20 11:42:58 2002 From: Peter.Bienstman at rug.ac.be (Peter Bienstman) Date: Wed, 20 Nov 2002 11:42:58 +0100 Subject: [C++-sig] Wrapping multiple class_ objects Message-ID: <200211201142.58482.Peter.Bienstman@rug.ac.be> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, I'm trying to wrap a class and two specific instances of it: class_ > ("SlabWallMixed", init()); object slab_E_wall = (class_ > ("slab_E_wall", init()))(1.0,1.0); object slab_H_wall = (class_ > ("slab_H_wall", init()))(1.0,-1.0); Any of these statements by themselves work fine, but if I combine two or more, I get: RuntimeError: trying to register to_python_converter for a type which already has a registered to_python_converter Did I get the syntax wrong or is this currenty impossible? Thanks! Peter - -- - ------------------------------------------------ Peter Bienstman Ghent University, Dep. of Information Technology Sint-Pietersnieuwstraat 41, B-9000 Gent, Belgium tel: +32 9 264 34 45, fax: +32 9 264 35 93 email: Peter.Bienstman at rug.ac.be - ------------------------------------------------ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE922cy4dgPAIjyquoRAsAeAJ9KNuBGfXLzdh58ez3LzGi6WbP+0wCfRNEA h1A6VuMjbERh2aYqvM7XCRc= =k0Wz -----END PGP SIGNATURE----- From warkid at hotbox.ru Wed Nov 20 11:03:34 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Wed, 20 Nov 2002 13:03:34 +0300 Subject: [C++-sig] multiple files linker error Message-ID: <19392232218.20021120130334@hotbox.ru> Hello c++-sig, I'm spliting to multiple files my bpl code of an extension and getting this linker error message: ''' error LNK2005: "struct swallow_assign::boost::detail::swallow_assign boost::tuples::`anonymous namespace'::ignore" (?ignore@?A0xdb06aef3 at tuples@boost@@3Uswallow_assign at detail@23 at A) already defined in ... ''' Alas I am not able to reproduce it for simpple examples. Any ideas why could it happen? Best regards, Kerim mailto:warkid at hotbox.ru From warkid at hotbox.ru Mon Nov 18 18:11:58 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Mon, 18 Nov 2002 20:11:58 +0300 Subject: [C++-sig] Passing C++ arrays as arguments Message-ID: <194252432218.20021118201158@hotbox.ru> Hello. I'm exposing to Python some third party library wich has an API like this: struct Abstract{ virtual void f(float[16])=0; }; Abstract *createInstance(); with this code: def("createInstance", createInstance, return_value_policy()); class_("Abstract", no_init) .def("f", Abstract::f); Can I simply define some from python tuple to float[16] converter so that I can call object returned from createInstance like this: createInstance().f((0,)*16) ? Best regards, Kerim mailto:warkid at hotbox.ru From Peter.Bienstman at rug.ac.be Wed Nov 20 13:59:20 2002 From: Peter.Bienstman at rug.ac.be (Peter Bienstman) Date: Wed, 20 Nov 2002 13:59:20 +0100 Subject: [C++-sig] class functions with default arguments Message-ID: <200211201359.20557.Peter.Bienstman@rug.ac.be> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, The BOOST_PYTHON_FUNCTION_OVERLOADS mechanism works great for handling the default arguments of freestanding functions, but is the same mechanism supposed to work for class member functions? It seems to generate functions where the 'this' argument is mentioned explicitly in the argument list, and that causes compile-time problems. Thanks! Peter - -- - ------------------------------------------------ Peter Bienstman Ghent University, Dep. of Information Technology Sint-Pietersnieuwstraat 41, B-9000 Gent, Belgium tel: +32 9 264 34 45, fax: +32 9 264 35 93 email: Peter.Bienstman at rug.ac.be - ------------------------------------------------ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE924co4dgPAIjyquoRAvEGAJ9XWP8ftJVSEoUzOubfuoctR8yHPwCg01kT XVCyEzBFcb+SQXcVxuoSZKo= =Vqjs -----END PGP SIGNATURE----- From dave at boost-consulting.com Wed Nov 20 14:02:03 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 08:02:03 -0500 Subject: [C++-sig] Wrapping multiple class_ objects In-Reply-To: <200211201142.58482.Peter.Bienstman@rug.ac.be> (Peter Bienstman's message of "Wed, 20 Nov 2002 11:42:58 +0100") References: <200211201142.58482.Peter.Bienstman@rug.ac.be> Message-ID: Peter Bienstman writes: > Hello, > > I'm trying to wrap a class and two specific instances of it: > > class_ > > ("SlabWallMixed", init()); > > object slab_E_wall > = (class_ > > ("slab_E_wall", init()))(1.0,1.0); > > object slab_H_wall > = (class_ > > ("slab_H_wall", init()))(1.0,-1.0); > > Any of these statements by themselves work fine, but if I combine two or more, > I get: > > RuntimeError: trying to register to_python_converter for a type which already > has a registered to_python_converter > > Did I get the syntax wrong or is this currenty impossible? There are lots of ways to write this so you don't instantiate the same class_<> twice. One is: object slabwallmixed = class_ > ("SlabWallMixed", init()); object slab_E_wall = slabwallmixed(1.0,1.0); object slab_H_wall = slabwallmixed(1.0,-1.0); -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 20 14:11:11 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 08:11:11 -0500 Subject: [C++-sig] multiple files linker error In-Reply-To: <19392232218.20021120130334@hotbox.ru> (Kerim Borchaev's message of "Wed, 20 Nov 2002 13:03:34 +0300") References: <19392232218.20021120130334@hotbox.ru> Message-ID: Kerim Borchaev writes: > Hello c++-sig, > > I'm spliting to multiple files my bpl code of an extension and getting > this linker error message: > > ''' > error LNK2005: "struct swallow_assign::boost::detail::swallow_assign > boost::tuples::`anonymous namespace'::ignore" > (?ignore@?A0xdb06aef3 at tuples@boost@@3Uswallow_assign at detail@23 at A) > already defined in ... > ''' > > Alas I am not able to reproduce it for simpple examples. > Any ideas why could it happen? Yeah. Please try checking out the latest boost/tuple/detail/tuple_basic_no_partial_spec.hpp from CVS and see if that fixes your problem -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Shayne.FLETCHER at rbos.com Wed Nov 20 14:25:39 2002 From: Shayne.FLETCHER at rbos.com (FLETCHER, Shayne, FM) Date: Wed, 20 Nov 2002 13:25:39 -0000 Subject: [C++-sig] Re: gcc-3.0.4, SunOS import module error Message-ID: >> Hi all: >> >> I'm having trouble reflecting inheritance hierarchies with gcc 3.0.4 on >> SunOS 5.8. >> Basically, a module like: >> >> struct bar{}; >> struct baz{}; >> struct foo : bar, baz {}; >> >> BOOST_PYTHON_MODULE(test_derivation) >> { >> class_("bar") >> ; >> class_("baz") >> ; >> class_ >("foo") >> ; >> } >> >> gives a bus error when the module is loaded from the interpreter >try > > bjam -sTOOLS=gcc -sPYTHON_TEST_ARGS=-v -n -a test > >to see what commands it's executing. You may be missing something >important when you try to build/run "by hand". Thanks, your advice has helped. Loading "by hand" was picking up the release build of libboost_python.so. Linking with that causes the bus error. - Shayne. *********************************************************************** Visit our Internet site at http://www.rbsmarkets.com This e-mail is intended only for the addressee named above. As this e-mail may contain confidential or privileged information, if you are not the named addressee, you are not authorised to retain, read, copy or disseminate this message or any part of it. The Royal Bank of Scotland plc is registered in Scotland No 90312 Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB Regulated by the Financial Services Authority *********************************************************************** From Peter.Bienstman at rug.ac.be Wed Nov 20 14:31:57 2002 From: Peter.Bienstman at rug.ac.be (Peter Bienstman) Date: Wed, 20 Nov 2002 14:31:57 +0100 Subject: [C++-sig] Wrapping multiple class_ objects In-Reply-To: References: <200211201142.58482.Peter.Bienstman@rug.ac.be> Message-ID: <200211201431.57704.Peter.Bienstman@rug.ac.be> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 20 November 2002 14:02, David Abrahams wrote: > There are lots of ways to write this so you don't instantiate the same > class_<> twice. One is: > > object slabwallmixed > = class_ > > ("SlabWallMixed", init()); > > object slab_E_wall = slabwallmixed(1.0,1.0); > object slab_H_wall = slabwallmixed(1.0,-1.0); Cool! But are these objects only for C++ internal use, or can I export them to Python? def("slab_E_wall", slab_E_wall) won't compile. Peter - -- - ------------------------------------------------ Peter Bienstman Ghent University, Dep. of Information Technology Sint-Pietersnieuwstraat 41, B-9000 Gent, Belgium tel: +32 9 264 34 45, fax: +32 9 264 35 93 email: Peter.Bienstman at rug.ac.be - ------------------------------------------------ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9247N4dgPAIjyquoRApANAKD1HJlALdgkx2sR3bI0Bhf4NGFhBgCfbfYE 05qULPbixzSo3v2dkgxLGXA= =GIf3 -----END PGP SIGNATURE----- From dave at boost-consulting.com Wed Nov 20 14:28:13 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 08:28:13 -0500 Subject: [C++-sig] Wrapping multiple class_ objects In-Reply-To: <200211201431.57704.Peter.Bienstman@rug.ac.be> (Peter Bienstman's message of "Wed, 20 Nov 2002 14:31:57 +0100") References: <200211201142.58482.Peter.Bienstman@rug.ac.be> <200211201431.57704.Peter.Bienstman@rug.ac.be> Message-ID: Peter Bienstman writes: > On Wednesday 20 November 2002 14:02, David Abrahams wrote: > >> There are lots of ways to write this so you don't instantiate the same >> class_<> twice. One is: >> >> object slabwallmixed >> = class_ > >> ("SlabWallMixed", init()); >> >> object slab_E_wall = slabwallmixed(1.0,1.0); >> object slab_H_wall = slabwallmixed(1.0,-1.0); > > Cool! But are these objects only for C++ internal use, or can I export them to > Python? > > def("slab_E_wall", slab_E_wall) > > won't compile. What do you think it's supposed to do? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 20 14:30:51 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 08:30:51 -0500 Subject: [C++-sig] Re: gcc-3.0.4, SunOS import module error In-Reply-To: ("Mike Rovner"'s message of "Tue, 19 Nov 2002 10:42:40 -0800") References: Message-ID: "Mike Rovner" writes: >> I'm having trouble reflecting inheritance hierarchies with gcc 3.0.4 on >> SunOS 5.8. > > I stopped using 3.0.4 and moved to 3.2 due to numerous compiler errors. Works fine for Boost.Python, though: http://cci.lbl.gov/boost/results/1037786401/dailylog_unix_gcc_test -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Peter.Bienstman at rug.ac.be Wed Nov 20 14:45:39 2002 From: Peter.Bienstman at rug.ac.be (Peter Bienstman) Date: Wed, 20 Nov 2002 14:45:39 +0100 Subject: [C++-sig] Wrapping multiple class_ objects In-Reply-To: References: <200211201142.58482.Peter.Bienstman@rug.ac.be> <200211201431.57704.Peter.Bienstman@rug.ac.be> Message-ID: <200211201445.39569.Peter.Bienstman@rug.ac.be> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 20 November 2002 14:28, David Abrahams wrote: > Peter Bienstman writes: > > On Wednesday 20 November 2002 14:02, David Abrahams wrote: > >> There are lots of ways to write this so you don't instantiate the same > >> class_<> twice. One is: > >> > >> object slabwallmixed > >> = class_ > > >> ("SlabWallMixed", init()); > >> > >> object slab_E_wall = slabwallmixed(1.0,1.0); > >> object slab_H_wall = slabwallmixed(1.0,-1.0); > > > > Cool! But are these objects only for C++ internal use, or can I export > > them to Python? > > > > def("slab_E_wall", slab_E_wall) > > > > won't compile. > > What do you think it's supposed to do? Perhaps I misunderstand the use of 'object', but I want to create C++ objects and have them accessible through an identifier in Python. This is the compile error message: /home/pbienst/boost_1_29_0/boost/python/make_function.hpp: In function `boost::python::api::object boost::python::make_function(F) [with F = boost::python::api::object]': /home/pbienst/boost_1_29_0/boost/python/def.hpp:78: instantiated from `void boost::python::def(const char*, Fn) [with Fn = boost::python::api::object]' camfr/camfr_wrap.cpp:1010: instantiated from here /home/pbienst/boost_1_29_0/boost/python/make_function.hpp:23: incomplete type ` boost::python::detail::arg_tuple_size' does not have member `value' Thanks! Peter - -- - ------------------------------------------------ Peter Bienstman Ghent University, Dep. of Information Technology Sint-Pietersnieuwstraat 41, B-9000 Gent, Belgium tel: +32 9 264 34 45, fax: +32 9 264 35 93 email: Peter.Bienstman at rug.ac.be - ------------------------------------------------ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE925ID4dgPAIjyquoRAi4jAKCQ6Kp8ieEaNbwYTPPSc7A0v4OUNwCeOln4 pbtxBOYTtJoQMesmidnMMzw= =KHCj -----END PGP SIGNATURE----- From dave at boost-consulting.com Wed Nov 20 15:01:30 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 09:01:30 -0500 Subject: [C++-sig] Wrapping multiple class_ objects In-Reply-To: <200211201445.39569.Peter.Bienstman@rug.ac.be> (Peter Bienstman's message of "Wed, 20 Nov 2002 14:45:39 +0100") References: <200211201142.58482.Peter.Bienstman@rug.ac.be> <200211201431.57704.Peter.Bienstman@rug.ac.be> <200211201445.39569.Peter.Bienstman@rug.ac.be> Message-ID: Peter Bienstman writes: > On Wednesday 20 November 2002 14:28, David Abrahams wrote: >> Peter Bienstman writes: >> > On Wednesday 20 November 2002 14:02, David Abrahams wrote: >> >> There are lots of ways to write this so you don't instantiate the same >> >> class_<> twice. One is: >> >> >> >> object slabwallmixed >> >> = class_ > >> >> ("SlabWallMixed", init()); >> >> >> >> object slab_E_wall = slabwallmixed(1.0,1.0); >> >> object slab_H_wall = slabwallmixed(1.0,-1.0); >> > >> > Cool! But are these objects only for C++ internal use, or can I export >> > them to Python? >> > >> > def("slab_E_wall", slab_E_wall) >> > >> > won't compile. >> >> What do you think it's supposed to do? > > Perhaps I misunderstand the use of 'object', You misunderstand the use of def(). Please read about scope here http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/scope.html http://www.python.org/cgi-bin/moinmoin/boost_2epython_2fmodule -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From warkid at hotbox.ru Wed Nov 20 17:18:31 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Wed, 20 Nov 2002 19:18:31 +0300 Subject: [C++-sig] multiple files linker error In-Reply-To: References: <19392232218.20021120130334@hotbox.ru> Message-ID: <149114730156.20021120191831@hotbox.ru> Hello David, yes. it worked out. thanks. Best regards, Kerim mailto:warkid at hotbox.ru Wednesday, November 20, 2002, 4:11:11 PM, you wrote: DA> Kerim Borchaev writes: >> Hello c++-sig, >> >> I'm spliting to multiple files my bpl code of an extension and getting >> this linker error message: >> >> ''' >> error LNK2005: "struct swallow_assign::boost::detail::swallow_assign >> boost::tuples::`anonymous namespace'::ignore" >> (?ignore@?A0xdb06aef3 at tuples@boost@@3Uswallow_assign at detail@23 at A) >> already defined in ... >> ''' >> >> Alas I am not able to reproduce it for simpple examples. >> Any ideas why could it happen? DA> Yeah. Please try checking out the latest DA> boost/tuple/detail/tuple_basic_no_partial_spec.hpp DA> from CVS and see if that fixes your problem From rwgk at yahoo.com Wed Nov 20 19:17:22 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 20 Nov 2002 10:17:22 -0800 (PST) Subject: [C++-sig] class functions with default arguments In-Reply-To: <200211201359.20557.Peter.Bienstman@rug.ac.be> Message-ID: <20021120181722.68446.qmail@web20206.mail.yahoo.com> --- Peter Bienstman wrote: > The BOOST_PYTHON_FUNCTION_OVERLOADS mechanism works great for handling the > default arguments of freestanding functions, but is the same mechanism > supposed to work for class member functions? It seems to generate functions > where the 'this' argument is mentioned explicitly in the argument list, and > that causes compile-time problems. For member functions you have to use the BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS macro. I never had any issues with this using a variety of platforms. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Web Hosting - Let the expert host your site http://webhosting.yahoo.com From mike at bindkey.com Wed Nov 20 20:18:35 2002 From: mike at bindkey.com (Mike Rovner) Date: Wed, 20 Nov 2002 11:18:35 -0800 Subject: [C++-sig] Re: Wrapping multiple class_ objects References: <200211201142.58482.Peter.Bienstman@rug.ac.be> <200211201431.57704.Peter.Bienstman@rug.ac.be> Message-ID: "Peter Bienstman" wrote in message news:200211201431.57704.Peter.Bienstman at rug.ac.be... > There are lots of ways to write this so you don't instantiate the same > class_<> twice. One is: > > object slabwallmixed > = class_ > > ("SlabWallMixed", init()); > > object slab_E_wall = slabwallmixed(1.0,1.0); > object slab_H_wall = slabwallmixed(1.0,-1.0); Cool! But are these objects only for C++ internal use, or can I export them to Python? Sure. Add the following: scope().attr("slab_E_wall") = slab_E_wall; scope().attr("slab_H_wall") = slab_H_wall; Mike From patrick at vrac.iastate.edu Wed Nov 20 21:56:57 2002 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Wed, 20 Nov 2002 14:56:57 -0600 Subject: [C++-sig] Incrementing reference count of returned object pointer Message-ID: <3DDBF719.5010308@vrac.iastate.edu> I am having some difficulty using boost::python::call() to invoke a Python function that returns a pointer. I understand that the callback semantics cause an exception to be thrown if the reference count of the returned object is 1, so I am wondering how to increment the reference count. The code that receives the reference will be holding onto it, so of course I don't want it to be garbage collected. For some background, what I am working on involves an abstract base class written in C++ that will be extended using a derived Python class. I would like to be able to use Python-defined objects in C++ as though they were polymorphic instances of the base class (which they are--at least conceptually). My long-term goal is to be able to load Python modules on the fly that define a subclass of the abstract base class. To get a reference to an instance of the derived Python class, I want to have a factory function that simply returns the instance. This factory function would be called by the C++ code (via boost::python::call() or some other similarly friendly mechanism), and the result would be treated as a reference to the abstract base class. What this all boils down to is an interface defined in C++ that can be implemented in Python (or any language) where instances of the interface implementations will be used in C++. So, given a PyObject* factory_func that is the callable factory function, I want to do something like this: Base* obj = boost::python::call(factory_func); As I understand it, the need to deal with the reference counting means that my code can't be quite that simple. I have the Python module implemented to the point where I can write a Python application that instantiates the derived class and hands it off to the C++ code. The next step is having the C++ code request the derived class instance from a given module. I've done a little bit of searching around, and I saw a reference to boost::python::handle as a mechanism to deal with reference-counted Python objects. Is that the way to go, and if so, how do I use this class? The Boost.Python reference doesn't have an example, so I am not sure how to put it to use. -Patrick -- Patrick L. Hartling | Research Assistant, VRAC patrick at vrac.iastate.edu | 2624 Howe Hall: 1.515.294.4916 http://www.137.org/patrick/ | http://www.vrac.iastate.edu/ From ostiguy at fnal.gov Wed Nov 20 22:58:37 2002 From: ostiguy at fnal.gov (Francois Ostiguy) Date: Wed, 20 Nov 2002 15:58:37 -0600 (CST) Subject: [C++-sig] python namespace Message-ID: Hi - I am trying to do the following: suppose I have two functions f1 and f2. I would like to map those functions to two different python "module" namespaces i.e. outer.inner1.f1 outer.inner2.f2 So far all my attempts have failed. In particular, I tried the following recipe, suggested by Dave in an earlier message namespace python = boost::python; void f1() { std:: cout <<"f1" << std::endl; } void f2() { std:: cout <<"f2" << std::endl; } BOOST_PYTHON_MODULE(outer) { python::handle<> inner_module1( PyModule_New("outer.inner1")); python::scope inner_scope1 = object(inner_module1); python::def("f1", &f1); python::handle<> inner_module2( PyModule_New("outer.inner2")); python::scope inner_scope2 = object(inner_module2); python::def("f2", &f2); } It fails with the following message: namespace.cc: In function `void init_module_outer()': namespace.cc:29: non-lvalue in unary `&' namespace.cc:29: no match for call to `(boost::python::api::object) ( boost::python::handle&)' /usr/local/ap/include/boost/python/object_core.hpp:101: candidates are: boost::python::api::object boost::python::api::object_operators::operator()() const [with U = boost::python::api::object] /usr/local/ap/include/boost/python/object_call.hpp:16: boost::python::detail::dependent::type boost::python::api::object_operators::operator()(const A0&) const [with A0 = boost::python::handle, U = boost::python::api::object] namespace.cc:33: non-lvalue in unary `&' Any ideas on how to achieve the desired result ? -Francois ---------------------------------------------------------------------------- Dr. Jean-Francois OSTIGUY voice: (630) 840-2231 Beam Physics Dept MS220 FAX: (630) 840-6039 Fermi National Accelerator Laboratory email: ostiguy at fnal.gov Batavia IL 60510-0500 WWW:www-ap.fnal.gov/~ostiguy From dave at boost-consulting.com Wed Nov 20 22:56:10 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 16:56:10 -0500 Subject: [C++-sig] python namespace In-Reply-To: (Francois Ostiguy's message of "Wed, 20 Nov 2002 15:58:37 -0600 (CST)") References: Message-ID: Francois Ostiguy writes: > So far all my attempts have failed. In particular, I tried the following > recipe, suggested by Dave in an earlier message > > namespace python = boost::python; > > void f1() { > std:: cout <<"f1" << std::endl; > } > > void f2() { > std:: cout <<"f2" << std::endl; > } > > > BOOST_PYTHON_MODULE(outer) > { > > > python::handle<> inner_module1( PyModule_New("outer.inner1")); > python::scope inner_scope1 = object(inner_module1); don't you need `python::' here?--^ > > python::def("f1", &f1); > > python::handle<> inner_module2( PyModule_New("outer.inner2")); > python::scope inner_scope2 = object(inner_module2); don't you need `python::' here?--^ > > python::def("f2", &f2); > > } > It fails with the following message: > > namespace.cc: In function `void init_module_outer()': > namespace.cc:29: non-lvalue in unary `&' > namespace.cc:29: no match for call to `(boost::python::api::object) ( > boost::python::handle&)' > /usr/local/ap/include/boost/python/object_core.hpp:101: candidates are: > boost::python::api::object > boost::python::api::object_operators::operator()() const [with U = > boost::python::api::object] > /usr/local/ap/include/boost/python/object_call.hpp:16: > boost::python::detail::dependent::type > boost::python::api::object_operators::operator()(const A0&) const > [with > A0 = boost::python::handle, U = boost::python::api::object] > namespace.cc:33: non-lvalue in unary `&' The above looks like it is trying to call some function-call operator with a handle<> argument. Where do you suppose that's coming from? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From ostiguy at fnal.gov Wed Nov 20 23:15:00 2002 From: ostiguy at fnal.gov (Francois Ostiguy) Date: Wed, 20 Nov 2002 16:15:00 -0600 (CST) Subject: [C++-sig] python namespace In-Reply-To: Message-ID: > > BOOST_PYTHON_MODULE(outer) > > { > > > > > > python::handle<> inner_module1( PyModule_New("outer.inner1")); > > python::scope inner_scope1 = object(inner_module1); > don't you need `python::' here?--^ > > > > python::def("f1", &f1); > > > > python::handle<> inner_module2( PyModule_New("outer.inner2")); > > python::scope inner_scope2 = object(inner_module2); > don't you need `python::' here?--^ > > > > python::def("f2", &f2); > > > > } Dave - you are correct. I forgot to use python::object instead of object in this version of my simplified example. I tried many permutations and I used the the wrong one in my post. The corrected version still does not compile: /usr/local/ap/include/boost/utility.hpp: In copy constructor `boost::python::scope::scope(const boost::python::scope&)': /usr/local/ap/include/boost/utility.hpp:55: ` boost::noncopyable::noncopyable(const boost::noncopyable&)' is private namespace.cc:29: within this context namespace.cc: In function `void init_module_outer()': namespace.cc:29: initializing temporary from result of ` boost::python::scope::scope(const boost::python::api::object&)' gmake: *** [namespace.o] Error 1 -Francois ---------------------------------------------------------------------------- Dr. Jean-Francois OSTIGUY voice: (630) 840-2231 Beam Physics Dept MS220 FAX: (630) 840-6039 Fermi National Accelerator Laboratory email: ostiguy at fnal.gov Batavia IL 60510-0500 WWW:www-ap.fnal.gov/~ostiguy From dave at boost-consulting.com Wed Nov 20 23:29:57 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 17:29:57 -0500 Subject: [C++-sig] python namespace In-Reply-To: (Francois Ostiguy's message of "Wed, 20 Nov 2002 16:15:00 -0600 (CST)") References: Message-ID: Francois Ostiguy writes: >> > BOOST_PYTHON_MODULE(outer) >> > { >> > >> > >> > python::handle<> inner_module1( PyModule_New("outer.inner1")); >> > python::scope inner_scope1 = object(inner_module1); >> don't you need `python::' here?--^ >> > >> > python::def("f1", &f1); >> > >> > python::handle<> inner_module2( PyModule_New("outer.inner2")); >> > python::scope inner_scope2 = object(inner_module2); >> don't you need `python::' here?--^ >> > >> > python::def("f2", &f2); >> > >> > } > > Dave - > > you are correct. I forgot to use python::object instead of object in > this version of my simplified example. I tried many permutations > and I used the the wrong one in my post. > > The corrected version still does not compile: > > /usr/local/ap/include/boost/utility.hpp: In copy constructor > `boost::python::scope::scope(const boost::python::scope&)': > /usr/local/ap/include/boost/utility.hpp:55: ` > boost::noncopyable::noncopyable(const boost::noncopyable&)' is private > namespace.cc:29: within this context > namespace.cc: In function `void init_module_outer()': > namespace.cc:29: initializing temporary from result of ` > boost::python::scope::scope(const boost::python::api::object&)' > gmake: *** [namespace.o] Error 1 Have you taken a close look at the error messages and the documentation for scope at http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/scope.html#scope-spec ? They tell all. python::scope inner_scope1(object(inner_module1)); Hmm, I probably should make the scope constructor explicit. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Thu Nov 21 00:46:07 2002 From: mike at bindkey.com (Mike Rovner) Date: Wed, 20 Nov 2002 15:46:07 -0800 Subject: [C++-sig] possible handle_exception_impl error Message-ID: I got a crash with following backtrace: >>> from PyTcn import * >>> a=Layer('a') >>> a.name Program received signal SIGSEGV, Segmentation fault. 0xfee5618c in ?? () at dyn-string.c:70 from /usr/local/lib/libstdc++.so.5 70 dyn-string.c: No such file or directory. (gdb) bt #0 0xfee5618c in ?? () at dyn-string.c:70 from /usr/local/lib/libstdc++.so.5 #1 0xfe37dc78 in ?? () at EnvInputStream.cpp:72 from /export/home/mike/BKsrc/CoreLibraries/src/./PyTcn.so #2 0xfe378fe4 in ?? () at EnvInputStream.cpp:72 from /export/home/mike/BKsrc/CoreLibraries/src/./PyTcn.so #3 0xfe376fc8 in ?? () at EnvInputStream.cpp:72 from /export/home/mike/BKsrc/CoreLibraries/src/./PyTcn.so #4 0xfe372ea8 in ?? () at EnvInputStream.cpp:72 from /export/home/mike/BKsrc/CoreLibraries/src/./PyTcn.so #5 0xfe36eaa8 in ?? () at EnvInputStream.cpp:72 from /export/home/mike/BKsrc/CoreLibraries/src/./PyTcn.so #6 0xfe36ad00 in ?? () at EnvInputStream.cpp:72 from /export/home/mike/BKsrc/CoreLibraries/src/./PyTcn.so #7 0xfe19008c in ?? () at /export/home/mike/boost_1_29_0/boost/function/function_template.hpp:320 from /usr/local/lib/libboost_python_debug.so #8 0xfe17aeb0 in _ZNK5boost6python7objects8function4callEP7_objectS4_ (this=0x170618, args=0x144060, keywords=0x0) at libs/python/src/object/function.cpp:118 #9 0xfe19177c in ?? () at /export/home/mike/boost_1_29_0/boost/python/type_id.hpp:127 from /usr/local/lib/libboost_python_debug.so #10 0xfe191128 in ?? () at /export/home/mike/boost_1_29_0/boost/function/function_base.hpp:157 from /usr/local/lib/libboost_python_debug.so #11 0xfe1aac3c in ?? () at /export/home/mike/boost_1_29_0/boost/python/type_id.hpp:127 from /usr/local/lib/libboost_python_debug.so #12 0xfe17d7c0 in _ZN5boost6python21handle_exception_implENS_9function0IvNS_21empty_function_p olicyENS_20empty_function_mixinESaINS_13function_baseEEEE (f=Cannot access memory at address 0xfdcef45c ) at libs/python/src/errors.cpp:24 #13 0xfe190460 in ?? () at /export/home/mike/boost_1_29_0/boost/function/function_template.hpp:296 from /usr/local/lib/libboost_python_debug.so #14 0xfe17b7d4 in function_call.2 (func=0x170618, args=0x144060, kw=0x0) at libs/python/src/object/function.cpp:355 #15 0x9b388 in PyObject_Call (func=0x170618, arg=0x144060, kw=0x0) at Objects/abstract.c:1688 #16 0x499d4 in PyEval_CallObjectWithKeywords (func=0x170618, arg=0x144060, kw=0x0) at Python/ceval.c:3058 #17 0x98094 in PyObject_CallFunction (callable=0x170618, format=0x144060 "") at Objects/abstract.c:1679 #18 0x1f458 in PyObject_GenericGetAttr (obj=0x1386e8, name=0x1187e8) at Objects/object.c:1270 #19 0x1f0f8 in PyObject_GetAttr (v=0x1386e8, name=0x1187e8) at Objects/object.c:1105 #20 0x470b4 in eval_frame (f=0x1197b0) at Python/ceval.c:1784 #21 0x48870 in PyEval_EvalCodeEx (co=0x1812e8, globals=0x1197b0, locals=0x1812e8, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2595 #22 0x4b520 in PyEval_EvalCode (co=0x1812e8, globals=0x117d08, locals=0x0) at Python/ceval.c:481 #23 0x7706c in run_node (n=0x1658b0, filename=0x117d08 "", globals=0x117d08, locals=0x117d08, flags=0x117d08) at Python/pythonrun.c:1079 #24 0x764d8 in PyRun_InteractiveOneFlags (fp=0xffffffff, filename=0xc64e8 "", flags=0xffbefb54) at Python/pythonrun.c:590 #25 0x76278 in PyRun_InteractiveLoopFlags (fp=0x1063a8, filename=0xc64e8 "", flags=0xffbefb54) at Python/pythonrun.c:526 #26 0x77d28 in PyRun_AnyFileExFlags (fp=0x1063a8, filename=0xc64e8 "", closeit=0, flags=0xffbefb54) at Python/pythonrun.c:489 #27 0x1b8c4 in Py_Main (argc=1, argv=0x1) at Modules/main.c:364 (gdb) Insteresting is #12 IMHO. Source: struct X { X(const char* init) : name(init) {} const char* Name() { return name.c_str();} private: std::string name; }; struct Obj : X { ... }; class_("Obj").add_property("name", (const char* (Obj::*)())&Obj::Name); From Paul_Kunz at SLAC.Stanford.EDU Thu Nov 21 00:51:25 2002 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Wed, 20 Nov 2002 15:51:25 -0800 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> Message-ID: <200211202351.gAKNpPP25444@libra3.slac.stanford.edu> >>>>> On Tue, 19 Nov 2002 12:00:20 -0500, David Abrahams said: > "Paul F. Kunz" writes: >> Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. >> >> My Python extension module fails to intialize. From the function >> generated by the macro >> >> BOOST_PYTHON_MODULE_INIT(hippo) >> >> the assertion in BOOST_FUNCTION_FUNCTION::operator() >> >> assert(!this->empty()); >> >> fails. With same source code, I do not have the problem with gcc >> 2.95.3 with boost 1.25.0 or gcc 3.2 with boost 1.28.0 under RedHat >> Linux. Also didn't have the problem with VC++ 6.0 sp 5. >> >> Any clues? Known problem? > Sorry, nope. > I can only suggest an upgrade to a current Boost.Python v2. It's > much better tested than 1.28.0. I took your suggestion. I converted to Boost.Python v2 first under Linux, and got things working. Then I tried Windows again. Got a little further... >>> from hippo import * >>> app = HDApp() Then I get the same exception as above. Relavent code is... class_ < PyApp > ( "HDApp" ) .def ( "canvas", &PyApp::currentCanvas, return_value_policy < reference_existing_object > () ) .def ( "openDocument", &PyApp::openDocument ) ; i.e. calling the default constructor causes exception. Any clues now? My next attempt will be to code up the examples from the Boost.Python tutorial and see how far I get. From dave at boost-consulting.com Thu Nov 21 00:50:54 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 18:50:54 -0500 Subject: [C++-sig] possible handle_exception_impl error In-Reply-To: ("Mike Rovner"'s message of "Wed, 20 Nov 2002 15:46:07 -0800") References: Message-ID: "Mike Rovner" writes: > I got a crash with following backtrace: > > Source: > > struct X { > X(const char* init) : name(init) {} > const char* Name() { return name.c_str();} > private: > std::string name; > }; > > struct Obj : X { ... }; > > class_("Obj").add_property("name", (const char* (Obj::*)())&Obj::Name); No module initialization function? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Thu Nov 21 01:05:04 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Wed, 20 Nov 2002 16:05:04 -0800 Subject: [C++-sig] example in lvalue_from_pytype won't compile Message-ID: I am working with the lvalue_from_pytype example and can't get it to compile. My code and the errors are as follows: #include //defines extern "C" _declspec(dllimport) PyTypeObject noddy_NoddyType; typedef struct { PyObject_HEAD long magicNum; } noddy_NoddyObject; using namespace boost::python; static handle<> cache; bool is_cached(noddy_NoddyObject* x) { return x == cache.get(); } void set_cache(noddy_NoddyObject* x) { cache = handle<>(borrowed(x)); } BOOST_PYTHON_MODULE(noddy_cache) { def("is_cached", is_cached); def("set_cache", set_cache); // register Noddy lvalue converter lvalue_from_pytype,&noddy_NoddyType>(); } Compiling... nc.cpp C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(15) : error C2446: '==' : no conversion from 'struct _object *' to 'noddy_NoddyObject *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(15) : error C2230: '==' : indirection to different types Error executing cl.exe. noddy cache.dll - 2 error(s), 0 warning(s) Apparently the converter is not getting registered but I can't see where. Also the code in the example does not declare noddy_NoddyType -- I exported the type from my noddy dll but am wondering if I am missing something here. Many thanks. --Mark From dave at boost-consulting.com Thu Nov 21 01:14:25 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 19:14:25 -0500 Subject: [C++-sig] example in lvalue_from_pytype won't compile In-Reply-To: (Mark Russell's message of "Wed, 20 Nov 2002 16:05:04 -0800") References: Message-ID: Mark, when posting errors, please make an effort to clearly indicate the line where the error occurred. You probably would have been able to figure out the problem and submit a patch if you had done this! Mark Russell writes: > I am working with the lvalue_from_pytype example and can't get it to > compile. My code and the errors are as follows: This is a doc bug. > #include > > //defines > extern "C" _declspec(dllimport) PyTypeObject noddy_NoddyType; > typedef struct { > PyObject_HEAD > long magicNum; > } noddy_NoddyObject; > > using namespace boost::python; > static handle<> cache; ^--- need `noddy_NoddyObject' here. > > bool is_cached(noddy_NoddyObject* x) > { > return x == cache.get(); > } > > void set_cache(noddy_NoddyObject* x) > { > cache = handle<>(borrowed(x)); ^--- need `noddy_NoddyObject' here. > } > > BOOST_PYTHON_MODULE(noddy_cache) > { > def("is_cached", is_cached); > def("set_cache", set_cache); > > // register Noddy lvalue converter > > lvalue_from_pytype,&noddy_NoddyType>(); > } > > Compiling... > nc.cpp > C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(15) : error C2446: > '==' : no conversion from 'struct _object *' to 'noddy_NoddyObject *' > Types pointed to are unrelated; conversion requires > reinterpret_cast, C-style cast or function-style cast > C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(15) : error C2230: > '==' : indirection to different types > Error executing cl.exe. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Thu Nov 21 01:37:59 2002 From: mike at bindkey.com (Mike Rovner) Date: Wed, 20 Nov 2002 16:37:59 -0800 Subject: [C++-sig] Re: possible handle_exception_impl error References: Message-ID: "David Abrahams" wrote in message news:u1y5fby1t.fsf at boost-consulting.com... > "Mike Rovner" writes: > > > I got a crash with following backtrace: > > > > Source: > > > > struct X { > > X(const char* init) : name(init) {} > > const char* Name() { return name.c_str();} > > private: > > std::string name; > > }; > > > > struct Obj : X { ... }; > > > > class_("Obj").add_property("name", (const char* (Obj::*)())&Obj::Name); > > No module initialization function? Oh well, excuse my laziness. :) #include using namespace boost::python; namespace Tcn { struct X { X(const char* init) : name(init) {} const char* Name() { return name.c_str();} private: const std::string name; }; } using namespace Tcn; struct Obj : X { explicit Obj(const char* init) : X(init), other_data(0) {} int other_data; }; BOOST_PYTHON_MODULE(PyTcn) { class_("Obj", init() ) .add_property("name", (const char* (Obj::*)())&Obj::Name); } The code above is working fine standalone, but crashes as part of bigger module. :( Apparently my namespace clashes with boost::python. :( From dave at boost-consulting.com Thu Nov 21 01:49:58 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 19:49:58 -0500 Subject: [C++-sig] Re: possible handle_exception_impl error In-Reply-To: ("Mike Rovner"'s message of "Wed, 20 Nov 2002 16:37:59 -0800") References: Message-ID: "Mike Rovner" writes: > The code above is working fine standalone, but crashes as part of > bigger module. :( > > Apparently my namespace clashes with boost::python. :( Why do you draw that conclusion? I think it's much more likely that your bigger module has a bug somewhere. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Thu Nov 21 02:06:08 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Wed, 20 Nov 2002 17:06:08 -0800 Subject: [C++-sig] example in lvalue_from_pytype won't compile In-Reply-To: Message-ID: Sorry David, The error message did not give me much of a hint on how to fix the problem. I must admit I am struggling a bit with c++, BPL has for the most part made the project I am working on very smooth going, most of the problems I am running into are actually my own lack of c++ expertise. BPL is certainly the best wrapper lib I have ever worked with. Thanks again for all your help. --Mark -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On Behalf Of David Abrahams Sent: Wednesday, November 20, 2002 4:14 PM To: c++-sig at python.org Subject: Re: [C++-sig] example in lvalue_from_pytype won't compile Mark, when posting errors, please make an effort to clearly indicate the line where the error occurred. You probably would have been able to figure out the problem and submit a patch if you had done this! Mark Russell writes: > I am working with the lvalue_from_pytype example and can't get it to > compile. My code and the errors are as follows: This is a doc bug. > #include > > //defines > extern "C" _declspec(dllimport) PyTypeObject noddy_NoddyType; > typedef struct { > PyObject_HEAD > long magicNum; > } noddy_NoddyObject; > > using namespace boost::python; > static handle<> cache; ^--- need `noddy_NoddyObject' here. > > bool is_cached(noddy_NoddyObject* x) > { > return x == cache.get(); > } > > void set_cache(noddy_NoddyObject* x) > { > cache = handle<>(borrowed(x)); ^--- need `noddy_NoddyObject' here. > } > > BOOST_PYTHON_MODULE(noddy_cache) > { > def("is_cached", is_cached); > def("set_cache", set_cache); > > // register Noddy lvalue converter > > lvalue_from_pytype,&noddy_NoddyType>(); > } > > Compiling... > nc.cpp > C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(15) : error C2446: > '==' : no conversion from 'struct _object *' to 'noddy_NoddyObject *' > Types pointed to are unrelated; conversion requires > reinterpret_cast, C-style cast or function-style cast > C:\developer\com-hacking\boost hacking\noddy cache\nc.cpp(15) : error C2230: > '==' : indirection to different types > Error executing cl.exe. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From mike at bindkey.com Thu Nov 21 02:12:56 2002 From: mike at bindkey.com (Mike Rovner) Date: Wed, 20 Nov 2002 17:12:56 -0800 Subject: [C++-sig] Re: Re: possible handle_exception_impl error References: Message-ID: "David Abrahams" wrote in message news:u8yznagqx.fsf at boost-consulting.com... > "Mike Rovner" writes: > > > The code above is working fine standalone, but crashes as part of > > bigger module. :( > > > > Apparently my namespace clashes with boost::python. :( > > Why do you draw that conclusion? > > I think it's much more likely that your bigger module has a bug > somewhere. Because I stripped down to this: #include #include "Tcn.h" using namespace boost::python; using namespace Tcn; BOOST_PYTHON_MODULE(bpl_t3) { class_("Layer", init()) .add_property("name", (const char* (LayerDef::*)())&LayerDef::Name) ; } and Tcn supposed to be a library I'm wrapping. Ideally it's not buggy but in reality.... And be sure it's not mine :( From dave at boost-consulting.com Thu Nov 21 02:38:56 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 20:38:56 -0500 Subject: [C++-sig] Re: Re: possible handle_exception_impl error In-Reply-To: ("Mike Rovner"'s message of "Wed, 20 Nov 2002 17:12:56 -0800") References: Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:u8yznagqx.fsf at boost-consulting.com... >> "Mike Rovner" writes: >> >> > The code above is working fine standalone, but crashes as part of >> > bigger module. :( >> > >> > Apparently my namespace clashes with boost::python. :( >> >> Why do you draw that conclusion? > > Because I stripped down to this: > > #include > #include "Tcn.h" > > using namespace boost::python; > using namespace Tcn; > > BOOST_PYTHON_MODULE(bpl_t3) > { > class_("Layer", init()) > .add_property("name", (const char* (LayerDef::*)())&LayerDef::Name) > ; > } > > and Tcn supposed to be a library I'm wrapping. I still don't see how that could lead to the conclusion that there's a namespace conflict. And if there was, you could ditch the using-directives and go with some amount of qualification instead. >> I think it's much more likely that your bigger module has a bug >> somewhere. > > Ideally it's not buggy but in reality.... > And be sure it's not mine :( Best of luck to you. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Thu Nov 21 02:57:27 2002 From: mike at bindkey.com (Mike Rovner) Date: Wed, 20 Nov 2002 17:57:27 -0800 Subject: [C++-sig] Re: Re: Re: possible handle_exception_impl error References: Message-ID: "David Abrahams" wrote in message news:un0o38zwv.fsf at boost-consulting.com... > I still don't see how that could lead to the conclusion that there's a > namespace conflict. And if there was, you could ditch the > using-directives and go with some amount of qualification instead. That's what I'm doing now. You are right - the conclusion was a wild guess. I'm in dispare. > >> I think it's much more likely that your bigger module has a bug > >> somewhere. > > > > Ideally it's not buggy but in reality.... > > And be sure it's not mine :( > > > Best of luck to you. Thank you, Dave. I really appreciate you help. From dave at boost-consulting.com Thu Nov 21 05:16:01 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 20 Nov 2002 23:16:01 -0500 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: <200211202351.gAKNpPP25444@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Wed, 20 Nov 2002 15:51:25 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211202351.gAKNpPP25444@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: >>>>>> On Tue, 19 Nov 2002 12:00:20 -0500, David Abrahams said: > >> "Paul F. Kunz" writes: >>> Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. >>> >>> My Python extension module fails to intialize. From the function >>> generated by the macro >>> >>> BOOST_PYTHON_MODULE_INIT(hippo) >>> >>> the assertion in BOOST_FUNCTION_FUNCTION::operator() >>> >>> assert(!this->empty()); >>> >>> fails. With same source code, I do not have the problem with gcc >>> 2.95.3 with boost 1.25.0 or gcc 3.2 with boost 1.28.0 under RedHat >>> Linux. Also didn't have the problem with VC++ 6.0 sp 5. >>> >>> Any clues? Known problem? > >> Sorry, nope. > >> I can only suggest an upgrade to a current Boost.Python v2. It's >> much better tested than 1.28.0. > > I took your suggestion. I converted to Boost.Python v2 first under > Linux, and got things working. Then I tried Windows again. Got a > little further... > >>>> from hippo import * >>>> app = HDApp() > > Then I get the same exception as above. Relavent code is... > > class_ < PyApp > ( "HDApp" ) > .def ( "canvas", &PyApp::currentCanvas, > return_value_policy < reference_existing_object > () ) > .def ( "openDocument", &PyApp::openDocument ) > ; > > i.e. calling the default constructor causes exception. That looks like a different problem than the previous one. Can you post a complete, minimal reproducible test case? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Mark.Charsley at radioscape.com Thu Nov 21 11:23:59 2002 From: Mark.Charsley at radioscape.com (Charsley, Mark) Date: Thu, 21 Nov 2002 10:23:59 -0000 Subject: [C++-sig] Keeping up to date Message-ID: <3190BC9FA8F6D3119508009027E5B33EBA53C5@MORSE> We've got a project that uses boost.python. At the moment, we just put each release of boost under source control (Rational's Clearcase) and use that until another release is available from boost.org. However I notice that several posts here recommend getting later versions of various files from boost.python's CVS. How do other people keep their local copies of boost.python up to date? TIA -- Mark ********************************************************************** This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify postmaster at radioscape.com. This footnote also confirms that this email message has been scanned for the presence of computer viruses known at the time of sending. www.radioscape.com ********************************************************************** From warkid at hotbox.ru Thu Nov 21 15:05:39 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Thu, 21 Nov 2002 17:05:39 +0300 Subject: [C++-sig] Returning const reference. Message-ID: <97193157625.20021121170539@hotbox.ru> Hello c++-sig, I want to export function returning const ref: /////////////////////// const int& f(){ static int i; return i; } BOOST_PYTHON_MODULE(hello) { def("f", f); } /////////////////////// and while compiling I get this error code: error C2079: 'cr' uses undefined struct 'boost::python::detail::specify_a_result_policy_to_wrap_functions_returning' with [ T=const int & ] what's wrong with what I'm doing? Best regards, Kerim mailto:warkid at hotbox.ru From rwgk at yahoo.com Thu Nov 21 15:30:47 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 21 Nov 2002 06:30:47 -0800 (PST) Subject: [C++-sig] Returning const reference. In-Reply-To: <97193157625.20021121170539@hotbox.ru> Message-ID: <20021121143047.32822.qmail@web20203.mail.yahoo.com> --- Kerim Borchaev wrote: > error C2079: 'cr' uses undefined struct > 'boost::python::detail::specify_a_result_policy_to_wrap_functions_returning Here is what the error message is trying to tell you: #include #include //... using namespace boost::python; typedef return_value_policy ccr; //... def("f", f, ccr()) Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus ? Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From warkid at hotbox.ru Thu Nov 21 16:24:43 2002 From: warkid at hotbox.ru (Kerim Borchaev) Date: Thu, 21 Nov 2002 18:24:43 +0300 Subject: [C++-sig] C++ nested classes and addressof.hpp (cannot convert from 'const C::N *' to 'C::N *') Message-ID: <163197901171.20021121182443@hotbox.ru> Hello c++-sig, I'm exporting c++ class nested in other c++ class: ///////////// struct C{ struct N{}; }; BOOST_PYTHON_MODULE(hello) { class_("C.N"); } ///////////// and getting this error message: C:\Tools\boost_1_29_0\boost\utility\addressof.hpp(26) : error C2440: 'return' : cannot convert from 'const C::N *' to 'C::N *' Conversion loses qualifiers What is fun that in addressof.hpp there's a comment: // Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov) Strange, isn't it? Best regards, Kerim mailto:warkid at hotbox.ru From ostiguy at fnal.gov Thu Nov 21 16:57:31 2002 From: ostiguy at fnal.gov (Francois Ostiguy) Date: Thu, 21 Nov 2002 09:57:31 -0600 (CST) Subject: [C++-sig] python namespace In-Reply-To: Message-ID: > Have you taken a close look at the error messages and the > documentation for scope at > http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/scope.html#scope-spec > ? > They tell all. > > python::scope inner_scope1(object(inner_module1)); > > Hmm, I probably should make the scope constructor explicit. Thanks, once again. At least I understand the origin of the error message. My code now compiles, unfortunately, the result is not what I expected. here is the current code for my toy example: using std::complex; namespace python = boost::python; void f1() { std:: cout <<"f1" << std::endl; } void f2() { std:: cout <<"f2" << std::endl; } static char filename[] = "outer.so"; BOOST_PYTHON_MODULE(outer) { python::handle<> inner_module1( PyModule_New("outer.inner1")); python::object inner_object1(inner_module1); inner_object1.attr("__file__") = filename; python::scope inner_scope1(inner_object1); python::def("f1", &f1); python::handle<> inner_module2( PyModule_New("outer.inner2")); python::object inner_object2(inner_module2); inner_object2.attr("__file__") = filename; python::scope inner_scope2(inner_object2); python::def("f2", &f2); } When I load the module, here is what I get Python 2.2.2 (#1, Oct 28 2002, 17:04:52) [GCC 3.1.1] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> import outer >>> dir() ['__builtins__', '__doc__', '__name__', 'outer'] >>> dir(outer) ['__doc__', '__file__', '__name__'] >>> That is to say, "inner1" and "inner2" are not defined in the "outer" scope. The documentation for PyModule_New(char* ) and other related functions is terse and not very helpful in terms of explaining how they should be used ... I am stumped. -Francois ---------------------------------------------------------------------------- Dr. Jean-Francois OSTIGUY voice: (630) 840-2231 Beam Physics Dept MS220 FAX: (630) 840-6039 Fermi National Accelerator Laboratory email: ostiguy at fnal.gov Batavia IL 60510-0500 WWW:www-ap.fnal.gov/~ostiguy From dave at boost-consulting.com Thu Nov 21 17:09:11 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 21 Nov 2002 11:09:11 -0500 Subject: [C++-sig] python namespace In-Reply-To: (Francois Ostiguy's message of "Thu, 21 Nov 2002 09:57:31 -0600 (CST)") References: Message-ID: Francois Ostiguy writes: > When I load the module, here is what I get > > Python 2.2.2 (#1, Oct 28 2002, 17:04:52) > [GCC 3.1.1] on sunos5 > Type "help", "copyright", "credits" or "license" for more information. >>>> import outer >>>> dir() > ['__builtins__', '__doc__', '__name__', 'outer'] >>>> dir(outer) > ['__doc__', '__file__', '__name__'] >>>> > > That is to say, "inner1" and "inner2" are not defined in the "outer" > scope. The documentation for PyModule_New(char* ) and other related > functions is terse and not very helpful in terms of explaining how they > should be used ... I am stumped. I suggest you ask about this on python-list (or python-dev, but only if you get radio silence). And leave out any mention of Boost.Python constructs if possible; it will just confuse people. I'd very much like to have a working example of this somewhere, so please report back when you find the answer. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From achim.domma at syynx.de Thu Nov 21 17:48:27 2002 From: achim.domma at syynx.de (Achim Domma) Date: Thu, 21 Nov 2002 17:48:27 +0100 Subject: [C++-sig] python namespace In-Reply-To: Message-ID: Hi, I have the same problem like Francois. I use the following: handle<> inner_module(PyModule_New("Drawable")); scope().attr("Drawable") = inner_module; scope drawable = object(inner_module); it works fine with VC7 but I tried it on RH8 with gcc3.2 and it failed to compile with the same error as Francois code. Then I tried something like: scope drawable = scope(object(inner_module)) This compiles but does not have the expected result. BTW: Should the parameter for PyModule_New be "InnerModule" or "OuterModule.InnerModule"? Achim From ostiguy at fnal.gov Thu Nov 21 17:56:41 2002 From: ostiguy at fnal.gov (Francois Ostiguy) Date: Thu, 21 Nov 2002 10:56:41 -0600 (CST) Subject: [C++-sig] python namespace In-Reply-To: Message-ID: On Thu, 21 Nov 2002, Achim Domma wrote: > Date: Thu, 21 Nov 2002 17:48:27 +0100 > From: Achim Domma > Reply-To: c++-sig at python.org > To: c++-sig at python.org > Subject: RE: [C++-sig] python namespace > > Hi, > > I have the same problem like Francois. I use the following: > > handle<> inner_module(PyModule_New("Drawable")); > scope().attr("Drawable") = inner_module; > scope drawable = object(inner_module); > > it works fine with VC7 but I tried it on RH8 with gcc3.2 and it failed to > compile with the same error as Francois code. Then I tried something like: > > scope drawable = scope(object(inner_module)) > > This compiles but does not have the expected result. BTW: Should the > parameter for PyModule_New be "InnerModule" or "OuterModule.InnerModule"? > I am not clear on what you mean ... do you mean it *compiles* and *works* fine with VC7 or just it *compiles* with VC7 ? -Francois ---------------------------------------------------------------------------- Dr. Jean-Francois OSTIGUY voice: (630) 840-2231 Beam Physics Dept MS220 FAX: (630) 840-6039 Fermi National Accelerator Laboratory email: ostiguy at fnal.gov Batavia IL 60510-0500 WWW:www-ap.fnal.gov/~ostiguy From achim.domma at syynx.de Thu Nov 21 18:15:22 2002 From: achim.domma at syynx.de (Achim Domma) Date: Thu, 21 Nov 2002 18:15:22 +0100 Subject: [C++-sig] python namespace In-Reply-To: Message-ID: > > handle<> inner_module(PyModule_New("Drawable")); > > scope().attr("Drawable") = inner_module; > > scope drawable = object(inner_module); > > > I am not clear on what you mean ... do you mean it *compiles* and *works* > fine with VC7 or just it *compiles* with VC7 ? This version compiles and works, as far as I tested it, which is not very much yet. But using dir(PythonMagick) I see the submodule 'Drawable' and dir(PythonMagick.Drawable) works also as expected. Achim From Paul_Kunz at SLAC.Stanford.EDU Thu Nov 21 20:38:25 2002 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Thu, 21 Nov 2002 11:38:25 -0800 Subject: [C++-sig] Converting std::vector to Python tuple Message-ID: <200211211938.gALJcP128801@libra3.slac.stanford.edu> Took a couple hours off from my VC++ 7 woes this morning to continue converting to boost.python V2 under Linux. I needed to expose to Python member functions of a C++ class that returned a const vector & and const vector &. After pouring over the documentation, FAQ, and mailing list archives, I came up with a solution that works for me, but would like to receive comment on it. First, from Ralf's scitbx package, I copied template ( typename ContainerType > struct to_tuple {...} into my own code. Then within my BOOST_PYTHON_MODULE I have ... class_ < PyFunctionRep > ( "Function", init < const std::string & > () ) .def ( "parmNames", &PyFunctionRep::parmNames, // ret vector return_value_policy < copy_const_reference > () ) .def ( "parameters", &PyFunctionRep::parameters, // ret vector return_value_policy < copy_const_reference > () ) ; and ... to_python_converter < const std::vector < double >, to_tuple < const std::vector < double > > > (); to_python_converter < const std::vector < std::string >, to_tuple < const std::vector < std::string > > > (); Is this correct? Suggestion for improvements? If this is correct, may I suggest that something like it go into the tutorial and/or FAQ. From dave at boost-consulting.com Thu Nov 21 21:11:24 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 21 Nov 2002 15:11:24 -0500 Subject: [C++-sig] python namespace In-Reply-To: ("Achim Domma"'s message of "Thu, 21 Nov 2002 17:48:27 +0100") References: Message-ID: "Achim Domma" writes: > Hi, > > I have the same problem like Francois. I use the following: > > handle<> inner_module(PyModule_New("Drawable")); > scope().attr("Drawable") = inner_module; > scope drawable = object(inner_module); > > it works fine with VC7 but I tried it on RH8 with gcc3.2 and it failed to > compile with the same error as Francois code. Then I tried something like: > > scope drawable = scope(object(inner_module)) Why are you messing around with that approach when I already posted this correct one? scope drawable(object(inner_module)); > > This compiles but does not have the expected result. Try with the latest CVS. It won't even compile . -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Thu Nov 21 21:22:10 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 21 Nov 2002 12:22:10 -0800 (PST) Subject: [C++-sig] Converting std::vector to Python tuple In-Reply-To: <200211211938.gALJcP128801@libra3.slac.stanford.edu> Message-ID: <20021121202210.59198.qmail@web20207.mail.yahoo.com> --- "Paul F. Kunz" wrote: > to_python_converter < > const std::vector < double >, > to_tuple < const std::vector < double > > > (); > > to_python_converter < > const std::vector < std::string >, > to_tuple < const std::vector < std::string > > > (); > > Is this correct? Suggestion for improvements? It looks great. I don't think you need the "const" but maybe it doesn't do any harm. There isn't much to improve. If you need more std::vector<> tuple mappings you could create your own little helper struct to cut down on the redundancy, along the lines of (untested) template std_vector_to_tuple { std_vector_to_tuple() { to_python_converter < std::vector, to_tuple > >(); } }; Then: std_vector_to_tuple(); std_vector_to_tuple(); > If this is correct, may I suggest that something like it go into the > tutorial and/or FAQ. Contributions from the community are highly appreciated. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus ? Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From BPettersen at NAREX.com Thu Nov 21 23:34:48 2002 From: BPettersen at NAREX.com (Bjorn Pettersen) Date: Thu, 21 Nov 2002 15:34:48 -0700 Subject: [C++-sig] python namespace Message-ID: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD871@admin56.narex.com> > From: David Abrahams [mailto:dave at boost-consulting.com] > > "Achim Domma" writes: > > > Hi, > > > > I have the same problem like Francois. I use the following: > > > > handle<> inner_module(PyModule_New("Drawable")); > > scope().attr("Drawable") = inner_module; > > scope drawable = object(inner_module); > > > > it works fine with VC7 but I tried it on RH8 with gcc3.2 and it failed > > to compile with the same error as Francois code. Then I tried > > something like: > > > > scope drawable = scope(object(inner_module)) > > Why are you messing around with that approach when I already > posted this correct one? > > scope drawable(object(inner_module)); Now I'm confused... If I use the following code: handle<> db_module(PyModule_New("db")); scope().attr("db") = db_module; scope db_scope = object(db_module); /**/ class_("X"); X ends up in nrx.db (my main module is named nrx) and everything works as expected. If I change the line marked /**/ to: scope db_scope(object(db_module)); X ends up in nrx and there's an empty nrx.db. To add to the confusion, I thought: A a = B(x); was equivalent to: A a(B(x)); is my C++ really that rusty? -- bjorn (running XP/VC6) From dave at boost-consulting.com Thu Nov 21 23:40:01 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 21 Nov 2002 17:40:01 -0500 Subject: [C++-sig] python namespace In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD871@admin56.narex.com> ("Bjorn Pettersen"'s message of "Thu, 21 Nov 2002 15:34:48 -0700") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD871@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: >> From: David Abrahams [mailto:dave at boost-consulting.com] >> >> "Achim Domma" writes: >> >> > scope drawable = scope(object(inner_module)) >> >> Why are you messing around with that approach when I already >> posted this correct one? >> >> scope drawable(object(inner_module)); > > Now I'm confused... If I use the following code: > > handle<> db_module(PyModule_New("db")); > scope().attr("db") = db_module; > scope db_scope = object(db_module); /**/ > class_("X"); > > X ends up in nrx.db (my main module is named nrx) and everything works > as expected. If I change the line marked /**/ to: > > scope db_scope(object(db_module)); > > X ends up in nrx and there's an empty nrx.db. To add to the confusion, I > thought: > > A a = B(x); > > was equivalent to: > > A a(B(x)); it is, unless A's constructor is explicit. > is my C++ really that rusty? Naw. Well, maybe. It's confusing. I was wrong, sorry. The correct line is scope db_scope((object(db_module))); The other one, without the extra parens, declares a function :( To see that, note that the following compiles: struct scope {}; struct object {}; int main() { scope db_scope(object(db_module)); } Hmm, maybe it wasn't such a good idea to make scope's constructor explicit. I give up!! Any suggestions for the proper interface to scope will be gratefully considered! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Fri Nov 22 00:24:55 2002 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Thu, 21 Nov 2002 15:24:55 -0800 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211202351.gAKNpPP25444@libra3.slac.stanford.edu> Message-ID: <200211212324.gALNOtj00529@libra3.slac.stanford.edu> >>>>> On Wed, 20 Nov 2002 23:16:01 -0500, David Abrahams said: >> >>>>> from hippo import * app = HDApp() >> Then I get the same exception as above. Relavent code is... >> >> class_ < PyApp > ( "HDApp" ) .def ( "canvas", >> &PyApp::currentCanvas, return_value_policy < >> reference_existing_object > () ) .def ( "openDocument", >> &PyApp::openDocument ) >> ; >> >> i.e. calling the default constructor causes exception. > That looks like a different problem than the previous one. Can you > post a complete, minimal reproducible test case? --- PyApp.h --- #ifndef PyApp_H #define PyApp_H class PyApp { public: PyApp ( ); ~PyApp ( ); }; #endif // PyApp_H --- PyApp.cxx --- #include "PyApp.h" PyApp::PyApp ( ) { } PyApp::~PyApp ( ) { } --- pyhippo.cxx --- #ifdef _MSC_VER # pragma warning(disable:4231) // nonstandard extension used 'extern' before... # pragma warning(disable:4251) // needs to have dll-interface used by client # pragma warning(disable:4275) // non dll-interface struct #endif #include "PyApp.h" #include using namespace boost::python; BOOST_PYTHON_MODULE(hippo) { class_ < PyApp > ( "HDApp" ) ; } // BOOST_PYTHON_MODULE_INIT Then in the directory where the hippo.pyd is built >>> from hippo import * >>> app = HDApp() From Paul_Kunz at SLAC.Stanford.EDU Fri Nov 22 01:31:51 2002 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Thu, 21 Nov 2002 16:31:51 -0800 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> Message-ID: <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> >>>>> On Tue, 19 Nov 2002 12:00:20 -0500, David Abrahams said: > "Paul F. Kunz" writes: >> Environment: boost 1.28.0, VC++ 7.0, Windows 2000 and XP. >> >> My Python extension module fails to intialize. From the function >> generated by the macro >> >> BOOST_PYTHON_MODULE_INIT(hippo) >> >> the assertion in BOOST_FUNCTION_FUNCTION::operator() >> >> assert(!this->empty()); >> >> fails. With same source code, I do not have the problem with gcc >> 2.95.3 with boost 1.25.0 or gcc 3.2 with boost 1.28.0 under RedHat >> Linux. Also didn't have the problem with VC++ 6.0 sp 5. >> >> Any clues? Known problem? > Sorry, nope. > I can only suggest an upgrade to a current Boost.Python v2. It's > much better tested than 1.28.0. Found the problem! Only took two afternoon's worth of work :-( The project setting for the vc.proj that created the Python extension module was set "Use Managed Extension" = "yes". Setting it to "no" completely fixes the problem. Grrr. I guess the "yes" setting was a default. From dave at boost-consulting.com Fri Nov 22 01:53:39 2002 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 21 Nov 2002 19:53:39 -0500 Subject: [C++-sig] Problem with vc++ 7 In-Reply-To: <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Thu, 21 Nov 2002 16:31:51 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: > Found the problem! Only took two afternoon's worth of work :-( > > The project setting for the vc.proj that created the Python extension > module was set "Use Managed Extension" = "yes". Setting it to "no" > completely fixes the problem. Grrr. I guess the "yes" setting was > a default. This is why I tell people to use Jamfiles. subproject libs/python/user ; # bring in the rules for python SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; extension hippo : PyApp.cxx pyhippo.cxx ../build/boost_python ; boost-python-runtest hippo : test.py hippo ; -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From patrick at vrac.iastate.edu Fri Nov 22 03:56:13 2002 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Thu, 21 Nov 2002 20:56:13 -0600 Subject: [C++-sig] Incrementing reference count of returned object pointer References: <3DDBF719.5010308@vrac.iastate.edu> Message-ID: <3DDD9CCD.9060703@vrac.iastate.edu> Patrick Hartling wrote: > I am having some difficulty using boost::python::call() to invoke a > Python function that returns a pointer. I understand that the callback > semantics cause an exception to be thrown if the reference count of the > returned object is 1, so I am wondering how to increment the reference > count. The code that receives the reference will be holding onto it, so > of course I don't want it to be garbage collected. > > For some background, what I am working on involves an abstract base > class written in C++ that will be extended using a derived Python > class. I would like to be able to use Python-defined objects in C++ as > though they were polymorphic instances of the base class (which they > are--at least conceptually). My long-term goal is to be able to load > Python modules on the fly that define a subclass of the abstract base > class. To get a reference to an instance of the derived Python class, I > want to have a factory function that simply returns the instance. This > factory function would be called by the C++ code (via > boost::python::call() or some other similarly friendly mechanism), > and the result would be treated as a reference to the abstract base > class. What this all boils down to is an interface defined in C++ that > can be implemented in Python (or any language) where instances of the > interface implementations will be used in C++. So, given a PyObject* > factory_func that is the callable factory function, I want to do > something like this: > > Base* obj = boost::python::call(factory_func); Okay, I think I got this worked out. Instead of the above, I am doing the following (assuming namespace python = boost::python): python::object base_obj = python::call(factory_func); Base* obj = python::extract(base_obj); This seems to do the trick. Is there anything fundamentally wrong with this? -Patrick -- Patrick L. Hartling | Research Assistant, VRAC patrick at vrac.iastate.edu | 2624 Howe Hall: 1.515.294.4916 http://www.137.org/patrick/ | http://www.vrac.iastate.edu/ From mrussell8081 at pacbell.net Fri Nov 22 04:47:58 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Thu, 21 Nov 2002 19:47:58 -0800 Subject: [C++-sig] debug mode triggers assert in class.hpp Message-ID: I have built a debug version of python and BPL e.g. when I try to create an object from a BPL extension it triggers the same assert in class.hpp at allocate. I must have some very basic config option wrong but I can't figure out what. The python transcript below shows the problem, the assert on line 453 in class.hpp is below that. --Mark C:\developer\pydebug>python_d Adding parser accelerators ... Done. Python 2.2.2 (#37, Nov 21 2002, 17:20:19) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import hello [8161 refs] >>> dir(hello) ['World', '__doc__', '__file__', '__name__'] [8172 refs] >>> w = hello.World() Assertion failed: self_->ob_type->ob_type == &class_metatype_object, file libs\p ython\build\../src/object\class.cpp, line 453 Traceback (most recent call last): File "", line 1, in ? RuntimeError: unidentifiable C++ exception [8211 refs] >>> class.hpp void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size) { assert(self_->ob_type->ob_type == &class_metatype_object); objects::instance<>* self = (objects::instance<>*)self_; From ghost at cs.msu.su Fri Nov 22 18:01:49 2002 From: ghost at cs.msu.su (Vladimir Prus) Date: Fri, 22 Nov 2002 20:01:49 +0300 Subject: [C++-sig] Wrapping & embedding, with a segfault Message-ID: <3DDE62FD.3010306@cs.msu.su> I'm trying to 1. Wrap some class with Boost.Python and then 2. Embed the Python interpreter, and run some script, passing the embedded class to that script. When doing 1), I've run in a problem. I've took the attached program, dropped it in "example" dir, added exe embedding_test : embedding_test.cpp ../build/boost_python : $(BOOST_PYTHON_V2_PROPERTIES) python2.2 ; to Jamfile, and run "bjam". But when I run the program, I get segfault. What can be the problem? TIA, Volodya P.S. Please cc me, I'm not subscribed. -------------- next part -------------- A non-text attachment was scrubbed... Name: embedding_test.cpp Type: text/x-c++src Size: 622 bytes Desc: not available URL: From n_lelong at hotmail.com Fri Nov 22 18:35:00 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Fri, 22 Nov 2002 18:35:00 +0100 Subject: [C++-sig] VC7 + auto_ptr + transfer of owership Message-ID: Hi everyone, whenever I try to declare a scheme of transfer of ownership to BP2, I get a nasty compiler error. I tries with a simple example, and it justs does the same. Here are my simple classes: struct Data { }; class Test { std::auto_ptr m_data; public: Test() {}; Test(Test const& src) : m_data( src.m_data.get()==NULL ? NULL : new Data(*src.m_data) ) {}; void setData(std::auto_ptr data) { m_data = data; } }; They are declared as follow : BOOST_PYTHON_MODULE( mgd ) { python::class_ Data_class("Data"); python::class_ Test_class("Test"); Test_class.def("setData", &Test::setData); } And my dear old VC7 tells me: d:\Sources\mgd\include\boost\python\detail\returning.hpp(205) : error C2664: 'boost::python::detail::returning::R (A0)' : cannot convert parameter 1 from 'const boost::add_const::type' to 'std::auto_ptr<_Ty>' with [ R=void, A0=std::auto_ptr<`anonymous-namespace'::Data> ] and [ T=std::auto_ptr<`anonymous-namespace'::Data> ] and [ _Ty=`anonymous-namespace'::Data ] No copy constructor available for class 'std::auto_ptr<_Ty>' or constructor attempts to perform illegal conversion to non-__gc reference with [ _Ty=`anonymous-namespace'::Data ] Being curious, I followed an example I found in a previous post, and changed the Holder for Data to auto_ptr, like this : python::class_ > Data_class("Data"); But when I do that, I grab another compiler error : d:\Sources\mgd\include\boost\python\object\make_instance.hpp(60) : error C2664: 'std::auto_ptr<_Ty>::auto_ptr(std::auto_ptr<_Ty> &)' : cannot convert parameter 1 from 'const boost::python::class_::held_type' to 'std::auto_ptr<_Ty> &' with [ _Ty=`anonymous-namespace'::Data ] and [ T=`anonymous-namespace'::Data, X1=std::auto_ptr<`anonymous-namespace'::Data>, X2=boost::python::detail::not_specified, X3=boost::python::detail::not_specified ] and [ _Ty=`anonymous-namespace'::Data ] Conversion loses qualifiers Am I doing something wrong ? Did anyone encounter this kind of problem ? Thanks, Nicolas. From dave at boost-consulting.com Fri Nov 22 19:51:53 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 13:51:53 -0500 Subject: [C++-sig] VC7 + auto_ptr + transfer of owership In-Reply-To: ("Nicolas Lelong"'s message of "Fri, 22 Nov 2002 18:35:00 +0100") References: Message-ID: "Nicolas Lelong" writes: > Hi everyone, > > whenever I try to declare a scheme of transfer of ownership to BP2, I get a > nasty compiler error. > > I tries with a simple example, and it justs does the same. Here are my > simple classes: > > Am I doing something wrong ? Did anyone encounter this kind of problem ? auto_ptr support is only really complete in the current CVS version. There are some problems with it in 1.29.0. HTH, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 22 19:58:11 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 13:58:11 -0500 Subject: [C++-sig] Contributing an embedding example (after a bugfix ;) In-Reply-To: (Dirk Gerrits's message of "Mon, 18 Nov 2002 22:44:30 +0100") References: Message-ID: Dirk Gerrits writes: > After receiving a lot of help in another thread (thanks!) I was able > to get my little Boost.Python program using embedding to compile and > run. It works great! But upon deinitialization with Py_Finalize(), I > get an error: > > Fatal Python error: PyThreadState_Get: no current thread > > I don't really know what is causing this, so I am asking for your help > again. :) The problem is that Boost.Python doesn't yet support PyFinalize(). It keeps some PyObject references alive in global data structures, and when those go out of scope after interpreter finalization, Python crashes. It's a fairly simple project to fix this, though it will take some work. Patches welcome. > After having fixed this though, I'd be willing to contribute this as > an example for Boost.Python, if there is interest. I thought it was a > pretty neat technique myself. ;) Please do; It's a nice example! > Before that, I'd need to Boostify the code a bit though, and I am > wondering if all of it is necessary. For example, BaseWrap seems a bit > superfluous since I'm only using Base's polymorphism from the C++ > side. Any comments on this? That's exactly what it's for. You if you want to override the C++ virtual function f() in Python, you need the dispatching override in BaseWrap. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 22 20:04:05 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 14:04:05 -0500 Subject: [C++-sig] Wrapping & embedding, with a segfault In-Reply-To: <3DDE62FD.3010306@cs.msu.su> (Vladimir Prus's message of "Fri, 22 Nov 2002 20:01:49 +0300") References: <3DDE62FD.3010306@cs.msu.su> Message-ID: Vladimir Prus writes: > I'm trying to > 1. Wrap some class with Boost.Python and then > 2. Embed the Python interpreter, and run some script, > passing the embedded class to that script. > > When doing 1), I've run in a problem. I've took > the attached program, dropped it in "example" dir, > added > > exe embedding_test : embedding_test.cpp ../build/boost_python : > $(BOOST_PYTHON_V2_PROPERTIES) python2.2 > ; > > to Jamfile, and run "bjam". But when I run the program, > I get segfault. What can be the problem? There's no module initialization function, to start with. See http://mail.python.org/pipermail/c++-sig/2002-November/002653.html, and my followup. > > P.S. Please cc me, I'm not subscribed. > > > > > // Example by Ralf W. Grosse-Kunstleve > > #include > #include > > > class hello > { > public: > hello(const std::string& country) { this->country = country; } > std::string greet() const { return "Hello from " + country; } > private: > std::string country; > }; > > > #include > #include > #include > > int main() > { > using namespace boost::python; > class_ d("hello", init()); > > // Add a regular member function. > d.def("greet", &hello::greet); > > > cout << d.ptr() << "\n"; > } > > -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dirk at gerrits.homeip.net Fri Nov 22 20:30:14 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Fri, 22 Nov 2002 20:30:14 +0100 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: References: Message-ID: <3DDE85C6.3060005@gerrits.homeip.net> David Abrahams wrote: > Dirk Gerrits writes: > > >upon deinitialization with Py_Finalize(), I > >get an error: > > > >Fatal Python error: PyThreadState_Get: no current thread > > > > The problem is that Boost.Python doesn't yet support PyFinalize(). It > keeps some PyObject references alive in global data structures, and > when those go out of scope after interpreter finalization, Python > crashes. OK, so for the moment no call to Py_Finalize(). Got it. Thanks for the explanation. > It's a fairly simple project to fix this, though it will take > some work. Patches welcome. I don't think I have the knowledge to help with this at the moment, unfortunately. > >After having fixed this though, I'd be willing to contribute this as > >an example for Boost.Python, if there is interest. I thought it was a > >pretty neat technique myself. ;) > > > Please do; It's a nice example! Thanks. I'll do some cleanup first and then post it again here. > >Before that, I'd need to Boostify the code a bit though, and I am > >wondering if all of it is necessary. For example, BaseWrap seems a > >bit superfluous since I'm only using Base's polymorphism from the C++ > >side. Any comments on this? > > > That's exactly what it's for. You if you want to override the C++ > virtual function f() in Python, you need the dispatching override in > BaseWrap. Ahh ok, thans again for clearing things up for me. Dirk Gerrits From dave at boost-consulting.com Fri Nov 22 20:37:49 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 14:37:49 -0500 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: <3DDE85C6.3060005@gerrits.homeip.net> (Dirk Gerrits's message of "Fri, 22 Nov 2002 20:30:14 +0100") References: <3DDE85C6.3060005@gerrits.homeip.net> Message-ID: Dirk Gerrits writes: > I don't think I have the knowledge to help with this at the moment, > unfortunately. Even for me, it will require some learning. I could tell you where to start, though. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Fri Nov 22 23:51:10 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 17:51:10 -0500 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: (Mark Russell's message of "Tue, 19 Nov 2002 19:32:07 -0800") References: Message-ID: Mark Russell writes: > I have modified the noddy example from the python docs to store a magic > number. I am trying to build a wrapper that will convert the magic number > of the noddy object to a win32 hwnd and back. So from python I want to > following behavior: > > magicSt is a structure that has an HWND member magicnum > >>> import noddy, cn What's cn? >>> n = noddy.noddy() >>> m = cn.magicSt() >>> m.magicnum = n You're sticking your noddy object in the magicnum attribute... >>> print m.magicnum > 453311 You could accomplish this by defining a __str__ method for your Noddy objects. > In c++ magicnum would be an HWND. The following compiles and I can > get the magicnum but when I try to set it -----------------------^^^^^^^^^^^^^^^^^^^^ What does this mean?Please be very specific when asking for help. Hmm, I decipher from the code below that you may mean >>> m.magicnum = n > I get:: TypeError: bad agrument type fro built-in operation. I have > a version of this that just converts the magic number to long and ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ How? > this works just fine. But you still want something else? > What am I missing?? I'm not sure I understand your problem, but as near as I can tell, you want Noddy objects to be converted automatically to HWND for assignment to the magicnum member of magicSt. Well, the problem is that HWND is a pointer type, and when converting a Python object to a pointer type, Boost.Python actually attempts to find an object of the pointee type. So if you want to convert to HWND, your converter's execute function must return a reference to the type that HWND points to (remove_pointer::type& if your compiler supported partial specialization, which it doesn't). > > struct convertNoddy { > static HWND& execute(PyObject& o) { > static long magic = call_method(&o, "getMagicNum"); > static HWND hmagic = reinterpret_cast(magic); > return hmagic; > } > }; > > BOOST_PYTHON_MODULE(cn) { > lvalue_from_pytype(); HTH, Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sat Nov 23 00:09:10 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 18:09:10 -0500 Subject: [C++-sig] Re: abstract base class In-Reply-To: ("Mike Rovner"'s message of "Tue, 19 Nov 2002 12:14:44 -0800") References: Message-ID: "Mike Rovner" writes: > "Nicolas Lelong" wrote in message > news:DAV39n1YcEBdyFj9ZYh00008290 at hotmail.com... >> Hi >> >> > [...] >> > class_("Operation", no_init); // line 169 >> >> You should try : >> >> class_("Operation", no_init); >> >> It works for me :) >> >> Hope this helps, > > Thank you. That works for me too ;) > > But I'm curious > (a) why that happened? Because if you don't tell it that LayerOperation is noncopyable, Boost.Python tries to register a converter for handling wrapped functions which handle function return values of type LayerOperation. Naturally, this has to be able to copy construct the returned LayerOperation object into storage that can be managed by a Python object. Since your LayerOperation is an abstract class, that fails. > (b) error message is inadequate. I guess that's not a question. Well, I'm truly sorry, but the control we poor C++ library writers get over the error messages emitted by your C++ compiler is limited at best. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Sat Nov 23 00:47:26 2002 From: mike at bindkey.com (Mike Rovner) Date: Fri, 22 Nov 2002 15:47:26 -0800 Subject: [C++-sig] Re: Re: abstract base class References: Message-ID: "David Abrahams" wrote in message news:ulm3lfbhl.fsf at boost-consulting.com... > >> You should try : > >> > >> class_("Operation", no_init); > >> > > (a) why that happened? > > Because if you don't tell it that LayerOperation is noncopyable, > Boost.Python tries to register a converter for handling wrapped > functions which handle function return values of type > LayerOperation. Naturally, this has to be able to copy construct the > returned LayerOperation object into storage that can be managed by a > Python object. Since your LayerOperation is an abstract class, that > fails. Thank you. Now it's clear. I've added that to moin.moin. > > (b) error message is inadequate. > > I guess that's not a question. Well, I'm truly sorry, but the control > we poor C++ library writers get over the error messages emitted by > your C++ compiler is limited at best. :) From mike at bindkey.com Sat Nov 23 00:54:05 2002 From: mike at bindkey.com (Mike Rovner) Date: Fri, 22 Nov 2002 15:54:05 -0800 Subject: [C++-sig] Re: Problem with vc++ 7 References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> Message-ID: "David Abrahams" wrote in message news:un0o5jxov.fsf at boost-consulting.com... > FWIW I have never had any problems testing Boost extensions built with > VC7 against a vc6 build of Python. Probably than you have never heard about that weird problem: I'm trying too setup boost129 on WinXPpro. I have VC6, VC7 and ActivePython2.2.1 installed. Unpacked boost from tar.gz. bjam (prebuild from boost site) complains: C:\BKutil\boost_1_29_0>bjam -sTOOLS=vc7 -sBUILD=release -sPYTHON_ROOT=c:\pyt hon22 don't know how to make ...patience... ...patience... ...found 2053 targets... ...updating 1 target... ...can't find 1 target... ...can't make 5 targets... ...skipped boost_python.CMD for lack of ... ...skipped boost_python.lib for lack of ... ...skipped boost_python.dll for lack of ... ...skipped boost_python.dll for lack of boost_python.dll. .. ...skipped boost_python.lib for lack of boost_python.lib. .. vc-Link libs\signals\build\bin\boost_signals.dll\vc7\release\runtime-link-dynami c\boost_signals.dll libs\signals\build\bin\boost_signals.dll\vc7\release\runtime -link-dynamic\boost_signals.lib LINK : warning LNK4089: all references to 'MSVCP70.dll' discarded by /OPT:REF ...skipped 5 targets... ...updated 1 target... And I can't understand what's wrong? A little help? Thanks, Mike From mrussell8081 at pacbell.net Sat Nov 23 00:59:44 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Fri, 22 Nov 2002 15:59:44 -0800 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: Message-ID: Hi David thanks for your reply. In your response you said: ... as near as I can tell, you want Noddy objects to be converted automatically to HWND for assignment to the magicnum member of magicSt. Well, the problem is that HWND is a pointer type, and when converting a Python object to a pointer type, Boost.Python actually attempts to find an object of the pointee type. So if you want to convert to HWND, your converter's execute function must return a reference to the type that HWND points to (remove_pointer::type& if your compiler supported partial specialization, which it doesn't). This is indeed what I am trying to do. In fact the full situation is this. I am working on a project that involves wrapping parts of DirectX8. So far I am having great success with BPL in getting this done--indeed I would not attempt this myself if I didn't have BPL to work with so great lib! Many of the structures in DirectX have a handle to the target window as a member. I am using Mark Hammond's win32ui for my windows frame and can get a representation of the window handle as an int in python. My plan is to wrap this integer value in an hwnd object and pass this object to hwnd data members in DirectX. I need the bpl wrapper to convert the integer to an HWND. I there any way to do this without the partial specialization you mentioned? Thanks again for your help. --Mark -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On Behalf Of David Abrahams Sent: Friday, November 22, 2002 2:51 PM To: c++-sig at python.org Subject: Re: [C++-sig] problems with lvalue_from_pytype Mark Russell writes: > I have modified the noddy example from the python docs to store a magic > number. I am trying to build a wrapper that will convert the magic number > of the noddy object to a win32 hwnd and back. So from python I want to > following behavior: > > magicSt is a structure that has an HWND member magicnum > >>> import noddy, cn What's cn? >>> n = noddy.noddy() >>> m = cn.magicSt() >>> m.magicnum = n You're sticking your noddy object in the magicnum attribute... >>> print m.magicnum > 453311 You could accomplish this by defining a __str__ method for your Noddy objects. > In c++ magicnum would be an HWND. The following compiles and I can > get the magicnum but when I try to set it -----------------------^^^^^^^^^^^^^^^^^^^^ What does this mean?Please be very specific when asking for help. Hmm, I decipher from the code below that you may mean >>> m.magicnum = n > I get:: TypeError: bad agrument type fro built-in operation. I have > a version of this that just converts the magic number to long and ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ How? > this works just fine. But you still want something else? > What am I missing?? I'm not sure I understand your problem, but as near as I can tell, you want Noddy objects to be converted automatically to HWND for assignment to the magicnum member of magicSt. Well, the problem is that HWND is a pointer type, and when converting a Python object to a pointer type, Boost.Python actually attempts to find an object of the pointee type. So if you want to convert to HWND, your converter's execute function must return a reference to the type that HWND points to (remove_pointer::type& if your compiler supported partial specialization, which it doesn't). > > struct convertNoddy { > static HWND& execute(PyObject& o) { > static long magic = call_method(&o, "getMagicNum"); > static HWND hmagic = reinterpret_cast(magic); > return hmagic; > } > }; > > BOOST_PYTHON_MODULE(cn) { > lvalue_from_pytype(); HTH, Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From dave at boost-consulting.com Sat Nov 23 00:57:20 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 18:57:20 -0500 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: (Mark Russell's message of "Fri, 22 Nov 2002 15:59:44 -0800") References: Message-ID: Mark Russell writes: > Hi David thanks for your reply. In your response you said: > > ... as near as I can tell, you want Noddy objects to be converted > automatically to HWND for assignment to the magicnum member of magicSt. > Well, the problem is that HWND is a pointer type, and when converting a > Python object to a pointer type, Boost.Python actually attempts to find an > object of the pointee type. So if you want to convert to HWND, your > converter's execute function must return a reference to the type that HWND > points to (remove_pointer::type& if your compiler supported partial > specialization, which it doesn't). > > This is indeed what I am trying to do. In fact the full situation is this. > I am working on a project that involves wrapping parts of DirectX8. So far > I am having great success with BPL in getting this done--indeed I would not > attempt this myself if I didn't have BPL to work with so great lib! Many of > the structures in DirectX have a handle to the target window as a member. I > am using Mark Hammond's win32ui for my windows frame and can get a > representation of the window handle as an int in python. My plan is to wrap > this integer value in an hwnd object and pass this object to hwnd data > members in DirectX. I need the bpl wrapper to convert the integer to an > HWND. I there any way to do this without the partial specialization you > mentioned? One way is just to find out what the real type of the pointee is on your own, by examining the header file. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Sat Nov 23 01:47:13 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Fri, 22 Nov 2002 16:47:13 -0800 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: Message-ID: David, From dave at boost-consulting.com Sat Nov 23 02:55:13 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 20:55:13 -0500 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: (Mark Russell's message of "Fri, 22 Nov 2002 16:47:13 -0800") References: Message-ID: Mark Russell writes: > David, > > From your last reply: > snip... > > One way is just to find out what the real type of the pointee is on your > own, by > examining the header file. > > An HWND is a pointer to an HWND__ struct defined as follows: > > struct HWND__ { int unused; }; > typedef struct HWND__* HWND > > I have attached three files noddy.cpp cn.cpp, and cnl.cpp-- cnl > contains my conversion for noddy objects just using longs cn does > the same thing using HWND. The following python session shows how > it works for longs: > > C:\developer\com-hacking\boost hacking\convert noddy long>python > Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. >>>> import noddy,cnl >>>> n=noddy.noddy() >>>> m=cnl.magic() >>>> m.magicnum > 1957 >>>> m.magicnum=n >>>> m.magicnum > 453311 >>>> > > cnl (convert noddy long) contains a struct called magic with a single data > member--magicnum. The struct initializes magicnum to 1957. Noddy's all > have an int value attribute 453311. I assign a noddy to m.magicnum > (setattr) and my converter correctly retrieves values and assigns it to the > magicnum data member. The problem is indeed occurring when I try to do the > same thing using pointers (my attempt is in cn.cpp). I just want to pass an > int from python to my converter--have the converter cast the int to an HWND > (pointer). How does knowing the real type help me in this situation? As I wrote several messages ago: > So if you want to convert to HWND, your converter's execute function > must return a reference to the type that HWND points to ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mrussell8081 at pacbell.net Sat Nov 23 04:07:08 2002 From: mrussell8081 at pacbell.net (Mark Russell) Date: Fri, 22 Nov 2002 19:07:08 -0800 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: Message-ID: David, As I understand the situation from your last reply: snip... As I wrote several messages ago: > So if you want to convert to HWND, your converter's execute function > must return a reference to the type that HWND points to ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ So if you want to convert to HWND, your converter's execute function must return a reference to the type that HWND points to (remove_pointer::type& if your compiler supported partial specialization, which it doesn't). > > struct convertNoddy { > static HWND& execute(PyObject& o) { > static long magic = call_method(&o, "getMagicNum"); > static HWND hmagic = reinterpret_cast(magic); > return hmagic; > } > }; I cannot simply cast the int to an HWND I have to use an mpl construct that describes the returned type. I have read your paper on mpl and looked through the refs--very interesting and I will want to explore this more but I can't workout how to return this. If vc supported partial specialization I take it that I could do the following: > return remove_pointer::type&hmagic; But since it doesn't I need to find a work around. It this correct? Thanks --Mark -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org]On Behalf Of David Abrahams Sent: Friday, November 22, 2002 5:55 PM To: c++-sig at python.org Subject: Re: [C++-sig] problems with lvalue_from_pytype Mark Russell writes: > David, > > From your last reply: > snip... > > One way is just to find out what the real type of the pointee is on your > own, by > examining the header file. > > An HWND is a pointer to an HWND__ struct defined as follows: > > struct HWND__ { int unused; }; > typedef struct HWND__* HWND > > I have attached three files noddy.cpp cn.cpp, and cnl.cpp-- cnl > contains my conversion for noddy objects just using longs cn does > the same thing using HWND. The following python session shows how > it works for longs: > > C:\developer\com-hacking\boost hacking\convert noddy long>python > Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. >>>> import noddy,cnl >>>> n=noddy.noddy() >>>> m=cnl.magic() >>>> m.magicnum > 1957 >>>> m.magicnum=n >>>> m.magicnum > 453311 >>>> > > cnl (convert noddy long) contains a struct called magic with a single data > member--magicnum. The struct initializes magicnum to 1957. Noddy's all > have an int value attribute 453311. I assign a noddy to m.magicnum > (setattr) and my converter correctly retrieves values and assigns it to the > magicnum data member. The problem is indeed occurring when I try to do the > same thing using pointers (my attempt is in cn.cpp). I just want to pass an > int from python to my converter--have the converter cast the int to an HWND > (pointer). How does knowing the real type help me in this situation? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From agurtovoy at meta-comm.com Sat Nov 23 04:17:56 2002 From: agurtovoy at meta-comm.com (Aleksey Gurtovoy) Date: Fri, 22 Nov 2002 21:17:56 -0600 Subject: [C++-sig] problems with lvalue_from_pytype Message-ID: <4034600A4760D411B8720001031D84FB01096555@postoffice.office.meta> Mark Russell wrote: > If vc supported partial specialization I take it that I could > do the following: > > > return remove_pointer::type&hmagic; > > But since it doesn't I need to find a work around. All you need to do to make the above work on MSVC (or any other compiler that does not support partial class template specialization) is to write #include "boost/type_traits/broken_compiler_spec.hpp" BOOST_TT_BROKEN_COMPILER_SPEC(HWND) somewhere in a header that gets included everywhere where the type traits constructs are used on HWNDs. HTH, Aleksey From dave at boost-consulting.com Sat Nov 23 04:07:35 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 22:07:35 -0500 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: (Mark Russell's message of "Fri, 22 Nov 2002 19:07:08 -0800") References: Message-ID: Mark Russell writes: > David, > > As I understand the situation from your last reply: > > snip... > > As I wrote several messages ago: > >> So if you want to convert to HWND, your converter's execute function >> must return a reference to the type that HWND points to > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > > > So if you want to convert to HWND, your converter's > execute function must return a reference to the type that HWND points > to (remove_pointer::type& if your compiler supported partial > specialization, which it doesn't). > >> >> struct convertNoddy { >> static HWND& execute(PyObject& o) { >> static long magic = call_method(&o, "getMagicNum"); >> static HWND hmagic = reinterpret_cast(magic); >> return hmagic; >> } >> }; > > I cannot simply cast the int to an HWND I have to use an mpl construct that > describes the returned type. ??? No, that's why I asked you to: >> find out what the real type of the pointee is on your own And didn't you just tell me that: >> An HWND is a pointer to an HWND__ struct defined as follows: >> >> struct HWND__ { int unused; }; >> typedef struct HWND__* HWND So, ask yourself: 1. what type does HWND point to? 2. Can you form a reference to that type? 3. Given an HWND__*, how can you get a HWND__&? OK, I'll spell it out for you: static HWND__& execute(PyObject& o) { ... return *hmagic; } > I have read your paper on mpl and looked through the refs--very > interesting and I will want to explore this more but I can't workout > how to return this. If vc supported partial specialization I take > it that I could do the following: > >> return remove_pointer::type&hmagic; Uh, that's sort of like saying return int&x; which wouldn't be legal C++ anyway. > But since it doesn't I need to find a work around. It this correct? I think you're making this too complicated. If you don't see the answer at this point, please re-read the thread very carefully. From dave at boost-consulting.com Sat Nov 23 04:15:51 2002 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 22 Nov 2002 22:15:51 -0500 Subject: [C++-sig] problems with lvalue_from_pytype In-Reply-To: <4034600A4760D411B8720001031D84FB01096555@postoffice.office.meta> (Aleksey Gurtovoy's message of "Fri, 22 Nov 2002 21:17:56 -0600") References: <4034600A4760D411B8720001031D84FB01096555@postoffice.office.meta> Message-ID: Aleksey Gurtovoy writes: > Mark Russell wrote: >> If vc supported partial specialization I take it that I could >> do the following: >> >> > return remove_pointer::type&hmagic; >> >> But since it doesn't I need to find a work around. > > All you need to do to make the above work on MSVC (or any other compiler > that does not support partial class template specialization) is to write > > #include "boost/type_traits/broken_compiler_spec.hpp" > BOOST_TT_BROKEN_COMPILER_SPEC(HWND) > > somewhere in a header that gets included everywhere where the type traits > constructs are used on HWNDs. Ahh, wouldn't that have to be #include "boost/type_traits/broken_compiler_spec.hpp" BOOST_TT_BROKEN_COMPILER_SPEC(HWND__) ^^ ?? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From agurtovoy at meta-comm.com Sat Nov 23 05:39:43 2002 From: agurtovoy at meta-comm.com (Aleksey Gurtovoy) Date: Fri, 22 Nov 2002 22:39:43 -0600 Subject: [C++-sig] problems with lvalue_from_pytype Message-ID: <4034600A4760D411B8720001031D84FB01096556@postoffice.office.meta> David Abrahams wrote: > Ahh, wouldn't that have to be > > > #include "boost/type_traits/broken_compiler_spec.hpp" > BOOST_TT_BROKEN_COMPILER_SPEC(HWND__) > ^^ > ?? Err, of course. Aleksey From dirk at gerrits.homeip.net Sat Nov 23 17:00:27 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Sat, 23 Nov 2002 17:00:27 +0100 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: References: <3DDE85C6.3060005@gerrits.homeip.net> Message-ID: <3DDFA61B.1070402@gerrits.homeip.net> I attached the promised cleanup of my little example. I made it a bit more consistent with the documentation code and changed the boring f() into hello(). :) Feel free to use my example in the documentation or /libs/python/example or whatever. I haven't yet written a Jamfile though. I don't have much experience with those. Regards, Dirk Gerrits -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: embedded_hello.cpp URL: From n_lelong at hotmail.com Sat Nov 23 21:14:21 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Sat, 23 Nov 2002 21:14:21 +0100 Subject: [C++-sig] VC7 + auto_ptr + transfer of owership Message-ID: >auto_ptr support is only really complete in the current CVS >version. There are some problems with it in 1.29.0. Huhf, I'm afraid that I checkouted the yesterday's version, and that's the one that causes the problem ! Any idea ? Thanks, Nicolas _________________________________________________________________ Protect your PC - get McAfee.com VirusScan Online http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963 From dave at boost-consulting.com Sat Nov 23 21:17:40 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Nov 2002 15:17:40 -0500 Subject: [C++-sig] Incrementing reference count of returned object pointer In-Reply-To: <3DDD9CCD.9060703@vrac.iastate.edu> (Patrick Hartling's message of "Thu, 21 Nov 2002 20:56:13 -0600") References: <3DDBF719.5010308@vrac.iastate.edu> <3DDD9CCD.9060703@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > Patrick Hartling wrote: > >> Base* obj = boost::python::call(factory_func); > > Okay, I think I got this worked out. Instead of the above, I am doing > the following (assuming namespace python = boost::python): > > python::object base_obj = python::call(factory_func); > Base* obj = python::extract(base_obj); > > This seems to do the trick. Is there anything fundamentally wrong > with this? Nothing fundamental. Of course if you were getting the dangling reference exception when using call, it's an indication that base_obj (or a copy) must survive at least as long as obj does, or it will be dangling again (and I can't protect you from that by throwing a nice exception ;->). -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sat Nov 23 23:09:17 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Nov 2002 17:09:17 -0500 Subject: [C++-sig] Workaround for fatal error C1204 Message-ID: If you've been getting fatal error C1204:Compiler limit:internal structure overflow messages with VC6 and/or VC7, you might find they go away after updating to the latest CVS. I've checked in a workaround for some of the ways in which this can occur. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Sat Nov 23 23:27:03 2002 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Sat, 23 Nov 2002 14:27:03 -0800 Subject: [C++-sig] Workaround for fatal error C1204 In-Reply-To: References: Message-ID: <200211232227.gANMR3713169@libra3.slac.stanford.edu> >>>>> On Sat, 23 Nov 2002 17:09:17 -0500, David Abrahams said: > If you've been getting > fatal error C1204:Compiler limit:internal structure overflow > messages with VC6 and/or VC7, you might find they go away after > updating to the latest CVS. I've checked in a workaround for some of > the ways in which this can occur. Does this mean I will no longer need to "/Zm1000" compiler option to work around the above? From dave at boost-consulting.com Sun Nov 24 00:34:25 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Nov 2002 18:34:25 -0500 Subject: [C++-sig] Workaround for fatal error C1204 In-Reply-To: <200211232227.gANMR3713169@libra3.slac.stanford.edu> ("Paul F. Kunz"'s message of "Sat, 23 Nov 2002 14:27:03 -0800") References: <200211232227.gANMR3713169@libra3.slac.stanford.edu> Message-ID: "Paul F. Kunz" writes: >>>>>> On Sat, 23 Nov 2002 17:09:17 -0500, David Abrahams said: > >> If you've been getting > >> fatal error C1204:Compiler limit:internal structure overflow > >> messages with VC6 and/or VC7, you might find they go away after >> updating to the latest CVS. I've checked in a workaround for some of >> the ways in which this can occur. > > Does this mean I will no longer need to "/Zm1000" compiler option > to work around the above? No, /ZmXXXX has a different effect, and as far as I can tell has no effect on C1204 errors. I suggest leaving /Zm set to a high value always, as doing otherwise invites disaster. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 24 01:16:07 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Nov 2002 19:16:07 -0500 Subject: [C++-sig] function as custom ctor In-Reply-To: <20021119170112.11649.qmail@web20204.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Tue, 19 Nov 2002 09:01:12 -0800 (PST)") References: <20021119170112.11649.qmail@web20204.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: >> > Can I pass this funktion to boost.python in a way, that I could be used as >> > ctor? Something like this: >> > >> > class_("Blob",init<>()) >> > .def( ??? , createBlob ); >> > >> > and then from Python: >> > >> > data = "a string with data to be passed to the blob" >> > blob = Blob(data) >> >> Not quite, but you can fake it: >> >> First expose your class with no_init, then expose createBlob as >> "Blob". > > Can there be both a class_("Blob", ...) /with constructors/ > and a free factory function def("Blob", ...)? Can there even be > multiple constructors and factory functions? Not using the fakery technique above. However, it should be fairly simple to make this capability available in a more-straightforward manner. I'll take a look at it. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 24 03:31:39 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Nov 2002 21:31:39 -0500 Subject: [C++-sig] Re: debuging In-Reply-To: (Greg Burley's message of "20 Nov 2002 11:15:40 +1000") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD75F@admin56.narex.com> Message-ID: Greg Burley writes: > Hi Mike, > > What's wrong with using gdb and stepping through your code. See notes > that follow ... Thanks, Greg! I'm going to add this to the FAQ if you don't mind... -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Sun Nov 24 04:06:01 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 23 Nov 2002 22:06:01 -0500 Subject: [C++-sig] Re: Re: debuging In-Reply-To: <20021120033434.GA31687@upl.cs.wisc.edu> (Adam Hupp's message of "Tue, 19 Nov 2002 21:34:34 -0600") References: <20021119222815.41802.qmail@web20206.mail.yahoo.com> <20021120033434.GA31687@upl.cs.wisc.edu> Message-ID: Adam Hupp writes: > On Tue, Nov 19, 2002 at 06:05:13PM -0500, David Abrahams wrote: >> > >> > What is the problem? Write the demangler? Can you explain it a >> > little, please? >> >> That's part of it. See: >> >> http://mail.python.org/pipermail/c++-sig/2002-June/001277.html > > > Unless I'm missing something, with g++ >= 3.1 you can use > abi::__cxa_demangle to do this. Attached is an example. Docs can be > found at > http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.2/namespaceabi.html Thanks, Adam! I have a volunteer who's looking at the problem of providing good error messages now; I've forwarded him your advice. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 03:52:42 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 24 Nov 2002 21:52:42 -0500 Subject: [C++-sig] Passing C++ arrays as arguments In-Reply-To: <194252432218.20021118201158@hotbox.ru> (Kerim Borchaev's message of "Mon, 18 Nov 2002 20:11:58 +0300") References: <194252432218.20021118201158@hotbox.ru> Message-ID: Kerim Borchaev writes: > Hello. > > I'm exposing to Python some third party library wich has an API like > this: > > struct Abstract{ > virtual void f(float[16])=0; Well, this function signature is really, truly equivalent to virtual void f(float*) = 0; So Boost.Python can't tell anything about the size of that array. It just sees a float* (unless you're using Visual C++, which broken-ly makes the argument type different from float*... but Boost.Python doesn't do anything special with the information in that case). > }; > > Abstract *createInstance(); > > with this code: > > def("createInstance", createInstance, return_value_policy()); > class_("Abstract", no_init) > .def("f", Abstract::f); OK > Can I simply define some from python tuple to float[16] converter so > that I can call object returned from createInstance like this: > createInstance().f((0,)*16) ? Nope. That's the problem with your function signature. It doesn't capture any information about the number of elements. I suggest you look at Ralf Grosse-Kunstleve's work described in the Boost.Python FAQ, and use boost::array if you can. -Dave -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 04:44:55 2002 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 24 Nov 2002 22:44:55 -0500 Subject: [C++-sig] MSVC project file [UPDATED] In-Reply-To: <007101c28a25$291ec2a0$2e6e4fcb@hare> ("Brett Calcott"'s message of "Tue, 12 Nov 2002 21:26:10 +1300") References: <003901c287bc$c078f870$2e6e4fcb@hare> <007101c28a25$291ec2a0$2e6e4fcb@hare> Message-ID: "Brett Calcott" writes: > Here's one that fixes the errors Scott mentioned. > Hmm. I tried your project file, after dropping it in $BOOST_ROOT/libs/python/build/VisualStudio, and just got a lot of these: --------------------Configuration: boost_python - Win32 DebugPython-------------------- Compiling... aix_init_module.cpp arg_to_python_base.cpp C:\\boost\\libs\\python\\src\\converter\\arg_to_python_base.cpp(7): catastrophic error: could not open source file "boost/python/converter/arg_to_python_base.hpp" #include ^ builtin_converters.cpp compilation aborted for C:\boost\libs\python\src\converter\arg_to_python_base.cpp (code 4) C:\\boost\\libs\\python\\src\\converter\\builtin_converters.cpp(7): catastrophic error: could not open source file "boost/python/detail/config.hpp" #include ^ class.cpp compilation aborted for C:\boost\libs\python\src\converter\builtin_converters.cpp (code 4) C:\\boost\\libs\\python\\src\\object\\class.cpp(6): catastrophic error: could not open source file "boost/python/object/class.hpp" #include ^ ... Did I do something wrong? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Mon Nov 25 07:12:10 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Mon, 25 Nov 2002 19:12:10 +1300 Subject: [C++-sig] MSVC project file [UPDATED] In-Reply-To: References: <003901c287bc$c078f870$2e6e4fcb@hare> <007101c28a25$291ec2a0$2e6e4fcb@hare> Message-ID: <20021125061210.GA1232@HARE> On Nov 24 22:44, David Abrahams wrote: > "Brett Calcott" writes: > > > Here's one that fixes the errors Scott mentioned. > > > > Hmm. I tried your project file, after dropping it in > $BOOST_ROOT/libs/python/build/VisualStudio, and just got a lot of > these: > > --------------------Configuration: boost_python - Win32 DebugPython-------------------- > Compiling... > aix_init_module.cpp > arg_to_python_base.cpp > C:\\boost\\libs\\python\\src\\converter\\arg_to_python_base.cpp(7): catastrophic error: could not open source file "boost/python/converter/arg_to_python_base.hpp" > #include > ^ > builtin_converters.cpp > compilation aborted for C:\boost\libs\python\src\converter\arg_to_python_base.cpp (code 4) > C:\\boost\\libs\\python\\src\\converter\\builtin_converters.cpp(7): catastrophic error: could not open source file "boost/python/detail/config.hpp" > #include > ^ > class.cpp > compilation aborted for C:\boost\libs\python\src\converter\builtin_converters.cpp (code 4) > C:\\boost\\libs\\python\\src\\object\\class.cpp(6): catastrophic error: could not open source file "boost/python/object/class.hpp" > #include > ^ > > ... > > Did I do something wrong? > Yeah, you didn't read the non-existent documentation :) There are two ways of setting include paths in VS. You can add them under: Project/Settings/C++/Preprocessor/Additional Include Directories which makes them project specific, or you can add them under the Tools/Options/Directories/Include Files, which makes them global to all projects. Given that people may put $BOOST_ROOT wherever they want, I typically define stlport and boost stuff at the global level, rather than expose my particular setup to the world. This means I can quickly switch versions too. *However*, as this file will exist within the boost tree, I can add the relative include path to the project file. I didn't think to do this as I had already got my global definition going. I will make this fix in the one I submit with the docs which should happen soonish... I have been quiet cos' I need to finish some writing - then I'll be back to look at this pointer stuff again too. Brett From n_lelong at hotmail.com Mon Nov 25 10:21:25 2002 From: n_lelong at hotmail.com (Nicolas Lelong) Date: Mon, 25 Nov 2002 10:21:25 +0100 Subject: [C++-sig] VC7 + auto_ptr + transfer of owership References: Message-ID: > >auto_ptr support is only really complete in the current CVS > >version. There are some problems with it in 1.29.0. > > Huhf, I'm afraid that I checkouted the yesterday's version, and that's the > one that causes the problem ! > My fault ! I've fumbled my checkout !... sorry for the trouble. Thanks, Nicolas From dave at boost-consulting.com Mon Nov 25 16:04:49 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 10:04:49 -0500 Subject: [C++-sig] MSVC project file [UPDATED] In-Reply-To: <20021125061210.GA1232@HARE> (Brett Calcott's message of "Mon, 25 Nov 2002 19:12:10 +1300") References: <003901c287bc$c078f870$2e6e4fcb@hare> <007101c28a25$291ec2a0$2e6e4fcb@hare> <20021125061210.GA1232@HARE> Message-ID: Brett Calcott writes: > Yeah, you didn't read the non-existent documentation :) > > There are two ways of setting include paths in VS. You can add them > under: Project/Settings/C++/Preprocessor/Additional Include Directories > which makes them project specific, or you can add them under the > Tools/Options/Directories/Include Files, which makes them global to all > projects. Given that people may put $BOOST_ROOT wherever they want, I > typically define stlport and boost stuff at the global level, rather > than expose my particular setup to the world. This means I can quickly > switch versions too. *However*, as this file will exist within the boost > tree, I can add the relative include path to the project file. I chose that particular location in the Boost tree based on the paths I saw in your file, which seemed to indicate that it was to be located in libs/python/<...>/<...>. > I didn't think to do this as I had already got my global definition > going. I will make this fix in the one I submit with the docs which > should happen soonish... > > I have been quiet cos' I need to finish some writing - then I'll be > back to look at this pointer stuff again too. OK. Peter has made the get_deleter patch I requested, so this is going to be very exciting. I'll be happy to work with you on it. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 17:33:16 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 11:33:16 -0500 Subject: [C++-sig] Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Fri, 22 Nov 2002 15:54:05 -0800") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:un0o5jxov.fsf at boost-consulting.com... >> FWIW I have never had any problems testing Boost extensions built with >> VC7 against a vc6 build of Python. > > Probably than you have never heard about that weird problem: > > I'm trying too setup boost129 on WinXPpro. > > I have VC6, VC7 and ActivePython2.2.1 installed. > Unpacked boost from tar.gz. > bjam (prebuild from boost site) complains: Yes, that's a very weird problem! I would expect to see a target name... > > C:\BKutil\boost_1_29_0>bjam -sTOOLS=vc7 -sBUILD=release -sPYTHON_ROOT=c:\pyt > hon22 > don't know how to make ^---------- HERE > ...patience... > ...patience... > ...found 2053 targets... > ...updating 1 target... > ...can't find 1 target... > ...can't make 5 targets... > ...skipped > > boost_python.CMD for lack of ... ^------- AND HERE > And I can't understand what's wrong? Me neither. The only thing I can guess is that you have a trailing space on your command-line and that is somehow getting parsed as a target name. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 17:59:27 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 11:59:27 -0500 Subject: [C++-sig] debuging In-Reply-To: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD75F@admin56.narex.com> ("Bjorn Pettersen"'s message of "Tue, 19 Nov 2002 14:28:01 -0700") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD75F@admin56.narex.com> Message-ID: "Bjorn Pettersen" writes: >> From: Mike Rovner [mailto:mike at bindkey.com] >> >> Howdy, folks. >> >> How do you debug BPL applications? >> >> I just got 'TypeError: bad argument type for built-in >> operation' and have absolutely no idea what to do next. > > Sounds like you need to get the traceback... Here's how I do it (you'll > probably want to modify it to throw a more standard exception ;-) Wow, yeah! Throwing the result of a new-expression is a very bad practice! Anyway, I'd like to use a modified version of this code in the Boost.Python tests if you don't mind... OK with you, Bjorn? > -- bjorn > > std::string getTraceback() { > std::string result; > PyObject *exception, *v, *traceback; > PyErr_Fetch(&exception, &v, &traceback); > PyErr_NormalizeException(&exception, &v, &traceback); > > /* > import traceback > lst = traceback.format_exception(exception, v, traceback) > for line in lst: > result += line > */ > PyObject* tbstr = PyString_FromString("traceback"); > PyObject* tbmod = PyImport_Import(tbstr); > if (!tbmod) throw new NException("Unable to import traceback > module. Is your Python installed?", N_EX_NULL); > PyObject* tbdict = PyModule_GetDict(tbmod); > PyObject* formatFunc = PyDict_GetItemString(tbdict, > "format_exception"); > if (!formatFunc) throw new NException("Can't find > traceback.format_exception", N_EX_NULL); > if (!traceback) { > traceback = Py_None; > Py_INCREF(Py_None); > } > PyObject* args = Py_BuildValue("(OOO)", exception, v, > traceback); > PyObject* lst = PyObject_CallObject(formatFunc, args); > > for (int i=0; i result += PyString_AsString(PyList_GetItem(lst, i)); > } > > Py_DECREF(args); > Py_DECREF(lst); > return result; > } -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Mon Nov 25 18:17:36 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 25 Nov 2002 09:17:36 -0800 Subject: [C++-sig] Re: Re: Problem with vc++ 7 References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> Message-ID: "David Abrahams" wrote in message news:uisylzk1f.fsf at boost-consulting.com... > Yes, that's a very weird problem! I would expect to see a target name... > > > > C:\BKutil\boost_1_29_0>bjam -sTOOLS=vc7 -sBUILD=release -sPYTHON_ROOT=c:\pyt > > hon22 > > don't know how to make > ^---------- HERE > > boost_python.CMD for lack of ... > ^------- AND HERE > > > And I can't understand what's wrong? > > Me neither. The only thing I can guess is that you have a trailing > space on your command-line and that is somehow getting parsed as a > target name. Nope. I tried with -s inline and in environment. Either way result is the same. :( And even when I say 'bjam dll' the output is the same (without target name). Mike From dave at boost-consulting.com Mon Nov 25 19:19:19 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 13:19:19 -0500 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: <3DDFA61B.1070402@gerrits.homeip.net> (Dirk Gerrits's message of "Sat, 23 Nov 2002 17:00:27 +0100") References: <3DDE85C6.3060005@gerrits.homeip.net> <3DDFA61B.1070402@gerrits.homeip.net> Message-ID: Dirk Gerrits writes: > I attached the promised cleanup of my little example. I made it a bit > more consistent with the documentation code and changed the boring f() > into hello(). :) > > Feel free to use my example in the documentation or > /libs/python/example or whatever. I haven't yet written a Jamfile > though. I don't have much experience with those. I had to modify your test quite a bit, but I checked it into libs/python/test/embedding.cpp, and the Jamfile now runs it. Thanks for your contribution! Unfortunately, I couldn't keep the "print" statements. Something about running the test under NTEmacs (my usual setup) was suppressing all of Python's output to stdout. If you could write up a short HTML page in the documentation describing what people need to know in order to embed Boost.Python extensions, that would be hugely appreciated as well. Thanks again, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 19:20:56 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 13:20:56 -0500 Subject: [C++-sig] Re: Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Mon, 25 Nov 2002 09:17:36 -0800") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:uisylzk1f.fsf at boost-consulting.com... >> Yes, that's a very weird problem! I would expect to see a target name... >> > >> > > C:\BKutil\boost_1_29_0>bjam -sTOOLS=vc7 -sBUILD=release -sPYTHON_ROOT=c:\pyt >> > hon22 >> > don't know how to make >> ^---------- HERE >> > boost_python.CMD for lack of ... >> ^------- AND HERE >> >> > And I can't understand what's wrong? >> >> Me neither. The only thing I can guess is that you have a trailing >> space on your command-line and that is somehow getting parsed as a >> target name. > > Nope. I tried with -s inline and in environment. Either way result is the > same. :( > And even when I say 'bjam dll' the output is the same (without target name). Have you rebuilt your bjam recently? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 19:22:18 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 13:22:18 -0500 Subject: [C++-sig] debuging In-Reply-To: (David Abrahams's message of "Mon, 25 Nov 2002 11:59:27 -0500") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD75F@admin56.narex.com> Message-ID: David Abrahams writes: > "Bjorn Pettersen" writes: > >>> From: Mike Rovner [mailto:mike at bindkey.com] >>> >>> Howdy, folks. >>> >>> How do you debug BPL applications? >>> >>> I just got 'TypeError: bad argument type for built-in >>> operation' and have absolutely no idea what to do next. >> >> Sounds like you need to get the traceback... Here's how I do it (you'll >> probably want to modify it to throw a more standard exception ;-) > > Wow, yeah! Throwing the result of a new-expression is a very bad > practice! > > Anyway, I'd like to use a modified version of this code in the > Boost.Python tests if you don't mind... > > OK with you, Bjorn? Hmm, I tried to use it in libs/python/test/embedding.cpp, but couldn't get it to work. It seems the standard traceback module can't be accessed from an embedded application without some extra help, which I can't figure out right now. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Mon Nov 25 20:02:31 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 25 Nov 2002 11:02:31 -0800 (PST) Subject: [C++-sig] Passing C++ arrays as arguments In-Reply-To: Message-ID: <20021125190231.40890.qmail@web20207.mail.yahoo.com> I already made an attempt to answer this question: http://mail.python.org/pipermail/c++-sig/2002-November/002650.html Is there a problem when following my advice? Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus ? Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From mike at bindkey.com Mon Nov 25 20:32:04 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 25 Nov 2002 11:32:04 -0800 Subject: [C++-sig] Re: Re: Re: Problem with vc++ 7 References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> Message-ID: "David Abrahams" wrote in message news:un0nxbjef.fsf at boost-consulting.com... > > And even when I say 'bjam dll' the output is the same (without target name). > > Have you rebuilt your bjam recently? Same result with bjam from web and freshly rebuild bjam from 1.29 distro. :( Output with d2 is too big for me (~800k) to find the problem. Mike From dave at boost-consulting.com Mon Nov 25 19:53:52 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 13:53:52 -0500 Subject: [C++-sig] Passing C++ arrays as arguments In-Reply-To: <20021125190231.40890.qmail@web20207.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Mon, 25 Nov 2002 11:02:31 -0800 (PST)") References: <20021125190231.40890.qmail@web20207.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > I already made an attempt to answer this question: > > http://mail.python.org/pipermail/c++-sig/2002-November/002650.html > > Is there a problem when following my advice? Probably not. I was just clearing my mailbox... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From cleung at eos.ubc.ca Mon Nov 25 22:18:11 2002 From: cleung at eos.ubc.ca (Charles Leung) Date: Mon, 25 Nov 2002 21:18:11 -0000 (GMT) Subject: [C++-sig] defining bjam rules... Message-ID: <33793.137.82.23.136.1038259091.squirrel@webmail.eos.ubc.ca> Hi all, I'm trying to implement rules for bjam to install my current project but I can't get bjam to execute the 'actions' statement that I defined in my Jamfile. Following is an example code that I can't get it to run. ECHO_ ?= echo ; rule COUT { COUT_ $(<) ; } actions COUT_ { $(ECHO_) $(<) } rule my_rules { DEPENDS $(<) : $(>) ; COUT $(>) ; } rule make_rule { exe $(<) : $(>) ; LINKLIBS on $(<)$(SUFEXE) = -lm ; my_rules $(<) : hello world ; } make_rule testit : test.cc ; I tried running something simular using ftjam and it works fine. Am I missing something here? Thanks, Charles From mike at bindkey.com Mon Nov 25 22:23:10 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 25 Nov 2002 13:23:10 -0800 Subject: [C++-sig] Re: Problem with vc++ 7 References: <20021118234634.40507.qmail@web20202.mail.yahoo.com><200211191557.gAJFvKu13884@libra3.slac.stanford.edu><200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: I am a complete stranger to Jam and scanning manual and tutorial seems to confirm that "Jam has simple yet unintuitive language." "David Abrahams" wrote in message news:ufztuwhkc.fsf at boost-consulting.com... > This is why I tell people to use Jamfiles. > > subproject libs/python/user ; > > # bring in the rules for python > SEARCH on python.jam = $(BOOST_BUILD_PATH) ; > include python.jam ; > > extension hippo : PyApp.cxx pyhippo.cxx ../build/boost_python ; > boost-python-runtest hippo : test.py hippo ; How to include my files from c:/a/b/c/include dir and libs (say c:/d/e/f.lib)? When I say: extension t1 : t1.cpp ../build/boost_python c:/a/b/c/include c:/d/e/f ; bjam complains: C:/d/e/Jamfile : No such file C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1455: in find-compatible-subvariant *** argument error * rule is-link-compatible ( feature : value1 : value2 ) * called with: ( : PYD : ) * missing argument value2 C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1416:see definition of rule 'is-link-compatible' being called C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1502: in link-libraries C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1710: in subvariant-target C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1797: in main-target C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1330: in declare-local-target C:\BKutil\boost_1_29_0\tools\build\python.jam:302: in extension Jamfile:29: in load-jamfiles C:\BKutil\boost_1_29_0\tools\build\bootstrap.jam:15: in boost-build C:\BKutil\boost_1_29_0\boost-build.jam:2: in module scope IMHO It would be good addition to FAQ (building section). Thanks, Mike From dirk at gerrits.homeip.net Mon Nov 25 22:27:51 2002 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Mon, 25 Nov 2002 22:27:51 +0100 Subject: [C++-sig] Re: Contributing an embedding example (after a bugfix ;) In-Reply-To: References: <3DDE85C6.3060005@gerrits.homeip.net> <3DDFA61B.1070402@gerrits.homeip.net> Message-ID: David Abrahams wrote: > I had to modify your test quite a bit, but I checked it into > libs/python/test/embedding.cpp, and the Jamfile now runs it. Thanks > for your contribution! You're welcome. You'll want to remove the #include for scoped_ptr too though, since it's not used anymore. My example also had a PythonDerived class on the C++ side because I wanted to be able to easily create instances of the class and store them in a container of shared_ptr along with CppDerived instances. I used scoped_ptr without a container to make the example smallar, but I think your changes made the example cleaner still. > Unfortunately, I couldn't keep the "print" statements. Something about > running the test under NTEmacs (my usual setup) was suppressing all of > Python's output to stdout. Well the returning of a string is more in lieu with the Tutorial anyway. ;) > If you could write up a short HTML page in the documentation > describing what people need to know in order to embed Boost.Python > extensions, that would be hugely appreciated as well. Sure! I have prelims though. This will have to wait till the weekend. ;) Should it be in QuickDoc format for the Tutorial or should it be more of a HTML FAQ entry? Regards, Dirk Gerrits From dave at boost-consulting.com Mon Nov 25 22:32:43 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 16:32:43 -0500 Subject: [C++-sig] Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Mon, 25 Nov 2002 13:23:10 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "Mike Rovner" writes: > I am a complete stranger to Jam and scanning manual and tutorial seems to > confirm that "Jam has simple yet unintuitive language." > > "David Abrahams" wrote in message > news:ufztuwhkc.fsf at boost-consulting.com... >> This is why I tell people to use Jamfiles. >> >> subproject libs/python/user ; >> >> # bring in the rules for python >> SEARCH on python.jam = $(BOOST_BUILD_PATH) ; >> include python.jam ; >> >> extension hippo : PyApp.cxx pyhippo.cxx ../build/boost_python ; >> boost-python-runtest hippo : test.py hippo ; > > How to include my files from c:/a/b/c/include dir and libs (say > c:/d/e/f.lib)? > > When I say: > extension t1 : t1.cpp > ../build/boost_python You need a colon here. Sources and dependencies are a separate argument from requirements > c:/a/b/c/include Oh, and the library below needs to go with the sources and the other dependency. You can read all about this at http://www.boost.org/tools/build/build_system.htm > c:/d/e/f > ; > IMHO It would be good addition to FAQ (building section). Please submit a patch which explains whatever you think needs to be clarified. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From grafik666 at redshift-software.com Mon Nov 25 22:48:25 2002 From: grafik666 at redshift-software.com (Rene Rivera) Date: Mon, 25 Nov 2002 15:48:25 -0600 Subject: [C++-sig] Re: Problem with vc++ 7 In-Reply-To: Message-ID: <20021125154826-r01010800-8e171464-0860-0108@12.100.89.43> [2002-11-25] Mike Rovner wrote: >I am a complete stranger to Jam and scanning manual and tutorial seems to >confirm that "Jam has simple yet unintuitive language." > >"David Abrahams" wrote in message >news:ufztuwhkc.fsf at boost-consulting.com... >> This is why I tell people to use Jamfiles. >> >> subproject libs/python/user ; >> >> # bring in the rules for python >> SEARCH on python.jam = $(BOOST_BUILD_PATH) ; >> include python.jam ; >> >> extension hippo : PyApp.cxx pyhippo.cxx ../build/boost_python ; >> boost-python-runtest hippo : test.py hippo ; > >How to include my files from c:/a/b/c/include dir and libs (say >c:/d/e/f.lib)? > >When I say: > extension t1 : t1.cpp > ../build/boost_python > c:/a/b/c/include > c:/d/e/f > ; > >bjam complains: > >C:/d/e/Jamfile : No such file >C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1455: in >find-compatible-subvariant >*** argument error >* rule is-link-compatible ( feature : value1 : value2 ) >* called with: ( : PYD : ) >* missing argument value2 >C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1416:see definition of >rule 'is-link-compatible' being called >C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1502: in link-libraries >C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1710: in subvariant-target >C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1797: in main-target >C:\BKutil\boost_1_29_0\tools\build\boost-base.jam:1330: in >declare-local-target >C:\BKutil\boost_1_29_0\tools\build\python.jam:302: in extension >Jamfile:29: in load-jamfiles >C:\BKutil\boost_1_29_0\tools\build\bootstrap.jam:15: in boost-build >C:\BKutil\boost_1_29_0\boost-build.jam:2: in module scope > >IMHO It would be good addition to FAQ (building section). This is an example of how bad the error messages in BBv1 are :-( Hopefuly BBv2 will be better behaved in this regard. The problem is that "some/path" is an inter sub/project dependency. That is, it's a denpendency to a "lib somelib : ..." target. I'm not totally sure what your intent is. But you probably want "C:/d/e/f.lib" instead. -- grafik - Don't Assume Anything -- rrivera at acm.org - grafik at redshift-software.com -- 102708583 at icq - Grafik666 at AIM - Grafik at jabber.org From grafik666 at redshift-software.com Mon Nov 25 22:56:25 2002 From: grafik666 at redshift-software.com (Rene Rivera) Date: Mon, 25 Nov 2002 15:56:25 -0600 Subject: [C++-sig] defining bjam rules... In-Reply-To: <33793.137.82.23.136.1038259091.squirrel@webmail.eos.ubc.ca> Message-ID: <20021125155626-r01010800-6e357207-0860-0108@12.100.89.43> [2002-11-25] Charles Leung wrote: >Hi all, > >I'm trying to implement rules for bjam to install my current project but I >can't get bjam to execute the 'actions' statement that I defined in my >Jamfile. Following is an example code that I can't get it to run. > > > >ECHO_ ?= echo ; > > >rule COUT >{ > COUT_ $(<) ; >} > >actions COUT_ >{ > $(ECHO_) $(<) >} > >rule my_rules >{ > DEPENDS $(<) : $(>) ; > COUT $(>) ; >} > Hmm... I think the missing info is that the $(<) is not the target name generated by the "exe" rule. It expands the same to include any extension based on the OS it runs. >rule make_rule >{ > exe $(<) : $(>) ; > LINKLIBS on $(<)$(SUFEXE) = -lm ; > my_rules $(<) : hello world ; >} So try "my_rule $(<)$(SUFEXE) : hello world ;" instead above, and see if you get the results you expect. >make_rule testit : test.cc ; > > > >I tried running something simular using ftjam and it works fine. Am I >missing something here? -- grafik - Don't Assume Anything -- rrivera at acm.org - grafik at redshift-software.com -- 102708583 at icq - Grafik666 at AIM - Grafik at jabber.org From dave at boost-consulting.com Mon Nov 25 22:42:47 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 16:42:47 -0500 Subject: [C++-sig] defining bjam rules... In-Reply-To: <33793.137.82.23.136.1038259091.squirrel@webmail.eos.ubc.ca> ("Charles Leung"'s message of "Mon, 25 Nov 2002 21:18:11 -0000 (GMT)") References: <33793.137.82.23.136.1038259091.squirrel@webmail.eos.ubc.ca> Message-ID: "Charles Leung" writes: > Hi all, > > I'm trying to implement rules for bjam to install my current project but I > can't get bjam to execute the 'actions' statement that I defined in my > Jamfile. Following is an example code that I can't get it to run. > > > > ECHO_ ?= echo ; > > > rule COUT > { > COUT_ $(<) ; > } > > actions COUT_ > { > $(ECHO_) $(<) > } > > rule my_rules > { > DEPENDS $(<) : $(>) ; > COUT $(>) ; > } > > rule make_rule > { > exe $(<) : $(>) ; > LINKLIBS on $(<)$(SUFEXE) = -lm ; > my_rules $(<) : hello world ; > } > > make_rule testit : test.cc ; > > > > I tried running something simular using ftjam and it works fine. Am I > missing something here? Lots. Boost.Build is a higher-order build system than FTJam, and so you need different techniques. Please try your Boost.Build questions on the yahoo group at http://www.yahoogroups.com/groups/jamboost Regards, -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 23:41:21 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 17:41:21 -0500 Subject: [C++-sig] Re: Re: Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Mon, 25 Nov 2002 11:32:04 -0800") References: <60FB8BB7F0EFC7409B75EEEC13E2019201BFD737@admin56.narex.com> Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:un0nxbjef.fsf at boost-consulting.com... >> > And even when I say 'bjam dll' the output is the same (without target > name). >> >> Have you rebuilt your bjam recently? > > Same result with bjam from web and freshly rebuild bjam from 1.29 distro. :( > Output with d2 is too big for me (~800k) to find the problem. We're currently baffled. Do you get the same result with the current Boost CVS state? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Mon Nov 25 23:45:03 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 17:45:03 -0500 Subject: [C++-sig] Re: Problem with vc++ 7 In-Reply-To: <20021125154826-r01010800-8e171464-0860-0108@12.100.89.43> (Rene Rivera's message of "Mon, 25 Nov 2002 15:48:25 -0600") References: <20021125154826-r01010800-8e171464-0860-0108@12.100.89.43> Message-ID: Rene Rivera writes: > This is an example of how bad the error messages in BBv1 are :-( Hopefuly > BBv2 will be better behaved in this regard. Actually I think I fixed BBv1 in the CVS for this particular message. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Tue Nov 26 00:21:52 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 25 Nov 2002 15:21:52 -0800 Subject: [C++-sig] Re: Re: Problem with vc++ 7 References: <20021118234634.40507.qmail@web20202.mail.yahoo.com><200211191557.gAJFvKu13884@libra3.slac.stanford.edu><200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "David Abrahams" wrote in message news:ubs4d72tg.fsf at boost-consulting.com... > > How to include my files from c:/a/b/c/include dir and libs (say > > c:/d/e/f.lib)? > > > > When I say: > > extension t1 : t1.cpp > > ../build/boost_python > > You need a colon here. Sources and dependencies are a separate > argument from requirements > > > c:/a/b/c/include OK. It works and reveal an error in boost/example/Jamfile (missed colons). > Oh, and the library below needs to go with the sources and the other > dependency. You can read all about this at http://www.boost.org/tools/build/build_system.htm > > > c:/d/e/f > > ; > > > > IMHO It would be good addition to FAQ (building section). > > Please submit a patch which explains whatever you think needs to be > clarified. On my way. From dave at boost-consulting.com Tue Nov 26 00:55:58 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 18:55:58 -0500 Subject: [C++-sig] Re: Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Mon, 25 Nov 2002 15:21:52 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:ubs4d72tg.fsf at boost-consulting.com... >> > How to include my files from c:/a/b/c/include dir and libs (say >> > c:/d/e/f.lib)? >> > >> > When I say: >> > extension t1 : t1.cpp >> > ../build/boost_python >> >> You need a colon here. Sources and dependencies are a separate >> argument from requirements >> >> > c:/a/b/c/include > > OK. It works and reveal an error in boost/example/Jamfile (missed colons). There is no such file-----------------^^^^^^^^^^^^^^^^^^^^^ Did you test the Jamfile in question? Does it work? >> Oh, and the library below needs to go with the sources and the other >> dependency. You can read all about this at > http://www.boost.org/tools/build/build_system.htm >> >> > c:/d/e/f >> > ; >> >> >> > IMHO It would be good addition to FAQ (building section). >> >> Please submit a patch which explains whatever you think needs to be >> clarified. > > On my way. Thanks! -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Tue Nov 26 01:42:10 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 25 Nov 2002 16:42:10 -0800 Subject: [C++-sig] Re: Re: Re: Problem with vc++ 7 References: <20021118234634.40507.qmail@web20202.mail.yahoo.com><200211191557.gAJFvKu13884@libra3.slac.stanford.edu><200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "David Abrahams" wrote in message news:ufztp2ohd.fsf at boost-consulting.com... > > OK. It works and reveal an error in boost/example/Jamfile (missed colons). > There is no such file-----------------^^^^^^^^^^^^^^^^^^^^^ Sorry. libs/python/example/Jamfile > Did you test the Jamfile in question? Does it work? You mean my jamfile ? : subproject libs/python/Tcn ; SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; extension PyTcn : # sources PyTcn.cpp : # dependencies ../build/boost_python S:/Fix/CoreLibraries/src/EnviLib S:/Fix/CoreLibraries/src/Technology #S:/Fix/CoreLibraries/bin/debug/Technology.lib ; Next complain is: ...found 960 targets... ...updating 3 targets... vc-Link ..\..\..\libs\python\Tcn\bin\PyTcn.pyd\msvc\debug\runtime-link-dynamic\P yTcn.pyd ..\..\..\libs\python\Tcn\bin\PyTcn.pyd\msvc\debug\runtime-link-dynamic\ PyTcn.lib The system cannot find the path specified. The system cannot find the path specified. CALL "C:\Program Files\Microsoft Visual C++\VC98\bin\VCVARS32.BAT" >nul "C:\Program Files\Microsoft Visual C++\VC98\bin\link" /nologo /INCREMENTAL: NO /DEBUG /DLL /subsystem:console /out:"..\..\..\libs\python\Tcn\bin\PyTcn.py d\msvc\debug\runtime-link-dynamic\PyTcn.pyd" /IMPLIB:"..\..\..\libs\python\Tcn\ bin\PyTcn.pyd\msvc\debug\runtime-link-dynamic\PyTcn.lib" /LIBPATH:"c:\python22\ libs" @"..\..\..\libs\python\Tcn\bin\PyTcn.pyd\msvc\debug\runtime-link-dynami c\PyTcn.CMD" ...failed vc-Link ..\..\..\libs\python\Tcn\bin\PyTcn.pyd\msvc\debug\runtime-link -dynamic\PyTcn.pyd ..\..\..\libs\python\Tcn\bin\PyTcn.pyd\msvc\debug\runtime-lin k-dynamic\PyTcn.lib... ...skipped PyTcn.pyd for lack of PyTcn.lib ... ...failed updating 1 target... ...skipped 1 target... ...updated 1 target... The contents of CMD: "..\..\..\libs\python\Tcn\bin\PyTcn.pyd\msvc\debug\runtime-link-dynamic\PyTc n.obj" My next struggle will be to include my libraries in link but seems I'm not there still. And as usual in last few days no clue :( Mike From mike at bindkey.com Tue Nov 26 02:02:03 2002 From: mike at bindkey.com (Mike Rovner) Date: Mon, 25 Nov 2002 17:02:03 -0800 Subject: [C++-sig] Re: Re: Problem with vc++ 7 References: <20021125154826-r01010800-8e171464-0860-0108@12.100.89.43> Message-ID: "Rene Rivera" wrote in message news:20021125154826-r01010800-8e171464-0860-0108 at 12.100.89.43... > >How to include my files from c:/a/b/c/include dir and libs (say > >c:/d/e/f.lib)? > > > > The problem is that "some/path" is an inter sub/project dependency. > That is, it's a denpendency to a "lib somelib : ..." target. I'm not totally > sure what your intent is. But you probably want "C:/d/e/f.lib" > instead. > My intent is to link my extension dll (pyd) with my libraries (one or more libfiles). IIUC in case of one file I can say "C:/d/e/f.lib" but what if I want to specify additional link dir like /LIBPATH:"c:/d/e" and name (need I?) libs to use (f,g,h). Thanks, Mike From dave at boost-consulting.com Tue Nov 26 01:54:45 2002 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 25 Nov 2002 19:54:45 -0500 Subject: [C++-sig] Re: Re: Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Mon, 25 Nov 2002 16:42:10 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "Mike Rovner" writes: > "David Abrahams" wrote in message > news:ufztp2ohd.fsf at boost-consulting.com... > >> > OK. It works and reveal an error in boost/example/Jamfile (missed > colons). >> There is no such file-----------------^^^^^^^^^^^^^^^^^^^^^ > > Sorry. libs/python/example/Jamfile > >> Did you test the Jamfile in question? Does it work? > > You mean my jamfile ? : No, I mean libs/python/example/Jamfile. Hint: I tested it before checking it in. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From Paul_Kunz at SLAC.Stanford.EDU Tue Nov 26 02:26:42 2002 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Mon, 25 Nov 2002 17:26:42 -0800 Subject: [C++-sig] Internal compiler error with VC 6.0 and 7.0 Message-ID: <200211260126.gAQ1Qgc17649@libra3.slac.stanford.edu> I'm using boost.python v2. My Python extenstion module exposes C++ member functions having as arguments both "const vector < string > & " and "const vector < double > &". Using the boost.python FAQ, I've copied relavent parts of Ralf's code into my own project. All works fine under Linux with both gcc 2.95.3 and gcc 3.2.1. Under Windows things worked with VC++ 7.0, but got "C1001: internal compiler error" for VC++ 6.0. Ok, I don't really need to do a build with 6.0. But then I made some changes, just moving files from one directory to another ("famous last words" ) and now I have the "C1001" for both 6.0 and 7.0. If I comment out the for loop at the end of from_python_sequence::convertible() member function of Ralf's code, both VC++ 6.0 and 7.0 compile the code and it runs. Any suggestions on what to do next? For reference here is my version of Ralf's code... --- /* -*- mode:c++ -*- * * Boost.Python conversion functions to and from STL * * $Id: pyconversions.h,v 1.5 2002/11/25 23:34:19 pfkeb Exp $ * */ #ifndef PY_CONVERSIONS_H #define PY_CONVERSIONS_H // BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround #include using namespace boost::python; /** A wrapper of a conversion function to convert a STL vector to a Python tuple. This class statisfies the requirements of the boost::python::to_python_converter conversion template argument. Copied from scitbx/include/scitbx/boost_python/container_conversions.h @sa boost_1_29_0/libs/python/doc/v2/faq.html @author Ralf W. Grosse-Kunstleve of Lawrence Berkeley National Laboratory */ template < typename ContainerType> struct to_tuple { /** Creates and returns a Python @c tuple from the elements copied from a STL container. The @c ContainerType must be a vector, but may contain any type of object supported by the boost::python::object constructor. */ static PyObject* convert ( ContainerType const& a) { using boost::python::incref; // works around gcc 2.96 bug using boost::python::list; // dito list result; for(std::size_t i=0;i of Lawrence Berkeley National Laboratory */ template < typename T > struct std_vector_to_tuple { std_vector_to_tuple () { to_python_converter < std::vector < T >, to_tuple < std::vector < T > > > (); } }; /** Default operations on all containers for conversion from Python container to C++ one. Copied from scitbx/include/scitbx/boost_python/container_conversions.h @sa boost_1_29_0/libs/python/doc/v2/faq.html @author Ralf W. Grosse-Kunstleve of Lawrence Berkeley National Laboratory */ struct default_policy { static bool check_convertibility_per_element() { return false; } template static bool check_size(boost::type, std::size_t sz) { return true; } template static void assert_size(boost::type, std::size_t sz) {} template static void reserve(ContainerType& a, std::size_t sz) {} }; /** Operations on containers that have variable capacity for conversion from Python container to C++ one. Copied from scitbx/include/scitbx/boost_python/container_conversions.h @sa boost_1_29_0/libs/python/doc/v2/faq.html @author Ralf W. Grosse-Kunstleve of Lawrence Berkeley National Laboratory */ struct variable_capacity_policy : default_policy { template static void reserve(ContainerType& a, std::size_t sz) { a.reserve(sz); } template static void set_value(ContainerType& a, std::size_t i, ValueType const& v) { assert(a.size() == i); a.push_back(v); } }; /** Conversion of Python sequence to C++ container. Copied from scitbx/include/scitbx/boost_python/container_conversions.h @sa boost_1_29_0/libs/python/doc/v2/faq.html @author Ralf W. Grosse-Kunstleve of Lawrence Berkeley National Laboratory */ template struct from_python_sequence { typedef typename ContainerType::value_type container_element_type; from_python_sequence() { boost::python::converter::registry::push_back( &convertible, &construct, boost::python::type_id()); } /** Appears to return @a obj_ptr if it is type of Python sequence that can be convertible to C++ container. */ static void* convertible(PyObject* obj_ptr) { using namespace boost::python; using boost::python::allow_null; // works around gcc 2.96 bug { // Restriction to list, tuple, iter, xrange until // Boost.Python overload resolution is enhanced. if (!( PyList_Check(obj_ptr) || PyTuple_Check(obj_ptr) || PyIter_Check(obj_ptr) || PyRange_Check(obj_ptr))) return 0; } handle<> obj_iter(allow_null(PyObject_GetIter(obj_ptr))); if (!obj_iter.get()) { // must be convertible to an iterator PyErr_Clear(); return 0; } if (ConversionPolicy::check_convertibility_per_element()) { int obj_size = PyObject_Length(obj_ptr); if (obj_size < 0) { // must be a measurable sequence PyErr_Clear(); return 0; } if (!ConversionPolicy::check_size( boost::type(), obj_size)) return 0; bool is_range = PyRange_Check(obj_ptr); //std::size_t i=0; int i = 0; #ifndef _MSC_VER // because it causes c1001: internal compiler error for(;;i++) { handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get()))); if (PyErr_Occurred()) { PyErr_Clear(); return 0; } if (!py_elem_hdl.get()) break; // end of iteration object py_elem_obj(py_elem_hdl); extract elem_proxy(py_elem_obj); if (!elem_proxy.check()) return 0; if (is_range) break; // in a range all elements are of the same type } if (!is_range) assert(i == obj_size ); #endif } return obj_ptr; } /** Constructs a C++ container from a Python sequence. */ static void construct( PyObject* obj_ptr, boost::python::converter::rvalue_from_python_stage1_data* data) { using namespace boost::python; using boost::python::allow_null; // works around gcc 2.96 bug using boost::python::converter::rvalue_from_python_storage; // dito using boost::python::throw_error_already_set; // dito handle<> obj_iter(PyObject_GetIter(obj_ptr)); void* storage = ( (rvalue_from_python_storage*) data)->storage.bytes; new (storage) ContainerType(); data->convertible = storage; ContainerType& result = *((ContainerType*)storage); std::size_t i=0; for(;;i++) { handle<> py_elem_hdl(allow_null(PyIter_Next(obj_iter.get()))); if (PyErr_Occurred()) throw_error_already_set(); if (!py_elem_hdl.get()) break; // end of iteration object py_elem_obj(py_elem_hdl); extract elem_proxy(py_elem_obj); ConversionPolicy::set_value(result, i, elem_proxy()); } ConversionPolicy::assert_size(boost::type(), i); } }; #endif // PY_CONVERSIONS_H --- and the code in my Python module. --- /** Converts an STL vector of double to Python tuple. */ std_vector_to_tuple < double > (); /** Converts an STL vector of string objects to Python tuple. */ std_vector_to_tuple < std::string > (); /** Converts Python sequence of strings to vector of string. */ from_python_sequence < std::vector < std::string >, variable_capacity_policy > (); /** Converts Python sequence of double to vector of double. */ from_python_sequence < std::vector < double >, variable_capacity_policy > (); From rwgk at yahoo.com Tue Nov 26 14:14:24 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 26 Nov 2002 05:14:24 -0800 (PST) Subject: [C++-sig] Internal compiler error with VC 6.0 and 7.0 In-Reply-To: <200211260126.gAQ1Qgc17649@libra3.slac.stanford.edu> Message-ID: <20021126131424.26848.qmail@web20210.mail.yahoo.com> --- "Paul F. Kunz" wrote: > If I comment out the for loop at the end of > from_python_sequence::convertible() member function of Ralf's code, > both VC++ 6.0 and 7.0 compile the code and it runs. > > Any suggestions on what to do next? This looks like one of these nasty trial-and-error code rearrangement jobs that I have already wasted uncounted hours with. Apparently you don't need check_convertibility_per_element(). I know this is not really an answer, but I'd just leave it alone until I actually need the code the compiler chokes on. Maybe you can use VC++ 7.1 by the time the need arises and you have saved yourself some frustration. If I had to bite that bullet I'd first try to narrow the #ifdef down to a smaller piece of code, then work on that ... If you find a code-rearrangement that works for you please post to this list. I'll patch the scitbx code accordingly. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From mike at bindkey.com Tue Nov 26 20:09:30 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 26 Nov 2002 11:09:30 -0800 Subject: [C++-sig] Re: Re: Re: Problem with vc++ 7 References: <20021118234634.40507.qmail@web20202.mail.yahoo.com><200211191557.gAJFvKu13884@libra3.slac.stanford.edu><200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "David Abrahams" wrote in message news:ufztp2ohd.fsf at boost-consulting.com... > "Mike Rovner" writes: > > > "David Abrahams" wrote in message > > news:ubs4d72tg.fsf at boost-consulting.com... > >> > How to include my files from c:/a/b/c/include dir and libs (say > >> > c:/d/e/f.lib)? > >> > > >> > When I say: > >> > extension t1 : t1.cpp > >> > ../build/boost_python > >> > >> You need a colon here. Sources and dependencies are a separate > >> argument from requirements > >> > >> > c:/a/b/c/include > > > > OK. It works and reveal an error in boost/example/Jamfile (missed colons). My fault! I misinterpreted ... as dependency and placed a colon before it. Now it all works fine (vc6). > >> Please submit a patch which explains whatever you think needs to be > >> clarified. > > > > On my way. That is my first attempt to suggest changes, so please be patient and lead me through. Suggested text: Using bjam to build python extensions ========================= bjam is a standard tool for building boostlibrary itself. Thus it is preferable way to build python extensions based on boost.python with bjam. Basic example listed in tutorial. However if you want to add external libraries in your extension (that is why you use boost.python, isn't it?), you must add them to dependency section: # Specify our location in the boost project hierarchy subproject libs/python/MyExtension ; ##################### if you put your dir in boost hierarchy # Include definitions needed for Python modules SEARCH on python.jam = $(BOOST_BUILD_PATH) ; include python.jam ; # Declare a Python extension extension Example : # sources Example.cpp ../build/boost_python : # dependencies FULL_PATH_INCLUDE_DIR RELATIVE_PATH_INCLUDE_DIR FULL_PATH.lib PATH_TO_LIB LIBNAME.lib ; # Declare a test for the extension module boost-python-runtest test1 : # Python test driver test1.py # extension modules to use Example ; Keeping your projects under boost hierarchy is often inconvenient. You may adjust Jamfile to build your extension from any place by - specifying BOOST_BUILD_PATH environment variable pointing to the root of your boost tree or - copying boost-build.jam file to some place in (or above) your source directory and changing the line subproject to the project-root ; in the Jamfile. --------------- See also http://www.python.org/cgi-bin/moinmoin/boost_2epython_2fBuildingExtensions BTW, still open question: How to specify library in a platform-independent way? From dave at boost-consulting.com Wed Nov 27 00:25:41 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Nov 2002 18:25:41 -0500 Subject: [C++-sig] Re: Re: Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Tue, 26 Nov 2002 11:09:30 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "Mike Rovner" writes: > My fault! I misinterpreted ... as dependency It _is_ a dependency. > That is my first attempt to suggest changes, so please be patient and lead > me through. > > Suggested text: > > Using bjam to build python extensions > ========================= > > bjam is a standard tool for building boostlibrary itself. Thus it is > preferable way to build python extensions based on boost.python with > bjam. Basic example listed in tutorial. > > However if you want to add external libraries in your extension (that is why > you use boost.python, isn't it?), you must add them to dependency > section: No, you must add them to the requirements section. Please see http://www.boost.org/tools/build/build_system.htm#main_targets > > # Specify our location in the boost project hierarchy > subproject libs/python/MyExtension ; ##################### if you put your > dir in boost hierarchy > > # Include definitions needed for Python modules > SEARCH on python.jam = $(BOOST_BUILD_PATH) ; > include python.jam ; > > # Declare a Python extension > extension Example > : # sources > Example.cpp > ../build/boost_python > > : # dependencies > FULL_PATH_INCLUDE_DIR > RELATIVE_PATH_INCLUDE_DIR > FULL_PATH.lib > PATH_TO_LIB > LIBNAME.lib > ; > > # Declare a test for the extension module > boost-python-runtest test1 > : # Python test driver > test1.py > # extension modules to use > Example ; > > Keeping your projects under boost hierarchy is often inconvenient. You may > adjust Jamfile to build your extension from any place by > - specifying BOOST_BUILD_PATH environment variable pointing to the root of > your boost tree or No, BOOST_BUILD_PATH would have to point at the tools/build subdirectory, but this is really only supposed to be used for *adding* additional stuff to the build system (e.g. user-defined toolsets). You should always use the approach below: > - copying boost-build.jam file to some place in (or above) your source > directory You need to change the contents so that it reads: boost-build /tools/build ; No point in copying it; it's just one line anyway. > and changing the line subproject to the > project-root ; > in the Jamfile. Or you can establish a new project and make your Jamfile reside in a subproject. > --------------- > See also > http://www.python.org/cgi-bin/moinmoin/boost_2epython_2fBuildingExtensions Hmm, why don't you just add your info to the Wiki? > BTW, still open question: How to specify library in a platform-independent > way? You could do something like: local libname if $(NT) { libname = foo.lib } else { libname = libfoo.a } ... $(libname) -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 27 01:32:34 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Nov 2002 19:32:34 -0500 Subject: [C++-sig] Boost.Python Function overload resolution order Message-ID: I just discovered something surprising in Boost.Python's function overload resolution: overloads are tried in the _reverse_ order in which they are def'ed. I actually thought it worked the opposite way! Changing this could break user code which relies on the current order: void f(float); void g(int); ... def("f", f); def("f", g); If we change the rules so that the first def() is tried first, g will neve be called. However, I consider the current rule to be counter-intuitive and surprising. Quite a dilemma. Opinions? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From mike at bindkey.com Wed Nov 27 01:48:40 2002 From: mike at bindkey.com (Mike Rovner) Date: Tue, 26 Nov 2002 16:48:40 -0800 Subject: [C++-sig] Re: Re: Re: Re: Problem with vc++ 7 References: <20021118234634.40507.qmail@web20202.mail.yahoo.com><200211191557.gAJFvKu13884@libra3.slac.stanford.edu><200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "David Abrahams" wrote in message news:uhee3c3re.fsf at boost-consulting.com... > "Mike Rovner" writes: > > > My fault! I misinterpreted ... as dependency > > It _is_ a dependency. O-my! I have a headache with all that words: dependance without a color, requrements with it. :) > Or you can establish a new project and make your Jamfile reside in a > subproject. IMHO Seasoned Jam user can figure that out himself and wiki/user_guide shiuld be plain. So I prefer not to include that option. OK? > > See also > > http://www.python.org/cgi-bin/moinmoin/boost_2epython_2fBuildingExtensions > > Hmm, why don't you just add your info to the Wiki? Done. > > BTW, still open question: How to specify library in a platform-independent > > way? > > You could do something like: > > local libname > if $(NT) > { > libname = foo.lib > } > else > { > libname = libfoo.a > } > > ... > > $(libname) > IIUC automatic name mangling will be in BB2. It will be good to specify a list of libs to include, like LIBS = a b c $(LIBS) Will that work? From rwgk at yahoo.com Wed Nov 27 02:40:41 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 26 Nov 2002 17:40:41 -0800 (PST) Subject: [C++-sig] Boost.Python Function overload resolution order In-Reply-To: Message-ID: <20021127014041.42514.qmail@web20202.mail.yahoo.com> --- David Abrahams wrote: > I just discovered something surprising in Boost.Python's function > overload resolution: overloads are tried in the _reverse_ order in > which they are def'ed. I actually thought it worked the opposite way! Great, finally I know why I was confused by some of your earlier postings! > If we change the rules so that the first def() is tried first, g will > neve be called. However, I consider the current rule to be > counter-intuitive and surprising. Quite a dilemma. > > Opinions? I have a module A def'ing some overloads for foo(). Then I have another module B which implicitly imports A and def's some more overloads in the scope() of A. In my particular case the overload resolution is unambiguous, so I don't really care. However, in general it could be advantageous if overloads def'ed by higher level modules get attention before any overloads def'ed by lower-level modules. For this scenario the current implementation seems ideal. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From dave at boost-consulting.com Wed Nov 27 03:22:43 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Nov 2002 21:22:43 -0500 Subject: [C++-sig] Re: Re: Re: Re: Problem with vc++ 7 In-Reply-To: ("Mike Rovner"'s message of "Tue, 26 Nov 2002 16:48:40 -0800") References: <20021118234634.40507.qmail@web20202.mail.yahoo.com> <200211191557.gAJFvKu13884@libra3.slac.stanford.edu> <200211220031.gAM0VpM25371@libra3.slac.stanford.edu> Message-ID: "Mike Rovner" writes: >> You could do something like: >> >> local libname >> if $(NT) >> { >> libname = foo.lib >> } >> else >> { >> libname = libfoo.a >> } >> >> ... >> >> $(libname) >> > > IIUC automatic name mangling will be in BB2. You might have a look at the feature. It handles some of that. > It will be good to specify a > list of libs to include, like > > LIBS = a b c > $(LIBS) > > Will that work? Why don't you try it and find out ;-) ? The jamboost list at http://groups.yahoo.com/group/jamboost is a better place to ask general Boost.Build questions... -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From dave at boost-consulting.com Wed Nov 27 03:41:16 2002 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 26 Nov 2002 21:41:16 -0500 Subject: [C++-sig] Boost.Python Function overload resolution order In-Reply-To: <20021127014041.42514.qmail@web20202.mail.yahoo.com> ("Ralf W. Grosse-Kunstleve"'s message of "Tue, 26 Nov 2002 17:40:41 -0800 (PST)") References: <20021127014041.42514.qmail@web20202.mail.yahoo.com> Message-ID: "Ralf W. Grosse-Kunstleve" writes: > --- David Abrahams wrote: >> I just discovered something surprising in Boost.Python's function >> overload resolution: overloads are tried in the _reverse_ order in >> which they are def'ed. I actually thought it worked the opposite way! > > Great, finally I know why I was confused by some of your earlier > postings! Are you sure that isn't just becausen I vocatulate too ferixtably? >> If we change the rules so that the first def() is tried first, g >> will neve be called. However, I consider the current rule to be >> counter-intuitive and surprising. Quite a dilemma. >> >> Opinions? > > I have a module A def'ing some overloads for foo(). Then I have > another module B which implicitly imports A and def's some more > overloads in the scope() of A. In my particular case the overload > resolution is unambiguous, so I don't really care. However, in > general it could be advantageous if overloads def'ed by higher level > modules get attention before any overloads def'ed by lower-level > modules. For this scenario the current implementation seems ideal. Why do you suppose that higher-level modules will be loaded second in general? -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From rwgk at yahoo.com Wed Nov 27 06:48:27 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 26 Nov 2002 21:48:27 -0800 (PST) Subject: [C++-sig] Boost.Python Function overload resolution order In-Reply-To: Message-ID: <20021127054827.78674.qmail@web20202.mail.yahoo.com> --- David Abrahams wrote: > Why do you suppose that higher-level modules will be loaded second in > general? Hm. Interesting point. How about: the lower-level module defines a base class that the higher-level one is inheriting from. Doesn't that dictate the order in which they have to be loaded? -- Anyway, this is becoming increasingly/too theoretical. I don't think that any of my code would break if you changed the overload resolution mechanism. Let's see what others have to say. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From dave at boost-consulting.com Wed Nov 27 07:57:53 2002 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 27 Nov 2002 01:57:53 -0500 Subject: [C++-sig] Support for virtual functions with default implementations Message-ID: Some of you have been struggling with a supposed inability of Boost.Python v2 to correctly expose virtual functions with default implementations. You can read all about the nitty-gritty details at: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/polymorphism.txt The bottom line, when exposing a class B with its "callback" class Bcb... struct B { virtual std::string f() { return "B"; } }; struct BWrap : B { BWrap(PyObject* self) : m_self(self) {} virtual std::string f() { return call_method(m_self, "f"); } std::string f_default() { return B::f(); } PyObject* m_self; }; ...turns out to be that sometimes, from Python, B.f() must invoke B::f virtually (e.g. when the Python object actually holds a [smart] pointer to some C++ class derived from B), and sometimes it must invoke BWrap::f_default, which invokes the actual B::f defined in B. Well, after several weeks of working on a complicated solution to this problem, I had an Aha! moment, and realized that we already had the capability!** The key is simply to expose your class like this: class_ >("B") .def("f", &B::f) // dispatch function .def("f", &BWrap::f_default) // default implementation ; That's it! Because later def() overloads get precedence, your default implementation will be used if the Python object actually contains a BWrap object. Otherwise, it will call B::f virtually. Issues: 1. f_default MUST be a member function of BWrap, or take a BWrap& first argument 2. You MUST def() f_default second. Failure to get either of these right will result in crashes or other runtime failures. I have just checked in changes which allow you to supply your default implementation in the .def() invocation: .def("f", &B::f, &BWrap::f_default) This version will catch those potential errors at compile-time. However, the other version should work fine with the Boost 1.29.0 release. -Dave **Don't worry, the weeks weren't a complete waste; the code got a lot cleaner as I refactored things. -- David Abrahams dave at boost-consulting.com * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution From brett.calcott at paradise.net.nz Wed Nov 27 11:07:02 2002 From: brett.calcott at paradise.net.nz (Brett Calcott) Date: Wed, 27 Nov 2002 23:07:02 +1300 Subject: [C++-sig] MSVC project file [UPDATED] In-Reply-To: References: <003901c287bc$c078f870$2e6e4fcb@hare> <007101c28a25$291ec2a0$2e6e4fcb@hare> <20021125061210.GA1232@HARE> Message-ID: <20021127100702.GD796@HARE> On Nov 25 10:04, David Abrahams wrote: > Brett Calcott writes: > > > Yeah, you didn't read the non-existent documentation :) > > > > There are two ways of setting include paths in VS. You can add them > > under: Project/Settings/C++/Preprocessor/Additional Include Directories > > which makes them project specific, or you can add them under the > > Tools/Options/Directories/Include Files, which makes them global to all > > projects. Given that people may put $BOOST_ROOT wherever they want, I > > typically define stlport and boost stuff at the global level, rather > > than expose my particular setup to the world. This means I can quickly > > switch versions too. *However*, as this file will exist within the boost > > tree, I can add the relative include path to the project file. > > I chose that particular location in the Boost tree based on the paths > I saw in your file, which seemed to indicate that it was to be located > in libs/python/<...>/<...>. Okay - but the paths in the project file (.dsp) for the include files are just for inclusion in the *IDE*, they are only there for convenience so that you can see them in the project file list. The *compiler* ignores them completely. > > > I didn't think to do this as I had already got my global definition > > going. I will make this fix in the one I submit with the docs which > > should happen soonish... > > > > I have been quiet cos' I need to finish some writing - then I'll be > > back to look at this pointer stuff again too. > > OK. Peter has made the get_deleter patch I requested, so this is > going to be very exciting. I'll be happy to work with you on it. Great. I'll be there soon... Cheers, Brett From nicodemus at globalite.com.br Fri Nov 29 16:22:16 2002 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 29 Nov 2002 12:22:16 -0300 Subject: [C++-sig] Conversion from python objects to c++ objects for argument passing Message-ID: <3DE78628.8000106@globalite.com.br> Hail! First, let me congratulate everyone involved in Boost.Python. The more you use it, the more you see how great the library is! I'm having a little problem though. I want that the following function: void PrintVec( const vector &v ) { vector::const_iterator it = v.begin(); stringstream ss; ss << "C++: ["; while ( it != v.end() ){ if ( it != v.begin() ){ ss << ", "; } ss << *it; } ss << "]"; cout << ss.str() << endl; } Be called like this from python: >>> PrintVec([1,2,3]) C++: [1, 2, 3] To accomplish that, I've been using this lvalue converter: struct pylist_to_vector { static vector& execute(PyObject& o) { static vector v; v.clear(); cout << "execute" << endl; if ( PyList_Check(&o) ){ int size = PyList_Size(&o); cout << "size is " << size << endl; v.reserve( size ); for( int i = 0; i < size; ++i ){ PyObject* item = PyList_GetItem(&o, i); if ( PyInt_Check(item) ){ int num = PyInt_AsLong(item); v.push_back( num ); } else { cout << "Not a num at: " << i << endl; } } } cout << "returning..." << endl; return v; } }; and in the module definition: BOOST_PYTHON_MODULE(test) { lvalue_from_pytype(); def( "PrintVec", &PrintVec ); } Everything links and compiles without a problem. But, when I execute: >>> PrintVec([1,2,3]) execute size is 3 returning... in python, it enters in an infinite loop and never stops. Debugging, I found out that it enters into my function, exits it, goes through boost.python, until it enters this code: /* file returning.hpp, line 114 template static PyObject* call( R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) , PyObject* args_ , PyObject*, P const* policies) { // check that each of the arguments is convertible BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) if (!policies->precall(args_)) return 0; (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)); return policies->postcall(args_, detail::none()); } In the "return 0;" line, the processor hits 100% and the application blocks. So, what am I doing wrong? Is this the right way to accomplish what I want? I'm using Intel C++ 6 with STLport on windows. Thanks for any hints and comments, Bruno da Silva de Oliveira. From rwgk at yahoo.com Fri Nov 29 16:51:58 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 29 Nov 2002 07:51:58 -0800 (PST) Subject: [C++-sig] Conversion from python objects to c++ objects for argument passing In-Reply-To: <3DE78628.8000106@globalite.com.br> Message-ID: <20021129155158.89159.qmail@web20207.mail.yahoo.com> I don't know what is wrong with your code specifically, but you are using a lvalue converter where you should be using a rvalue converter anyway. lvalue converters are suitable only for accessing exisiting objects directly. You are creating a new object, as a static object. This is not thread-safe and in all likelihood has other drawbacks. For more information please refer to the How can I wrap functions which take C++ containers as arguments? section at http://www.boost.org/libs/python/doc/v2/faq.html You may copy container_conversions.h to your own include tree. Include the file in your extension module and then: scitbx::boost_python::container_conversions::from_python_sequence< std::vector, scitbx::boost_python::container_conversions::variable_capacity_policy>(); This should be all you need. Ralf --- Nicodemus wrote: > Hail! > > First, let me congratulate everyone involved in Boost.Python. The more > you use it, the more you see how great the library is! > > I'm having a little problem though. I want that the following function: > > void PrintVec( const vector &v ) > { > vector::const_iterator it = v.begin(); > stringstream ss; > ss << "C++: ["; > while ( it != v.end() ){ > if ( it != v.begin() ){ > ss << ", "; > } > ss << *it; > } > ss << "]"; > cout << ss.str() << endl; > } > > Be called like this from python: > > >>> PrintVec([1,2,3]) > C++: [1, 2, 3] > > To accomplish that, I've been using this lvalue converter: > > struct pylist_to_vector > { > static vector& execute(PyObject& o) > { > static vector v; > v.clear(); > cout << "execute" << endl; > if ( PyList_Check(&o) ){ > int size = PyList_Size(&o); > cout << "size is " << size << endl; > v.reserve( size ); > for( int i = 0; i < size; ++i ){ > PyObject* item = PyList_GetItem(&o, i); > if ( PyInt_Check(item) ){ > int num = PyInt_AsLong(item); > v.push_back( num ); > } > else { > cout << "Not a num at: " << i << endl; > } > } > } > cout << "returning..." << endl; > return v; > } > }; > > and in the module definition: > > BOOST_PYTHON_MODULE(test) > { > lvalue_from_pytype(); > def( "PrintVec", &PrintVec ); > } > > Everything links and compiles without a problem. But, when I execute: > >>> PrintVec([1,2,3]) > execute > size is 3 > returning... > > in python, it enters in an infinite loop and never stops. Debugging, I > found out that it enters into my function, exits it, goes through > boost.python, until it enters this code: > > /* file returning.hpp, line 114 > template > static PyObject* call( > R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) > , PyObject* args_ > , PyObject*, P const* policies) > { > // check that each of the arguments is convertible > BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) > > if (!policies->precall(args_)) > return 0; > (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)); > return policies->postcall(args_, detail::none()); > } > > In the "return 0;" line, the processor hits 100% and the application blocks. > > So, what am I doing wrong? Is this the right way to accomplish what I > want? I'm using Intel C++ 6 with STLport on windows. > > Thanks for any hints and comments, > Bruno da Silva de Oliveira. __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From nicodemus at globalite.com.br Fri Nov 29 23:25:09 2002 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 29 Nov 2002 19:25:09 -0300 Subject: [C++-sig] Conversion from python objects to c++ objects for argument passing In-Reply-To: <20021129155158.89159.qmail@web20207.mail.yahoo.com> References: <20021129155158.89159.qmail@web20207.mail.yahoo.com> Message-ID: <3DE7E945.5000904@globalite.com.br> I had checked the FAQ and tried this code before I posted earlier, but it gave me the same result (the application locks in a loop in that same line). Any other ideas of what maybe wrong? Thanks for your reply Ralf, Bruno da Silva de Oliveira. Ralf W. Grosse-Kunstleve wrote: >I don't know what is wrong with your code specifically, but you are using a >lvalue converter where you should be using a rvalue converter anyway. lvalue >converters are suitable only for accessing exisiting objects directly. You are >creating a new object, as a static object. This is not thread-safe and in all >likelihood has other drawbacks. >For more information please refer to the > >How can I wrap functions which take C++ containers as arguments? > >section at > >http://www.boost.org/libs/python/doc/v2/faq.html > >You may copy container_conversions.h to your own include tree. Include the file >in your extension module and then: > > scitbx::boost_python::container_conversions::from_python_sequence< > std::vector, > scitbx::boost_python::container_conversions::variable_capacity_policy>(); > >This should be all you need. >Ralf > >--- Nicodemus wrote: > > >>Hail! >> >>First, let me congratulate everyone involved in Boost.Python. The more >>you use it, the more you see how great the library is! >> >>I'm having a little problem though. I want that the following function: >> >>void PrintVec( const vector &v ) >>{ >> vector::const_iterator it = v.begin(); >> stringstream ss; >> ss << "C++: ["; >> while ( it != v.end() ){ >> if ( it != v.begin() ){ >> ss << ", "; >> } >> ss << *it; >> } >> ss << "]"; >> cout << ss.str() << endl; >>} >> >>Be called like this from python: >> >> >>> PrintVec([1,2,3]) >>C++: [1, 2, 3] >> >>To accomplish that, I've been using this lvalue converter: >> >>struct pylist_to_vector >>{ >> static vector& execute(PyObject& o) >> { >> static vector v; >> v.clear(); >> cout << "execute" << endl; >> if ( PyList_Check(&o) ){ >> int size = PyList_Size(&o); >> cout << "size is " << size << endl; >> v.reserve( size ); >> for( int i = 0; i < size; ++i ){ >> PyObject* item = PyList_GetItem(&o, i); >> if ( PyInt_Check(item) ){ >> int num = PyInt_AsLong(item); >> v.push_back( num ); >> } >> else { >> cout << "Not a num at: " << i << endl; >> } >> } >> } >> cout << "returning..." << endl; >> return v; >> } >>}; >> >>and in the module definition: >> >>BOOST_PYTHON_MODULE(test) >>{ >> lvalue_from_pytype(); >> def( "PrintVec", &PrintVec ); >>} >> >>Everything links and compiles without a problem. But, when I execute: >> >>> PrintVec([1,2,3]) >>execute >>size is 3 >>returning... >> >>in python, it enters in an infinite loop and never stops. Debugging, I >>found out that it enters into my function, exits it, goes through >>boost.python, until it enters this code: >> >>/* file returning.hpp, line 114 >>template >>static PyObject* call( >> R (*pf)(BOOST_PP_ENUM_PARAMS_Z(1, N, A)) >> , PyObject* args_ >> , PyObject*, P const* policies) >> { >> // check that each of the arguments is convertible >> BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CHECK_CONVERSION, nil) >> >> if (!policies->precall(args_)) >> return 0; >> (*pf)(BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_CALL_ARGS, nil)); >> return policies->postcall(args_, detail::none()); >> } >> >>In the "return 0;" line, the processor hits 100% and the application blocks. >> >>So, what am I doing wrong? Is this the right way to accomplish what I >>want? I'm using Intel C++ 6 with STLport on windows. >> >>Thanks for any hints and comments, >>Bruno da Silva de Oliveira. >> >> > > >__________________________________________________ >Do you Yahoo!? >Yahoo! Mail Plus - Powerful. Affordable. Sign up now. >http://mailplus.yahoo.com > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig > > > From rwgk at yahoo.com Fri Nov 29 22:59:18 2002 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 29 Nov 2002 13:59:18 -0800 (PST) Subject: [C++-sig] Conversion from python objects to c++ objects for argument passing In-Reply-To: <3DE7E945.5000904@globalite.com.br> Message-ID: <20021129215918.63263.qmail@web20209.mail.yahoo.com> --- Nicodemus wrote: > I had checked the FAQ and tried this code before I posted earlier, but > it gave me the same result (the application locks in a loop in that same > line). Any other ideas of what maybe wrong? The converters are known to work on a number of platforms. The only problem that I am aware of are internal compiler errors reported by others using the Visual C++ optimizer (I am not aware of problems when the optimizer is not used). Could you post a minimal example that I could use to reproduce your problem? Please be specific about the OS, compiler, compiler/linker options used. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com From nicodemus at globalite.com.br Sat Nov 30 00:43:03 2002 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 29 Nov 2002 20:43:03 -0300 Subject: [C++-sig] Conversion from python objects to c++ objects for argument passing In-Reply-To: <20021129215918.63263.qmail@web20209.mail.yahoo.com> References: <20021129215918.63263.qmail@web20209.mail.yahoo.com> Message-ID: <3DE7FB87.60805@globalite.com.br> God, I'm embaressed. I found the bug. And it couldn't be more stupid. The error is in my PrintVec function: void PrintVec( const vector &v ) { vector::const_iterator it = v.begin(); stringstream ss; ss << "C++: ["; while ( it != v.end() ){ if ( it != v.begin() ){ ss << ", "; } ss << *it; } ss << "]"; cout << ss.str() << endl; } I forgot to update the iterator inside the while loop!!! grrrr... Anyway. The code from scitbx works perfectly. The code that I posted earlier (pylist_to_vector) also works, but, as Ralf mentioned, is not thread-safe. I'm really ashamed of myself. Thanks for your time Ralf, and sorry for wasting your time. Bruno da Silva de Oliveira. Ralf W. Grosse-Kunstleve wrote: >--- Nicodemus wrote: > > >>I had checked the FAQ and tried this code before I posted earlier, but >>it gave me the same result (the application locks in a loop in that same >>line). Any other ideas of what maybe wrong? >> >> > >The converters are known to work on a number of platforms. The only problem >that I am aware of are internal compiler errors reported by others using the >Visual C++ optimizer (I am not aware of problems when the optimizer is not >used). > >Could you post a minimal example that I could use to reproduce your problem? >Please be specific about the OS, compiler, compiler/linker options used. > >Ralf > > >__________________________________________________ >Do you Yahoo!? >Yahoo! Mail Plus - Powerful. Affordable. Sign up now. >http://mailplus.yahoo.com > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig > > > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.cpp URL: