From giulio.eulisse at cern.ch Tue Apr 1 09:24:42 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 01 Apr 2003 09:24:42 +0200 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <3E88A3D7.7020503@globalite.com.br> References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> <1049128478.10102.148.camel@lxcms25> <3E88A3D7.7020503@globalite.com.br> Message-ID: <1049181883.12009.4.camel@lxcms25> > But Giulio, what's the problem in exporting all virtual functions? I > assume you have something like: > > struct A > { > virtual C getC(); > }; it's more like: struct A { virtual void setC(C *ptr); }; > and you don't want to export the class C, right? But remember that > exporting class A without class C will compile just fine. If you try to > call getC in Python, you will just get an exception. Was that the > problem, or I misunderstood? It doesn't compile fine: it complains about non declared class C... I'll send you a real example as soon as I prepare one... Ciao, Giulio From giulio.eulisse at cern.ch Tue Apr 1 09:36:28 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 01 Apr 2003 09:36:28 +0200 Subject: [C++-sig] Pyste typedef problems... In-Reply-To: <3E88A51B.6030602@globalite.com.br> References: <1049121321.9875.92.camel@lxcms25> <1049130384.9875.167.camel@lxcms25> <3E88A51B.6030602@globalite.com.br> Message-ID: <1049182588.12009.17.camel@lxcms25> > When I test your example, Pyste generates a warning for you: > > ]pyste --module=A A.pyste > > ---> Error: A::f returns a pointer or a reference, but no policy was > specified. > > So you have to specify a police for that function. Please look at the > documentation for that. For this particular function, you have to write: > > A = Class("A", "A.h") > set_policy(A.f, return_value_policy(copy_non_const_reference)) I used return_internal_reference() as policy (the cut and paste lost it). Is that a problem? Ciao, Giulio From giulio.eulisse at cern.ch Tue Apr 1 10:00:19 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 01 Apr 2003 10:00:19 +0200 Subject: [C++-sig] Another pyste bug...;-) In-Reply-To: <3E88A250.7010509@globalite.com.br> References: <3E88A250.7010509@globalite.com.br> Message-ID: <1049184019.12041.36.camel@lxcms25> > >How (un)stable is the CVS version?do you tag bug-fixes? > It's not very stable yet, is a work in progress yet. 8) Works quite well for me...As you said it solved the "char *" problem. > I don't tag bug fixes, I only update the version number. Current version > is 0.6.4. You think I should tag each bug fix? No, I was just asking, it's fine for me as it is... Ciao, Giulio From giulio.eulisse at cern.ch Tue Apr 1 10:12:43 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 01 Apr 2003 10:12:43 +0200 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> <1049128478.10102.148.camel@lxcms25> Message-ID: <1049184763.12009.48.camel@lxcms25> > > Another possible solution would be get rid of the whole boost/QT idea, > > and make PyQT and boost play nicely together > > It's not clear that PyQT (SIP) will automatically generate empty > virtual functions for you either. The problem is not the virtual function per se. It's the virtual function requiring QPopupMenu or so: I don't have time, right now, to implement every single class in QT but I have to if these classes are in a pure virtual function. PyQT just is much more advanced as for the number of classes implemented. > You must mean an abstract class. There's no such thing as a virtual > class. Yes, sorry. > > which derives from a QT one, this class gets derived into "Derived" > > and extended in python. An instance of the class "Derived" is > > created in an embedded python environment and is passed to C++ using > > something like extract. > > It's not clear what you mean by "passed to C++ using > extract". You can only write extract in C++, so the > object must already be available in C++ code somehow. I get the "object" from the embedded python environment. > > The virtual method MyBase.method() is then called in C++ and its > > python implementation in Derived gets called. > > **OK so far; I don't see any need to provide a C++ implementation of > the virtual member function other than the one provided automatically > by pyste's generated wrapper class. That alone should be enough to > ensure that there is no problem with instantiating an abstract base > class. The problem is that if you exclude a pure virtual function(because you don't want to implement the whole QT), the code generated by pyste does not compile because the wrapping for that function is not generated. > I don't know the first thing about PyQt, but the real issue is that I > can't understand the problem you're having. I want to have a stripped down QT module and since QStyle has a pure virtual method which requires QPopupMenu, I want to exclude() it. I can't. Ciao, Giulio From nicodemus at globalite.com.br Tue Apr 1 13:43:49 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 01 Apr 2003 08:43:49 -0300 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <1049181883.12009.4.camel@lxcms25> References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> <1049128478.10102.148.camel@lxcms25> <3E88A3D7.7020503@globalite.com.br> <1049181883.12009.4.camel@lxcms25> Message-ID: <3E897B75.4050709@globalite.com.br> Giulio Eulisse wrote: >>But Giulio, what's the problem in exporting all virtual functions? I >>assume you have something like: >> >>struct A >>{ >> virtual C getC(); >>}; >> >> > >it's more like: > >struct A >{ > virtual void setC(C *ptr); >}; > > > >>and you don't want to export the class C, right? But remember that >>exporting class A without class C will compile just fine. If you try to >>call getC in Python, you will just get an exception. Was that the >>problem, or I misunderstood? >> >> > >It doesn't compile fine: it complains about non declared class C... >I'll send you a real example as soon as I prepare one... > Ah! Indeed, but that's because QPopupMenu is forward declared in you header. Try to add: Include("qpopupmenu.h") to your pyste file. That should solve the problem. > >Ciao, >Giulio > > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig > >. > > > From nicodemus at globalite.com.br Tue Apr 1 13:45:49 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 01 Apr 2003 08:45:49 -0300 Subject: [C++-sig] Pyste typedef problems... In-Reply-To: <1049182588.12009.17.camel@lxcms25> References: <1049121321.9875.92.camel@lxcms25> <1049130384.9875.167.camel@lxcms25> <3E88A51B.6030602@globalite.com.br> <1049182588.12009.17.camel@lxcms25> Message-ID: <3E897BED.8020403@globalite.com.br> Giulio Eulisse wrote: >>When I test your example, Pyste generates a warning for you: >> >>]pyste --module=A A.pyste >> >>---> Error: A::f returns a pointer or a reference, but no policy was >>specified. >> >>So you have to specify a police for that function. Please look at the >>documentation for that. For this particular function, you have to write: >> >>A = Class("A", "A.h") >>set_policy(A.f, return_value_policy(copy_non_const_reference)) >> >> > >I used return_internal_reference() as policy (the cut and paste lost >it). Is that a problem? > > It's fine if it works for you. 8) Regards, Nicodemus. From giulio.eulisse at cern.ch Tue Apr 1 13:52:11 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 01 Apr 2003 13:52:11 +0200 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <3E897B75.4050709@globalite.com.br> References: <1049113458.10102.53.camel@lxcms25> <10 49116833.10102.76.camel@lxcms25> <10491 28478.10102.148.camel@lxcms25> <3E88A3D7.7020503@globalite.com.br> <1049181883.12009.4.camel@lxcms25> <3E897B75.4050709@globalite.com.br> Message-ID: <1049197931.12009.173.camel@lxcms25> > Ah! Indeed, but that's because QPopupMenu is forward declared in you > header. Try to add: > Include("qpopupmenu.h") > to your pyste file. That should solve the problem. ARGH! If only I knew it a couple of days ago! ;-) Ok...I think this will (temporary) solve most of my problems...;-) BTW, where is Include() documented at? Thanks a lot! Ciao, Giulio From giulio.eulisse at cern.ch Tue Apr 1 14:07:38 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 01 Apr 2003 14:07:38 +0200 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <1049197931.12009.173.camel@lxcms25> References: <1049113458.10102.53.camel@lxcms25> <10 49116833.10102.76.camel@lxcms25> <10491 28478.10102.148.camel@lxcms25> <3E88A3D7.7020503@globalite.com.br> <1049181883.12009.4.camel@lxcms25> <3E897B75.4050709@globalite.com.br> <1049197931.12009.173.camel@lxcms25> Message-ID: <1049198858.12009.194.camel@lxcms25> > BTW, where is Include() documented at? Ok, I found it...next time I will RTFM a bit deeper...;-) Perhaps this should be emphasized a little bit in the docs. (This is not a complain: just a suggestion!) Ciao, Giulio From dsouza at purdue.edu Wed Apr 2 00:46:53 2003 From: dsouza at purdue.edu (Larina D'Souza) Date: Tue, 1 Apr 2003 17:46:53 -0500 Subject: [C++-sig] Python and C integration Message-ID: <000d01c2f8a0$97a03530$496bd280@ics.purdue.edu> I wrote this code that I got somewhere from a book #include "/usr/local/include/python2.1/Python.h" #include #include #include int fac(int n) { if(n<2)return(1); return((n)*fac(n-1)); } char *reverse(char *s) { register char t, *p=s, *q=(s+(strlen(s)-1)); while(s && (p From gaiacrtn at free.fr Thu Apr 3 10:48:05 2003 From: gaiacrtn at free.fr (Baptiste Lepilleur) Date: Thu, 3 Apr 2003 10:48:05 +0200 Subject: [C++-sig] Boost.Python and abstract class... Message-ID: <004a01c2f9bd$c73c7b00$98b8c2d4@gaia> Hi all, I'm a newbie to Boost.Python and I'm trying to expose an abstract class to python, as demonstrated in "Class Virtual Functions" of the tutorials (http://boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html) . If I try the code provided in the tutorial, I get the following error: >>> class Derived(Base): ... def f(self): ... return 42 ... >>> d = Derived() Traceback (most recent call last): File "", line 1, in ? RuntimeError: This class cannot be instantiated from Python I fixed this by adding a constructor: >>> class Derived(Base): ... def __init__(self): ... pass ... def f(self): ... return 42 ... >>> d = Derived() >>> call_f(d) Traceback (most recent call last): File "", line 1, in ? TypeError: bad argument type for built-in operation But then I get the above error. If I make the Base class non abstract and expose it without boost::noncopyable and no_init, then call_f works correctly. Works (with making Base non abstract): class_("Base"); Don't work (see above): class_("Base"); I'm using VC6 SP5 and Boost 1.30. Anyone knows what is wrong ? Baptiste. From pierre.barbier at cirad.fr Thu Apr 3 10:54:33 2003 From: pierre.barbier at cirad.fr (Pierre Barbier de Reuille) Date: Thu, 03 Apr 2003 10:54:33 +0200 Subject: [C++-sig] Boost.Python and abstract class... In-Reply-To: <004a01c2f9bd$c73c7b00$98b8c2d4@gaia> References: <004a01c2f9bd$c73c7b00$98b8c2d4@gaia> Message-ID: <3E8BF6C9.8060109@cirad.fr> Just don't look at the web site's tutorial : only refer to the one in your boost directory ! Pierre Baptiste Lepilleur wrote: > Hi all, > I'm a newbie to Boost.Python and I'm trying to expose an abstract class > to python, as demonstrated in "Class Virtual Functions" of the tutorials > (http://boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html) > . > > If I try the code provided in the tutorial, I get the following error: > > >>>>class Derived(Base): > > ... def f(self): > ... return 42 > ... > >>>>d = Derived() > > Traceback (most recent call last): > File "", line 1, in ? > RuntimeError: This class cannot be instantiated from Python > > I fixed this by adding a constructor: > > >>>>class Derived(Base): > > ... def __init__(self): > ... pass > ... def f(self): > ... return 42 > ... > >>>>d = Derived() >>>>call_f(d) > > Traceback (most recent call last): > File "", line 1, in ? > TypeError: bad argument type for built-in operation > > But then I get the above error. If I make the Base class non abstract > and expose it without boost::noncopyable and no_init, then call_f works > correctly. > > Works (with making Base non abstract): > class_("Base"); > > Don't work (see above): > class_("Base"); > > I'm using VC6 SP5 and Boost 1.30. > > Anyone knows what is wrong ? > > Baptiste. > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From tim_nagels at hotmail.com Thu Apr 3 12:02:44 2003 From: tim_nagels at hotmail.com (Tim Nagels) Date: Thu, 03 Apr 2003 12:02:44 +0200 Subject: [C++-sig] ambiguous template arguments for .def Message-ID: An HTML attachment was scrubbed... URL: From rwgk at yahoo.com Thu Apr 3 12:30:57 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 3 Apr 2003 02:30:57 -0800 (PST) Subject: [C++-sig] ambiguous template arguments for .def In-Reply-To: Message-ID: <20030403103057.82695.qmail@web20209.mail.yahoo.com> I think you have to add a semicolon after each def statement. Ralf --- Tim Nagels wrote: c:\boost_1_30_0\boost\python\def.hpp(94) : see declaration of 'def' c:\projects\boostpyadmin\adminlib.cpp(274) : error C2143: syntax error : missing ';' before 'tag::id' __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From tim_nagels at hotmail.com Thu Apr 3 12:58:13 2003 From: tim_nagels at hotmail.com (Tim Nagels) Date: Thu, 03 Apr 2003 12:58:13 +0200 Subject: [C++-sig] ambiguous template arguments for .def Message-ID: An HTML attachment was scrubbed... URL: From rwgk at yahoo.com Thu Apr 3 19:20:34 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 3 Apr 2003 09:20:34 -0800 (PST) Subject: [C++-sig] ambiguous template arguments for .def In-Reply-To: Message-ID: <20030403172034.79084.qmail@web20202.mail.yahoo.com> --- Tim Nagels wrote: > doesn't make a difference to the fact he can't determine wich .def function template to use Can you narrow it down to just one function? Please post the signature of that one function. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From domma at procoders.net Thu Apr 3 20:08:18 2003 From: domma at procoders.net (Achim Domma (ProCoders)) Date: Thu, 3 Apr 2003 20:08:18 +0200 Subject: [C++-sig] build project outside boost tree Message-ID: Hi, when I started using boost.python, I failed to build a extensions module outside the boost tree. I want to give it another try, if it's possible at all. Could somebody give me a starting direction? What do I have to do? regards, Achim From Paul_Kunz at SLAC.Stanford.EDU Thu Apr 3 20:09:21 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Thu, 03 Apr 2003 10:09:21 -0800 Subject: [C++-sig] build project outside boost tree In-Reply-To: References: Message-ID: <200304031809.h33I9Lm01206@libra3.slac.stanford.edu> >>>>> On Thu, 03 Apr 2003 20:08:18 +0200, "Achim Domma (ProCoders)" said: > Hi, when I started using boost.python, I failed to build a > extensions module outside the boost tree. I want to give it another > try, if it's possible at all. Could somebody give me a starting > direction? What do I have to do? I just treat it like any other external library. Works fine for me on both Windows and Linux. From rwgk at yahoo.com Thu Apr 3 20:35:07 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 3 Apr 2003 10:35:07 -0800 (PST) Subject: [C++-sig] build project outside boost tree In-Reply-To: Message-ID: <20030403183507.69624.qmail@web20210.mail.yahoo.com> --- "Achim Domma (ProCoders)" wrote: > when I started using boost.python, I failed to build a extensions module > outside the boost tree. I want to give it another try, if it's possible at > all. Could somebody give me a starting direction? What do I have to do? We use SCons (www.scons.org) as a build tool and are very pleased with it. Look for the "Repository feature." This lets you build *everything* outside your source code trees. We embed code (some 20 or 30 lines of Python) for quick-and-dirty parsing of jam files in your SConscripts. Works like charm for building libboost_python.so or boost_python.dll anywhere you want. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From domma at procoders.net Thu Apr 3 20:48:44 2003 From: domma at procoders.net (Achim Domma (ProCoders)) Date: Thu, 3 Apr 2003 20:48:44 +0200 Subject: [C++-sig] build project outside boost tree In-Reply-To: <20030403183507.69624.qmail@web20210.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 > We use SCons (www.scons.org) as a build tool and are very pleased > with it. Look > for the "Repository feature." This lets you build *everything* > outside your > source code trees. We embed code (some 20 or 30 lines of Python) for > quick-and-dirty parsing of jam files in your SConscripts. Works > like charm for > building libboost_python.so or boost_python.dll anywhere you want. > Ralf Sorry for being imprecise. I want to use bjam to build my extension! Most users expect a simple configure;make;make install, and I don't want to force them to download and install more tools than neccessary. regards, Achim From rwgk at yahoo.com Fri Apr 4 02:13:27 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 3 Apr 2003 16:13:27 -0800 (PST) Subject: [C++-sig] build project outside boost tree In-Reply-To: Message-ID: <20030404001327.37732.qmail@web20210.mail.yahoo.com> --- "Achim Domma (ProCoders)" wrote: > Sorry for being imprecise. I want to use bjam to build my extension! Most > users expect a simple configure;make;make install, and I don't want to force > them to download and install more tools than neccessary. FWIW: As it stands right now the size of the latest scons distribution is 152K, or exactly 2.2% of the latest Boost release. I don't think your users will notice if you bundle scons with the rest of your package. There is nothing to install: scons works straight from the unpacked tar file. If you have Python anyway I cannot see a reason for still using a build tool from the stone ages of computing. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From domma at procoders.net Fri Apr 4 11:51:46 2003 From: domma at procoders.net (Achim Domma (ProCoders)) Date: Fri, 4 Apr 2003 11:51:46 +0200 Subject: [C++-sig] build project outside boost tree In-Reply-To: <20030404001327.37732.qmail@web20210.mail.yahoo.com> Message-ID: > FWIW: As it stands right now the size of the latest scons > distribution is 152K, > or exactly 2.2% of the latest Boost release. I don't think your users will > notice if you bundle scons with the rest of your package. There > is nothing to > install: scons works straight from the unpacked tar file. If you > have Python > anyway I cannot see a reason for still using a build tool from > the stone ages > of computing. That's true and scons looks realy nice to me! Do you have some simple boost.python related examples to share? Using a new build tool, the first step is always the hardest one for me. If I understand earlier post right, boost.python is quite sensible to build flags. So a simple example would help me a lot! regards, Achim From giulio.eulisse at cern.ch Fri Apr 4 12:25:12 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 04 Apr 2003 12:25:12 +0200 Subject: [C++-sig] boost & pedantic -W -Wall -ansi Message-ID: <1049451912.18640.116.camel@lxcms25> When compiling a pyste generated file with -pedantic -W -Wall -ansi, besides a number of warnings because of unused variables, there is a problem which makes the compiler fail. /afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/object/make_ptr_instance.hpp:37 invalid use of member `boost::mpl::bool_::type The same code works perfectly without those flags. Any idea? Since the code is quite long, I'll wait to see if this is a common error befor giving more information. Ciao, Giulio PS: dropping -pedantic -ansi -Wall -W is not an option...;-) From dave at boost-consulting.com Fri Apr 4 05:41:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 03 Apr 2003 22:41:33 -0500 Subject: [C++-sig] pyste and virtual classes. In-Reply-To: <1049184763.12009.48.camel@lxcms25> (Giulio Eulisse's message of "01 Apr 2003 10:12:43 +0200") References: <1049113458.10102.53.camel@lxcms25> <1049116833.10102.76.camel@lxcms25> <1049128478.10102.148.camel@lxcms25> <1049184763.12009.48.camel@lxcms25> Message-ID: Giulio Eulisse writes: >> > Another possible solution would be get rid of the whole boost/QT idea, >> > and make PyQT and boost play nicely together >> >> It's not clear that PyQT (SIP) will automatically generate empty >> virtual functions for you either. > > The problem is not the virtual function per se. It's the virtual > function requiring QPopupMenu or so What does "requiring" mean here? Please try to use precise, well-accepted terminology, or we will all be struggling to understand you. Do you mean that it accepts a QPopupMenu argument? Surely the argument is passed by pointer or reference if so (?) > I don't have time, right now, to implement every single class in QT When you say "implement" do you mean "wrap"? The classes in QT are surely already implemented (?) > but I have to if these classes are in a pure virtual function. What does it mean for a class to be "in a pure virtual function"? Do you mean that it is an argument or return type? If I have translated all your terminology properly, then your premise is wrong: as long as you don't need to override a pure virtual function in Python (and I assume you don't because you're asking us to give you an empty stub function) you don't need to wrap the classes used as arguments. In fact, you don't need to have wrapped any classes until a. You want to wrap a derived class and use the base in bases<...> b. You want to actually convert an instance of the class to/from Python. > PyQT just is much more advanced as for the number of classes > implemented. More advanced than what? >> You must mean an abstract class. There's no such thing as a virtual >> class. > > Yes, sorry. > >> > which derives from a QT one, this class gets derived into >> > "Derived" A Python "Derived", I presume? >> > and extended in python. An instance of the class "Derived" is >> > created in an embedded python environment and is passed to C++ using >> > something like extract. OK, at that point, Base must have been wrapped. >> It's not clear what you mean by "passed to C++ using >> extract". You can only write extract in C++, so the >> object must already be available in C++ code somehow. > > I get the "object" from the embedded python environment. OK, then extract is not used to pass it to C++; it's used once the argument is already passed. >> > The virtual method MyBase.method() is then called in C++ and its >> > python implementation in Derived gets called. >> >> **OK so far; I don't see any need to provide a C++ implementation of >> the virtual member function other than the one provided automatically >> by pyste's generated wrapper class. That alone should be enough to >> ensure that there is no problem with instantiating an abstract base >> class. > > The problem is that if you exclude a pure virtual function(because you > don't want to implement the whole QT), the code generated by pyste does > not compile because the wrapping for that function is not generated. OK, I understand that... but what's the point in excluding the pure virtual function in the first place? It doesn't cost you anything until you try to call it, and then it will raise a Python exception, as it should. There's no way that Pyste could in general figure out how to give you a benign function body which does nothing, since it doesn't know what a sensible return value is. Even if the virtual function returns void, it may be required by the Qt system to do something in particular, and _not_ doing that could break Qt. At this point I think I have a clue what problem you're trying to solve, but my sense of it is that it's such a specialized need that you should hack Pyste yourself to add the functionality you want, because there's no way to implement it in a way that would be generally useful to people. >> I don't know the first thing about PyQt, but the real issue is that I >> can't understand the problem you're having. > > I want to have a stripped down QT module and since QStyle has a pure > virtual method which requires QPopupMenu, I want to exclude() it. > I can't. I still don't know what "requires" means here. -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Fri Apr 4 13:34:58 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Fri, 4 Apr 2003 03:34:58 -0800 (PST) Subject: [C++-sig] build project outside boost tree In-Reply-To: Message-ID: <20030404113458.31210.qmail@web20204.mail.yahoo.com> --- "Achim Domma (ProCoders)" wrote: > That's true and scons looks realy nice to me! Do you have some simple > boost.python related examples to share? Using a new build tool, the first > step is always the hardest one for me. If I understand earlier post right, > boost.python is quite sensible to build flags. So a simple example would > help me a lot! Er... I don't think I have a simple example handy. If you'd like to see how a multiplatform build can work try this: http://cci.lbl.gov/~rwgk/cctbx/installation.html I realize this is overwhelming as a start but the examples in the SCons documentation are very good as an introduction. Start with something really simple and work your way up. Borrow flags from libtbx/build/SConscript and the jam-file reading from libtbx/SConscript. The first step was hard for me as well but now I don't spend much time anymore working on the build tools. Ralf __________________________________________________ Do you Yahoo!? Yahoo! Tax Center - File online, calculators, forms, and more http://tax.yahoo.com From nicodemus at globalite.com.br Fri Apr 4 13:39:08 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 04 Apr 2003 08:39:08 -0300 Subject: [C++-sig] boost & pedantic -W -Wall -ansi In-Reply-To: <1049451912.18640.116.camel@lxcms25> References: <1049451912.18640.116.camel@lxcms25> Message-ID: <3E8D6EDC.5020800@globalite.com.br> Giulio Eulisse wrote: >When compiling a pyste generated file with -pedantic -W -Wall -ansi, >besides a number of warnings because of unused variables, there is a >problem which makes the compiler fail. > >/afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/object/make_ptr_instance.hpp:37 invalid use of member `boost::mpl::bool_::type > >The same code works perfectly without those flags. >Any idea? Since the code is quite long, I'll wait to see if this is a >common error befor giving more information. > >Ciao, >Giulio >PS: dropping -pedantic -ansi -Wall -W is not an option...;-) > > Hi Giulio, Could you post a (short) snipped of the code that manifests the problem and the compiler message, so we can analyse what's wrong with the generated code? Regards, Nicodemus. From gaiacrtn at free.fr Sat Apr 5 10:02:51 2003 From: gaiacrtn at free.fr (Baptiste Lepilleur) Date: Sat, 5 Apr 2003 10:02:51 +0200 Subject: [C++-sig] Boost.Python and abstract class... References: <004a01c2f9bd$c73c7b00$98b8c2d4@gaia> <3E8BF6C9.8060109@cirad.fr> Message-ID: <006f01c2fb49$df0a1700$b1df2cd5@gaia> Thanks for your reply. I finally figured it out when rereading the doc. I was doing: class_("Base", no_init); // (first code sample) instead of : class_("Base"); It's now working correctly. Though, the tutorials on present the second form as a way to avoid having to redefine the constructor in python. Baptiste. ----- Original Message ----- From: "Pierre Barbier de Reuille" To: Sent: Thursday, April 03, 2003 10:54 AM Subject: Re: [C++-sig] Boost.Python and abstract class... > Just don't look at the web site's tutorial : only refer to the one in > your boost directory ! > > Pierre > > Baptiste Lepilleur wrote: > > Hi all, > > I'm a newbie to Boost.Python and I'm trying to expose an abstract class > > to python, as demonstrated in "Class Virtual Functions" of the tutorials > > (http://boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html) > > . > > > > If I try the code provided in the tutorial, I get the following error: > > > > > >>>>class Derived(Base): > > > > ... def f(self): > > ... return 42 > > ... > > > >>>>d = Derived() > > > > Traceback (most recent call last): > > File "", line 1, in ? > > RuntimeError: This class cannot be instantiated from Python > > > > I fixed this by adding a constructor: > > > > > >>>>class Derived(Base): > > > > ... def __init__(self): > > ... pass > > ... def f(self): > > ... return 42 > > ... > > > >>>>d = Derived() > >>>>call_f(d) > > > > Traceback (most recent call last): > > File "", line 1, in ? > > TypeError: bad argument type for built-in operation > > > > But then I get the above error. If I make the Base class non abstract > > and expose it without boost::noncopyable and no_init, then call_f works > > correctly. > > > > Works (with making Base non abstract): > > class_("Base"); > > > > Don't work (see above): > > class_("Base"); > > > > I'm using VC6 SP5 and Boost 1.30. > > > > Anyone knows what is wrong ? > > > > Baptiste. > > > > > > > > _______________________________________________ > > C++-sig mailing list > > C++-sig at python.org > > http://mail.python.org/mailman/listinfo/c++-sig > > > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From lutz_p at gmx.net Sat Apr 5 18:07:08 2003 From: lutz_p at gmx.net (Lutz Paelike) Date: Sat, 05 Apr 2003 18:07:08 +0200 Subject: [C++-sig] Defining Policies for unknown data handles Message-ID: <3E8EFF2C.30207@gmx.net> Hi all, i'm starting with boost python and also tried the great pyste tool to make some python bindings. I have a question, which seems not too difficult for me, but i'm not sure which is the right way to go.. I have a commercial application with an interface i like to use. There are a couple of structures and functions defined. Some of them use a pointer to a hidden structure returned by a initalizing function. I don't need to know anything about the struct , i just pass it on to other functions to refer to the internal data. It's going like this: 1. Definition of data handle: typedef struct _CapChannel *CapChannel; /* Opaque pointer to a channel*/ 2. Get Handle CapChannel CapCreateChannel _PROTO((char *name, CapChannelUsage usage, int data_type)); 3. Use Handle int CapSetData _PROTO((CapChannel channel, void *data)); You get the picture... So when i use pyste to generate the boost python interface code it gives a warning: ---> Error: CapCreateChannel returns a pointer or a reference, but no policy was specified. This makes perfect sense for me, as Pyste/Boost Python don't know how to deal with this reference. The question for me is now which is the right policy to use and how do i define this correctly? I don't need access to _CapChannel from Python. I just want to store the pointer. Thanks for your help, Lutz Paelike Lutz From nicodemus at globalite.com.br Sat Apr 5 20:22:21 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 05 Apr 2003 15:22:21 -0300 Subject: [C++-sig] Defining Policies for unknown data handles In-Reply-To: <3E8EFF2C.30207@gmx.net> References: <3E8EFF2C.30207@gmx.net> Message-ID: <3E8F1EDD.9060904@globalite.com.br> Lutz Paelike wrote: > Hi all, Hi Lutz, > i'm starting with boost python and also tried the great pyste tool to > make some python bindings. > > I have a question, which seems not too difficult for me, but i'm not > sure which is the right way to go.. > > I have a commercial application with an interface i like to use. > There are a couple of structures and functions defined. > Some of them use a pointer to a hidden structure returned by a > initalizing function. I don't need to know anything about the struct , > i just pass it on to other functions to refer to the internal data. > > It's going like this: > > 1. Definition of data handle: > > typedef struct _CapChannel *CapChannel; /* Opaque pointer to a > channel*/ > > 2. Get Handle > > CapChannel CapCreateChannel _PROTO((char *name, CapChannelUsage usage, > int data_type)); > 3. Use Handle > > int CapSetData _PROTO((CapChannel channel, void *data)); > > > You get the picture... > > So when i use pyste to generate the boost python interface code it gives > a warning: > > ---> Error: CapCreateChannel returns a pointer or a reference, but no > policy was specified. > > This makes perfect sense for me, as Pyste/Boost Python don't know how to > deal with this reference. > The question for me is now which is the right policy to use and how do > i define this correctly? > I don't need access to _CapChannel from Python. I just want to store the > pointer. Just set the correct policy for CapCreateChannel: f = Function('CapCreateChannel', ...) set_policy(f, return_value_policy(return_opaque_pointer)) Note: pyste didn't support return_opaque_pointer until version 0.6.5, which I just commited to CVS. Hope that helps, Nicodemus. From lutz_p at gmx.net Sun Apr 6 14:30:37 2003 From: lutz_p at gmx.net (Lutz Paelike) Date: Sun, 06 Apr 2003 14:30:37 +0200 Subject: [C++-sig] Re: Defining Policies for unknown data handles Message-ID: <3E901DED.5060003@gmx.net> > Lutz Paelike wrote: > >> Hi all, > > > Hi Lutz, > >> i'm starting with boost python and also tried the great pyste tool >> to make some python bindings. >> >> I have a question, which seems not too difficult for me, but i'm >> not sure which is the right way to go.. >> >> I have a commercial application with an interface i like to use. >> There are a couple of structures and functions defined. Some of >> them use a pointer to a hidden structure returned by a initalizing >> function. I don't need to know anything about the struct , i just >> pass it on to other functions to refer to the internal data. >> >> It's going like this: >> >> 1. Definition of data handle: >> >> typedef struct _CapChannel *CapChannel; /* Opaque pointer to a >> channel*/ >> >> 2. Get Handle >> >> CapChannel CapCreateChannel _PROTO((char *name, CapChannelUsage >> usage, int data_type)); 3. Use Handle >> >> int CapSetData _PROTO((CapChannel channel, void *data)); >> >> >> You get the picture... >> >> So when i use pyste to generate the boost python interface code it >> gives a warning: >> >> ---> Error: CapCreateChannel returns a pointer or a reference, but >> no policy was specified. >> >> This makes perfect sense for me, as Pyste/Boost Python don't know >> how to deal with this reference. The question for me is now which >> is the right policy to use and how do i define this correctly? I >> don't need access to _CapChannel from Python. I just want to store >> the pointer. > > > Just set the correct policy for CapCreateChannel: > > f = Function('CapCreateChannel', ...) set_policy(f, > return_value_policy(return_opaque_pointer)) > > Note: pyste didn't support return_opaque_pointer until version 0.6.5, > which I just commited to CVS. > > Hope that helps, Nicodemus. I'm sorry, that did not work completely. And maybe i found a (small) bug in pyste.. When i use the following as you suggested: f= Function("CapCreateChannel","mocapserver.h") set_policy(f, return_value_policy(return_opaque_pointer)) i get ----------------------------------- Traceback (most recent call last): File "p:\Dev\boost_1_30_0\libs\python\pyste\src\pyste.py", line 194, in ? status = Main() File "p:\Dev\boost_1_30_0\libs\python\pyste\src\pyste.py", line 151, in Main execfile(interface, context) File "mcp.pyste", line 42, in ? set_policy(f, return_value_policy(return_opaque_pointer)) NameError: name 'return_opaque_pointer' is not defined --------------------------------- i figured out that you have a defined a variable called return_opaque_pointer and this var contains just the string "return_opaque_pointer" so i used this instead: f= Function("CapCreateChannel","mocapserver.h") set_policy(f, return_value_policy('return_opaque_pointer')) Now Pyste works, but still yields following warning: ------------------------------------------ mocapserver.h:205: type specifier omitted for parameter mocapserver.h:205: parse error before `,' token mocapserver.h:211: type specifier omitted for parameter mocapserver.h:211: parse error before `)' token ---> Error: _CapChannel is forward declared. Please include the appropriate header with its definition Module mocap generated 2.19 seconds --------------------------------------------- This is ok, because Pyste is right there is no definition of _CapChannel as it's resolved by linking to the appropriate lib. Pyste generated code, though. It looks like: def("CapCreateChannel", &CapCreateChannel, return_value_policy()); But if i now compile this i get: ----------------------------------------- cl /Zm800 -nologo -GX -c -DBOOST_PYTHON_DYNAMIC_LIB -D_STLP_DO_IMPORT_CSTD_FUNCTIONS=1 -D_STLP_DEBUG=1 -D_STLP_DEBUG_UNINITIALIZED=1 /Z7 /Od /Ob0 /GX /GR /MDd /IP:\Dev\STLport-4.5.3\stlport /IP:\Dev\boost_1_30_0 /IC:\Python22\include /IV:\include /I. /c mocap.cpp /Fomocap.obj mocap.cpp P:\Dev\boost_1_30_0\boost/python/opaque_pointer_converter.hpp(88) : error C2440: 'return' : cannot convert from 'struct _CapChannel' to 'struct _CapChannel *& ' A reference that is not to 'const' cannot be bound to a non-lvalue P:\Dev\boost_1_30_0\boost/python/opaque_pointer_converter.hpp(87) : while compiling class-template member function 'struct _CapChannel *&__cdecl boost::python::opaque_pointer_converter::execute(struct boost::python::opaque_pointer_converter::instance &) ' ------------------------------------------------- Suggestions? Thanks a lot, Lutz Paelike From nicodemus at globalite.com.br Sun Apr 6 15:43:52 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 06 Apr 2003 10:43:52 -0300 Subject: [C++-sig] Re: Defining Policies for unknown data handles In-Reply-To: <3E901DED.5060003@gmx.net> References: <3E901DED.5060003@gmx.net> Message-ID: <3E902F18.8010905@globalite.com.br> Lutz Paelike wrote: > >> Lutz Paelike wrote: >> >>> Hi all, >> >> >> >> Hi Lutz, >> >>> i'm starting with boost python and also tried the great pyste tool >>> to make some python bindings. >>> >>> I have a question, which seems not too difficult for me, but i'm not >>> sure which is the right way to go.. >>> >>> I have a commercial application with an interface i like to use. >>> There are a couple of structures and functions defined. Some of them >>> use a pointer to a hidden structure returned by a initalizing >>> function. I don't need to know anything about the struct , i just >>> pass it on to other functions to refer to the internal data. >>> >>> It's going like this: >>> >>> 1. Definition of data handle: >>> >>> typedef struct _CapChannel *CapChannel; /* Opaque pointer to a >>> channel*/ >>> >>> 2. Get Handle >>> >>> CapChannel CapCreateChannel _PROTO((char *name, CapChannelUsage >>> usage, int data_type)); 3. Use Handle >>> >>> int CapSetData _PROTO((CapChannel channel, void *data)); >>> >>> >>> You get the picture... >>> >>> So when i use pyste to generate the boost python interface code it >>> gives a warning: >>> >>> ---> Error: CapCreateChannel returns a pointer or a reference, but >>> no policy was specified. >>> >>> This makes perfect sense for me, as Pyste/Boost Python don't know >>> how to deal with this reference. The question for me is now which is >>> the right policy to use and how do i define this correctly? I don't >>> need access to _CapChannel from Python. I just want to store >>> the pointer. >> >> >> >> Just set the correct policy for CapCreateChannel: >> >> f = Function('CapCreateChannel', ...) set_policy(f, >> return_value_policy(return_opaque_pointer)) >> >> Note: pyste didn't support return_opaque_pointer until version 0.6.5, >> which I just commited to CVS. >> >> Hope that helps, Nicodemus. > > > > > I'm sorry, that did not work completely. And maybe i found a (small) bug > in pyste.. > > When i use the following as you suggested: > > f= Function("CapCreateChannel","mocapserver.h") > set_policy(f, return_value_policy(return_opaque_pointer)) > > i get > ----------------------------------- > Traceback (most recent call last): > File "p:\Dev\boost_1_30_0\libs\python\pyste\src\pyste.py", line 194, in ? > status = Main() > File "p:\Dev\boost_1_30_0\libs\python\pyste\src\pyste.py", line 151, > in Main > execfile(interface, context) > File "mcp.pyste", line 42, in ? > set_policy(f, return_value_policy(return_opaque_pointer)) > NameError: name 'return_opaque_pointer' is not defined > --------------------------------- > > i figured out that you have a defined a variable called > return_opaque_pointer > and this var contains just the string "return_opaque_pointer" > so i used this instead: > > f= Function("CapCreateChannel","mocapserver.h") > set_policy(f, return_value_policy('return_opaque_pointer')) Ouch! Stupid, stupid, stupid! (that would be me). Thanks for reporting this. Fixed in version 0.6.6. > Now Pyste works, but still yields following warning: > > ------------------------------------------ > mocapserver.h:205: type specifier omitted for parameter > mocapserver.h:205: parse error before `,' token > mocapserver.h:211: type specifier omitted for parameter > mocapserver.h:211: parse error before `)' token Hmm, those are errors emitted by gccxml about your code... can't really help if you don't show some of it. 8) > ---> Error: _CapChannel is forward declared. Please include the > appropriate header with its definition > > Module mocap generated > 2.19 seconds > --------------------------------------------- > > This is ok, because Pyste is right there is no definition of _CapChannel > as it's resolved by linking to the appropriate lib. > Pyste generated code, though. It looks like: > > def("CapCreateChannel", &CapCreateChannel, > return_value_policy()); Forward declaration normally generates compiler errors with Boost.Python, hence the warning. You should include its definition like this: Include('CapChannel.h') Pyste will always generate code if gccxml could produce an xml file. Problem is, if you get some compilation errors, the definitions in the xml file can be incomplete, like missing methods and classes. You should try to remove those errors reported by GCCXML. > But if i now compile this i get: > > ----------------------------------------- > > cl /Zm800 -nologo -GX -c -DBOOST_PYTHON_DYNAMIC_LIB > -D_STLP_DO_IMPORT_CSTD_FUNCTIONS=1 -D_STLP_DEBUG=1 > -D_STLP_DEBUG_UNINITIALIZED=1 /Z7 /Od /Ob0 /GX /GR /MDd > /IP:\Dev\STLport-4.5.3\stlport /IP:\Dev\boost_1_30_0 > /IC:\Python22\include /IV:\include /I. /c mocap.cpp /Fomocap.obj > mocap.cpp > > P:\Dev\boost_1_30_0\boost/python/opaque_pointer_converter.hpp(88) : > error C2440: 'return' : cannot convert from 'struct _CapChannel' to > 'struct _CapChannel *& ' > A reference that is not to 'const' cannot be bound to a non-lvalue > > P:\Dev\boost_1_30_0\boost/python/opaque_pointer_converter.hpp(87) : > while compiling class-template member function 'struct _CapChannel > *&__cdecl boost::python::opaque_pointer_converter *>::execute(struct boost::python::opaque_pointer_converter _CapChannel *>::instance &) ' > ------------------------------------------------- > > Suggestions? > I don't know, the generated code seems to be ok. Perhaps someone else can help? > Thanks a lot, > > Lutz Paelike Thanks Lutz, Nicodemus. From dave at boost-consulting.com Sun Apr 6 21:06:36 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 06 Apr 2003 15:06:36 -0400 Subject: [C++-sig] static data members Message-ID: I implemented and checked in static data member support a few days ago, but due to poor bandwidth couldn't announce it. You can now use def_readonly and def_readwrite with pointers and references to ordinary objects (as opposed to data members). The expression &T::x where x is a static data member of T is a regular pointer, in case you wondered. Please see libs/python/test/data_members.[cpp/py] for examples. Documentation to follow. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Sun Apr 6 21:14:53 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 06 Apr 2003 15:14:53 -0400 Subject: [C++-sig] build project outside boost tree In-Reply-To: ("Achim Domma \'s message of "Thu, 3 Apr 2003 20:08:18 +0200") References: Message-ID: "Achim Domma \(ProCoders\)" writes: > Hi, > > when I started using boost.python, I failed to build a extensions module > outside the boost tree. I want to give it another try, if it's possible at > all. Could somebody give me a starting direction? What do I have to do? Did you look at http://www.boost.org/libs/python/doc/building.html#outside ? These instructions work for me, last time I checked. When Boost.Build v2 is released (soonish) it will be possible to build an extension module outside the boost tree and still have the Boost.Python library rebuild automatically whenever it changes. Until then, the link above shows you how to do it with a prebuilt Boost.Python library (just run bjam in libs/python/build and copy the result to an appropriate place in your project tree). HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Sun Apr 6 21:47:42 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 06 Apr 2003 16:47:42 -0300 Subject: [C++-sig] build project outside boost tree In-Reply-To: References: Message-ID: <3E90845E.2000402@globalite.com.br> David Abrahams wrote: >When Boost.Build v2 is released (soonish) it will be possible to build an extension >module outside the boost tree and still have the Boost.Python library >rebuild automatically whenever it changes. > I know it's too late for that, but have you people considered SCons? It is really a great tool, and it's in Python. 8) From nicodemus at globalite.com.br Sun Apr 6 22:50:18 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 06 Apr 2003 17:50:18 -0300 Subject: [C++-sig] static data members In-Reply-To: References: Message-ID: <3E90930A.2030307@globalite.com.br> David Abrahams wrote: >I implemented and checked in static data member support a few days >ago, but due to poor bandwidth couldn't announce it. You can now use >def_readonly and def_readwrite with pointers and references to >ordinary objects (as opposed to data members). The expression &T::x >where x is a static data member of T is a regular pointer, in case >you wondered. > >Please see libs/python/test/data_members.[cpp/py] for examples. >Documentation to follow. > > Nice! I updated pyste to generate code that uses this new facility (version 0.7.0). Great work Dave, Nicodemus. From lutz_p at gmx.net Mon Apr 7 02:08:12 2003 From: lutz_p at gmx.net (Lutz Paelike) Date: Mon, 07 Apr 2003 02:08:12 +0200 Subject: [C++-sig] build project outside boost tree In-Reply-To: <3E90845E.2000402@globalite.com.br> References: <3E90845E.2000402@globalite.com.br> Message-ID: <3E90C16C.7050604@gmx.net> I agree. I had the same problem and Ralf gave the tip with Scons. I checked it out and it's very easy to use. I like it. If anybody is interested i could post a SConstruct file (like a Makefile)... Lutz Paelike Nicodemus wrote: > > > David Abrahams wrote: > >> When Boost.Build v2 is released (soonish) it will be possible to build >> an extension >> module outside the boost tree and still have the Boost.Python library >> rebuild automatically whenever it changes. > > > I know it's too late for that, but have you people considered SCons? It > is really a great tool, and it's in Python. 8) > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > From dave at boost-consulting.com Mon Apr 7 10:55:40 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 07 Apr 2003 04:55:40 -0400 Subject: [C++-sig] build project outside boost tree In-Reply-To: <3E90845E.2000402@globalite.com.br> (Nicodemus's message of "Sun, 06 Apr 2003 16:47:42 -0300") References: <3E90845E.2000402@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>When Boost.Build v2 is released (soonish) it will be possible to build an extension >>module outside the boost tree and still have the Boost.Python library >> rebuild automatically whenever it changes. > > I know it's too late for that, but have you people considered SCons? > It is really a great tool, and it's in Python. 8) Yes, we considered it. I like SCons, but it fails several of our design criteria (which you can peruse at http://www.boost.org/tools/build/build_system.htm#design_criteria). Being based on Python, unfortunately, fails the 4th requirement. -- Dave Abrahams Boost Consulting www.boost-consulting.com From ganssauge at gmx.de Mon Apr 7 15:27:14 2003 From: ganssauge at gmx.de (=?iso-8859-1?Q?Gottfried_Gan=DFauge?=) Date: Mon, 7 Apr 2003 15:27:14 +0200 Subject: [C++-sig] Re: Defining Policies for unknown data handles Message-ID: <014801c2fd09$66ed5cc0$fe78a8c0@gieke> > I don't know, the generated code seems to be ok. Perhaps someone else > can help? There's something missing from the generated code: a call to the macro BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID This *must* be used to create a specialization for the type_id function. See the documentation for return_opaque_pointer. Here is an example: --- opaque.h ---------------><------------------------------------><--- typedef struct opaque_ *opaque; extern opaque open_opaque(); --- opaque.pyste -----------><------------------------------------><--- f = Function('open_opaque', 'opaque.h') set_policy (f, return_value_policy (return_opaque_pointer)) ---- opaque.cpp-------------><------------------------------------><-- // Includes ==================================================================== #include #include // Using ======================================================================= using namespace boost::python; /***************************************************** * THE FOLLOWING LINE SHOULD BE ADDED BY PYSTE */ BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) // Module ====================================================================== BOOST_PYTHON_MODULE(opaque) { def("open_opaque", &open_opaque, return_value_policy< return_opaque_pointer >()); } -----------------------------><------------------------------------><--- Cheers, Gottfried > > > Thanks a lot, > > > > Lutz Paelike From beyer at imb-jena.de Mon Apr 7 18:09:09 2003 From: beyer at imb-jena.de (Andreas Beyer) Date: Mon, 07 Apr 2003 18:09:09 +0200 Subject: [C++-sig] boost.python and MinGW Message-ID: <3E91A2A5.8030404@imb-jena.de> Hi, I am trying to compile and use boost.python with MinGW. Although compiling works, I get strange errors when using it. The 'hello world' example from the boost.python tutorial works fine. However, as soon as I try to access a class attribute python crashes without raising an exception (which makes it difficult for me to debug the error). If I compile boost.python with MSVC it works fine. For compiling boost.python with MinGW I have taken the following steps: 1. Create python22.def with pexports v. 0.43 (Python 2.2.2) 2. Create libpython22.a with dlltool v. 2.13 3. Run 'bjam -sTOOLS=mingw' in python\test, (boost 1.30.0, bjam 3.1.4) 4. Create libboost_python.a as above 5. Compile the example from below with Python's distutil (I was too lazy to create a jam-file) This is my example: #include using namespace boost::python; char const * greet() { return "hello world!"; } struct World { int hallo; }; BOOST_PYTHON_MODULE(hello) { def("greet", greet); class_("World") .def_readwrite("hallo", &World::hallo); } This is the compiler call for the example (no warnings): C:\MinGW\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\boost_1_30_0 -IC:\Python22\include -c hello.cpp -o build\temp.win32-2.2\Release\hello.o C:\MinGW\bin\dllwrap.exe -mno-cygwin -mdll -static --entry _DllMain at 12 --output-lib build\temp.win32 -2.2\Release\libhello.a --def build\temp.win32-2.2\Release\hello.def -s build\temp.win32-2.2\Release \hello.o -LC:\Python22\libs -lstdc++ -lboost_python -lpython22 -o build\lib.win32-2.2\hello.pyd I cannot access the attribute 'hallo', although greet() works fine. The following python session crashes in the last line without warning: >>import hello >>hello.greet() 'hello world!' >>ob=hello.World() >>ob.hallo Any ideas? Thanks, Andreas From dirk at gerrits.homeip.net Mon Apr 7 22:01:26 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Mon, 07 Apr 2003 22:01:26 +0200 Subject: [C++-sig] Boost.Python documentation errors Message-ID: <3E91D916.6080102@gerrits.homeip.net> Hi, here's a list of some errors in the BPL documentation, starting with one in my own part. (Thanks for spotting it Torsten!) In using_the_interpreter.html of the tutorial, under 'Beyond handles', it says 'main_namespace dict' in a code example. This should obviously be 'dict main_namespace'. Sorry about that folks! Could you fix it in CVS, Joel? Now on with the errors I found in the Pyste documentation... In running_pyste.html, it says 'avaiable' instead of 'available'. At the end of policies.html, it says 'thought' instead of 'though'. At the start of templates.html it says 'can easily exported too' instead of 'can easily be exported too'. (Missing 'be'.) Also, Classes and Template should be spelled without the capital letter when not at the start of the sentence. And 'only DPoint is affect by this renames' should be 'only DPoint is affected by these renames'. In wrapper.html it says 'std::vector' instead of 'std::vector' and 'Boost.Python has an excellent support for that' instead of 'Boost.Python has excellent support for that'. Also, I think the code example directly after that is bugged: result is not assigned to. Or is the comment supposed to be a placeholder for that assignment? It wasn't 100% clear to me. Further, it says 'The same mechanism can be done with methods too' instead of 'The same mechanism can be used with methods too'. (I'm not a native English speaker but I think this is more correct.) In smart_pointers.html it says 'conversor' instead of 'convertor' and later 'conversors' instead of 'convertors'. Lastly, there is no concensus on the spelling of Pyste/pyste and GCCXML/gccxml. I suggest they are all changed to Pyste and GCCXML respectively. Now I want to note that this is in no way intended as a personal attack on Bruno. We all make mistakes after all. ;) Cheers, Dirk Gerrits From nicodemus at globalite.com.br Mon Apr 7 22:48:31 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 07 Apr 2003 17:48:31 -0300 Subject: [C++-sig] Re: Defining Policies for unknown data handles In-Reply-To: <014801c2fd09$66ed5cc0$fe78a8c0@gieke> References: <014801c2fd09$66ed5cc0$fe78a8c0@gieke> Message-ID: <3E91E41F.8090605@globalite.com.br> Gottfried Gan?auge wrote: >>I don't know, the generated code seems to be ok. Perhaps someone else >>can help? >> >> >There's something missing from the generated code: a call to the macro >BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID >This *must* be used to create a specialization for the type_id function. > >See the documentation for return_opaque_pointer. > >Here is an example: >--- opaque.h ---------------><------------------------------------><--- >typedef struct opaque_ *opaque; > >extern opaque open_opaque(); > >--- opaque.pyste -----------><------------------------------------><--- >f = Function('open_opaque', 'opaque.h') >set_policy (f, return_value_policy (return_opaque_pointer)) > >---- opaque.cpp-------------><------------------------------------><-- >// Includes >==================================================================== >#include >#include > >// Using >======================================================================= >using namespace boost::python; > >/***************************************************** > * THE FOLLOWING LINE SHOULD BE ADDED BY PYSTE > */ >BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) > >// Module >====================================================================== >BOOST_PYTHON_MODULE(opaque) >{ > def("open_opaque", &open_opaque, return_value_policy< >return_opaque_pointer >()); >} >-----------------------------><------------------------------------><--- > >Cheers, > >Gottfried > > Yes, I forgot about the specialization, sorry 8/. Thanks Gottfried! Here's the generated file: // Includes ==================================================================== #include #include // Using ======================================================================= using namespace boost::python; // Declarations ================================================================ namespace { BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) }// namespace // Module ====================================================================== BOOST_PYTHON_MODULE(test) { def("open_opaque", &open_opaque, return_value_policy< return_opaque_pointer >()); } But this is producing compiler errors in my machine (Windows XP, Intel 6.0, STLport-4.5.3): test.cpp test.cpp(13): error: "type_info" is ambiguous BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) ^ test.cpp(13): error: "type_id" is not a class or function template name in the current scope BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) ^ test.cpp(13): error: expected a ";" BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) ... snip more 1452 lines of errors. 8P I believe the code is correct, seems more like a problem with my setup. Any ideas? Regards, Nicodemus. From nicodemus at globalite.com.br Mon Apr 7 23:10:31 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 07 Apr 2003 18:10:31 -0300 Subject: [C++-sig] Boost.Python documentation errors In-Reply-To: <3E91D916.6080102@gerrits.homeip.net> References: <3E91D916.6080102@gerrits.homeip.net> Message-ID: <3E91E947.9020509@globalite.com.br> Dirk Gerrits wrote: > Hi, > > > Now on with the errors I found in the Pyste documentation... Thanks a lot for reporting all this! 8) > > In running_pyste.html, it says 'avaiable' instead of 'available'. > > At the end of policies.html, it says 'thought' instead of 'though'. > > At the start of templates.html it says 'can easily exported too' > instead of 'can easily be exported too'. (Missing 'be'.) Also, Classes > and Template should be spelled without the capital letter when not at > the start of the sentence. And 'only DPoint is affect by this renames' > should be 'only DPoint is affected by these renames'. > > In wrapper.html it says 'std::vector' instead of > 'std::vector' and 'Boost.Python has an excellent support > for that' instead of 'Boost.Python has excellent support for that'. typos... 8/ > Also, I think the code example directly after that is bugged: result > is not assigned to. Or is the comment supposed to be a placeholder for > that assignment? It wasn't 100% clear to me. Sorry, you're right. The comment was supposed to be a placeholder for the code, but it wasn't clear in the documentation. I didn't put the code to avoid shadowing the intent of the snippet, but the code seems simple enough, so I will put it: list names_wrapper() { list result; // call original function vector v = names(); // put all the strings inside the python list vector::iterator it; for (it = v.begin(); it != v.end(); ++it){ result.append(*it); } return result; } Hope that's better. 8) > Further, it says 'The same mechanism can be done with methods too' > instead of 'The same mechanism can be used with methods too'. (I'm not > a native English speaker but I think this is more correct.) > > In smart_pointers.html it says 'conversor' instead of 'convertor' and > later 'conversors' instead of 'convertors'. Oops. In my native language (Brazillian Portuguese), converter is "conversor", hence the confusion. 8P > Lastly, there is no concensus on the spelling of Pyste/pyste and > GCCXML/gccxml. I suggest they are all changed to Pyste and GCCXML > respectively. Agreed! Sloppy writing by my part. 8) > Now I want to note that this is in no way intended as a personal > attack on Bruno. We all make mistakes after all. ;) Of course I don't consider this a personal attack! I really appreciate your time to read the entire documentation, and taking notes of what you saw that was wrong or unclear. > Cheers, > Dirk Gerrits Thanks again Dirk! Nicodemus. From Gottfried.Ganssauge at HAUFE.DE Mon Apr 7 23:48:26 2003 From: Gottfried.Ganssauge at HAUFE.DE (Gottfried.Ganssauge at HAUFE.DE) Date: Mon, 7 Apr 2003 23:48:26 +0200 Subject: AW: [C++-sig] Re: Defining Policies for unknown data handles Message-ID: <2040C0A1CA23D51181A30050BAAC990274A90A@berexch.ber.haufemg.com> ... > Yes, I forgot about the specialization, sorry 8/. Thanks Gottfried! > > > Here's the generated file: > > // Includes > > ==================================================================== > #include > #include > > // Using > > ============================================================== > ========= > using namespace boost::python; > > // Declarations > ================================================================ > namespace { What's that namespace good for? Presumably BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID defines a specialization in namespace boost::python. With the above namespace in place that specialization is defined within an anonymous namespace. > > > BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) > > }// namespace > > > // Module > > ====================================================================== > BOOST_PYTHON_MODULE(test) > { > def("open_opaque", &open_opaque, return_value_policy< > return_opaque_pointer >()); > } > > > But this is producing compiler errors in my machine (Windows > XP, Intel > 6.0, STLport-4.5.3): > > > test.cpp > test.cpp(13): error: "type_info" is ambiguous > BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) > ^ > > test.cpp(13): error: "type_id" is not a class or function template > name in the current scope > BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) > ^ > > test.cpp(13): error: expected a ";" > BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) > > ... snip more 1452 lines of errors. 8P > > > > I believe the code is correct, seems more like a problem with > my setup. > Any ideas? Sorry, I don't have that compiler available, only could check the code with gcc-3.2 I would try without that namespace. Cheers, Gottfried > > Regards, > Nicodemus. > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From nicodemus at globalite.com.br Tue Apr 8 00:10:46 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 07 Apr 2003 19:10:46 -0300 Subject: AW: [C++-sig] Re: Defining Policies for unknown data handles In-Reply-To: <2040C0A1CA23D51181A30050BAAC990274A90A@berexch.ber.haufemg.com> References: <2040C0A1CA23D51181A30050BAAC990274A90A@berexch.ber.haufemg.com> Message-ID: <3E91F766.1080500@globalite.com.br> Gottfried.Ganssauge at HAUFE.DE wrote: >... > > >>Yes, I forgot about the specialization, sorry 8/. Thanks Gottfried! >> >> >>Here's the generated file: >> >> // Includes >> >>==================================================================== >> #include >> #include >> >> // Using >> >>============================================================== >>========= >> using namespace boost::python; >> >> // Declarations >> ================================================================ >> namespace { >> >> >What's that namespace good for? >Presumably BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID defines a specialization >in namespace boost::python. With the above namespace in place that >specialization is defined within an anonymous namespace. > > In this namespace goes all the other declarations, like virtual wrappers and overloads. >> BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) >> >> }// namespace >> >> >> // Module >> >>====================================================================== >> BOOST_PYTHON_MODULE(test) >> { >> def("open_opaque", &open_opaque, return_value_policy< >> return_opaque_pointer >()); >> } >> >> >>But this is producing compiler errors in my machine (Windows >>XP, Intel >>6.0, STLport-4.5.3): >> >> >> test.cpp >> test.cpp(13): error: "type_info" is ambiguous >> BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) >> ^ >> >> test.cpp(13): error: "type_id" is not a class or function template >> name in the current scope >> BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) >> ^ >> >> test.cpp(13): error: expected a ";" >> BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(opaque_) >> >> ... snip more 1452 lines of errors. 8P >> >> >> >>I believe the code is correct, seems more like a problem with >>my setup. >>Any ideas? >> >> >Sorry, I don't have that compiler available, only could check the code with >gcc-3.2 >I would try without that namespace. > That was the problem. 8) Thanks Gottfried! Nicodemus. From djowel at gmx.co.uk Tue Apr 8 01:55:13 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Tue, 8 Apr 2003 07:55:13 +0800 Subject: [C++-sig] Boost.Python documentation errors References: <3E91D916.6080102@gerrits.homeip.net> Message-ID: <006c01c2fd61$25dd4b70$bcd817d2@kim> Dirk Gerrits wrote: > Hi, > > here's a list of some errors in the BPL documentation, starting with > one in my own part. (Thanks for spotting it Torsten!) > > In using_the_interpreter.html of the tutorial, under 'Beyond handles', > it says 'main_namespace dict' in a code example. This should obviously > be 'dict main_namespace'. Sorry about that folks! Could you fix it in > CVS, Joel? Sure! Nicodemus, could you please send in the patches for Pyste? -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net From milind_patil at hotmail.com Tue Apr 8 02:54:51 2003 From: milind_patil at hotmail.com (Milind Patil) Date: Mon, 7 Apr 2003 17:54:51 -0700 Subject: [C++-sig] staticmethod usage Message-ID: Hi, I have only recently started experimenting with boost.c++ package and pyste. Congratulations to the developers of these excellent packages. Along the way I faced some issues. Some have been persistent and I am kinda stumped. Please look at the code(hello.cpp) below to illustrate some of the issues... #include #include #include using namespace boost::python; class Y { public: Y() : y(0) { } Y(int y) : y(y) { } Y(Y const& rhs) : y(rhs.y) { } virtual ~Y() { } operator int() const { return y; } void operator=(Y const& y) { this->y = y.y; } int y; }; class X { public: X(): a(0), b(0) { } X(Y a, Y b) : a(a), b(b) { } X(Y a, Y b, void c (Y *)) : a(a), b(b) { } void show() {std::cout << " show " << endl; } static void show(const char * s) {std::cout << "static show " << s << endl; } static void tryitout (const char* s, Y y, Y z = NULL) {std::cout << "static tryitout " << s << endl; } Y a; Y b; }; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_tryitout_overloads_2_3, tryitout, 2, 3) BOOST_PYTHON_MODULE(hello) { class_ ("Y"); class_ ("X") .def_readwrite("a", &X::a) .def_readwrite("b", &X::b) //.def("tryitout", (void (*)(const char *, Y, Y = NULL ) )&X::tryitout, X_tryitout_overloads_2_3()) .def("tryitout", (void (*)(const char *, Y, Y = NULL ) )&X::tryitout ) .staticmethod("tryitout") .def ("show", (void (X::*)() )&X::show) .def ("show", (void (*)(const char *) )&X::show) .staticmethod("show") ; implicitly_convertible(); implicitly_convertible(); } Essentially I have an overloaded function "show:, one of them been static. The other staic function is "tryitout" with optional argument. I am trying to use them thus: import hello x = hello.X() y = hello.Y() print hello.X.show("X.show") print x.tryitout("x.tryitout", y, y) print x.tryitout("sd", y) print x.show() My issues (with boost_1_30_0, gcc 2.95 and python2.2.2): a) If I uncomment //.def("tryitout", (void (*)(const char *, Y, Y ) )&X::tryitout, X_tryitout_overloads_2_3()) the compilation fails. The compiler message is long and unintelligible (to me). How do I use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS with static methods? b) If I use .def("tryitout", (void (X::*)(const char *, Y, Y ) )&X::tryitout ) which is what pyste generated, I get compilation problems. The compiler cannot find the function (void (X::*)(const char *, Y, Y ) )&X::tryitout . Why does def("tryitout", (void (*)(const char *, Y, Y ) )&X::tryitout ) work and not the above? c) The python code gives exception at print x.show() saying args are not right. How do I expose overloaded functions one of which is static? Note that the arguments to the overloaded functions are different. Any help is appreciated. Thank you, Milind From nicodemus at globalite.com.br Tue Apr 8 03:06:53 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 07 Apr 2003 22:06:53 -0300 Subject: [C++-sig] Boost.Python documentation errors In-Reply-To: <006c01c2fd61$25dd4b70$bcd817d2@kim> References: <3E91D916.6080102@gerrits.homeip.net> <006c01c2fd61$25dd4b70$bcd817d2@kim> Message-ID: <3E9220AD.5090204@globalite.com.br> Joel de Guzman wrote: >Dirk Gerrits wrote: > > >>Hi, >> >>here's a list of some errors in the BPL documentation, starting with >>one in my own part. (Thanks for spotting it Torsten!) >> >>In using_the_interpreter.html of the tutorial, under 'Beyond handles', >>it says 'main_namespace dict' in a code example. This should obviously >>be 'dict main_namespace'. Sorry about that folks! Could you fix it in >>CVS, Joel? >> >> > >Sure! Nicodemus, could you please send in the patches for Pyste? > > Done! Also, I fixed the return_opaque_pointer support, thanks to Gottfried. 8) Regards, Nicodemus. From nicodemus at globalite.com.br Tue Apr 8 03:16:01 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 07 Apr 2003 22:16:01 -0300 Subject: [C++-sig] pyste and big files In-Reply-To: <3E86472F.4090407@globalite.com.br> References: <3E860768.7080506@vega.bg> <3E86472F.4090407@globalite.com.br> Message-ID: <3E9222D1.1020109@globalite.com.br> Nicodemus wrote: > > > Niki Spahiev wrote: > >> I got msvc internal overflow with pyste generated files. Can pyste >> write separate finctions for each class? > > > I don't understand what you mean by "functions for each class", but > you can always generate various little modules, one for each pyste > file if you want. If you're using a single pyste file for the entire > library, break it into smaller ones, one for each submodule your > library has (or any other criteria you find appropriate). Note that > you can still access the library in Python as a single module: > > pyste --module=sub_module1 sub_module1.pyste > pyste --module=sub_module2 sub_module2.pyste > pyste --module=sub_module3 sub_module3.pyste > > (Each sub_module is a subset of your library called here "library" ;)) > > Then you create a "library.py", which imports the sub modules: > > # file library.py > from sub_module1 import * > from sub_module2 import * > from sub_module3 import * > > > And then as a user: > > >>> import library > >>> # use library normally > > Which is the same as: > > pyste --module=library library.pyste > > >>> import library > >>> # use library normally too > > Which I believe it's what you're doing right now. > > I recommend this approach anyway for large libraries, even if you're > not having the problems you're describing. Hi All! To solve this kind of problem, and to help the developer while developing libraries, I implemented a new mode of code generation in Pyste. Using the flag --multiple, Pyste will generate various cpps (one for each class in the pyste files) in a directory, instead of the usual single one. The user can then compile them all and link them into a single library, acomplishing the same results of the single-cpp-mode. The advantages of this method are: - There's no need to recompile the entire module when a single class changes. - In single mode, a library with about 20-30 classes can easily use 300mb+ of memory to compile. Breaking it into smaller cpps solves the problem. The drawback of this approach is that a compilation starting from zero can take about 4x times more than the single-cpp-method... but in a low memory machine it may actually be faster. More details of usage in the documentation. Regards, Nicodemus. From djowel at gmx.co.uk Tue Apr 8 03:22:30 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Tue, 8 Apr 2003 09:22:30 +0800 Subject: [C++-sig] Boost.Python documentation errors References: <3E91D916.6080102@gerrits.homeip.net> <006c01c2fd61$25dd4b70$bcd817d2@kim> <3E9220AD.5090204@globalite.com.br> Message-ID: <00bd01c2fd6d$55aeb210$bcd817d2@kim> Nicodemus wrote: > Joel de Guzman wrote: > >> Dirk Gerrits wrote: >> >> >>> Hi, >>> >>> here's a list of some errors in the BPL documentation, starting with >>> one in my own part. (Thanks for spotting it Torsten!) >>> >>> In using_the_interpreter.html of the tutorial, under 'Beyond >>> handles', it says 'main_namespace dict' in a code example. This >>> should obviously be 'dict main_namespace'. Sorry about that folks! >>> Could you fix it in CVS, Joel? >>> >>> >> >> Sure! Nicodemus, could you please send in the patches for Pyste? >> >> > Done! Also, I fixed the return_opaque_pointer support, thanks to > Gottfried. 8) Done? You mean the Pyste part committed to CVS? Ok... I also committed the using_the_interpreter.html fixes. Regards, -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net From dirk at gerrits.homeip.net Tue Apr 8 07:15:03 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Tue, 08 Apr 2003 07:15:03 +0200 Subject: [C++-sig] Re: Boost.Python documentation errors In-Reply-To: <3E91E947.9020509@globalite.com.br> References: <3E91D916.6080102@gerrits.homeip.net> <3E91E947.9020509@globalite.com.br> Message-ID: Nicodemus wrote: > Dirk Gerrits wrote: > >> Now on with the errors I found in the Pyste documentation... > > Thanks a lot for reporting all this! 8) > [snip] > >> Now I want to note that this is in no way intended as a personal >> attack on Bruno. We all make mistakes after all. ;) > > Of course I don't consider this a personal attack! I really appreciate > your time to read the entire documentation, and taking notes of what you > saw that was wrong or unclear. You're welcome. :) Dirk Gerrits From dirk at gerrits.homeip.net Tue Apr 8 08:30:38 2003 From: dirk at gerrits.homeip.net (Dirk Gerrits) Date: Tue, 08 Apr 2003 08:30:38 +0200 Subject: [C++-sig] Re: Boost.Python documentation errors In-Reply-To: <00bd01c2fd6d$55aeb210$bcd817d2@kim> References: <3E91D916.6080102@gerrits.homeip.net> <006c01c2fd61$25dd4b70$bcd817d2@kim> <3E9220AD.5090204@globalite.com.br> <00bd01c2fd6d$55aeb210$bcd817d2@kim> Message-ID: Joel de Guzman wrote: [snip] > I also committed the using_the_interpreter.html fixes. Great! Thanks. Dirk Gerrits From giulio.eulisse at cern.ch Tue Apr 8 18:58:10 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 08 Apr 2003 18:58:10 +0200 Subject: [C++-sig] boost & pedantic -W -Wall -ansi In-Reply-To: <3E8D6EDC.5020800@globalite.com.br> References: <1049451912.18640.116.camel@lxcms25> <3E8D6EDC.5020800@globalite.com.br> Message-ID: <1049821090.2420.140.camel@lxcms25> On Fri, 2003-04-04 at 13:39, Nicodemus wrote: > Giulio Eulisse wrote: > > >When compiling a pyste generated file with -pedantic -W -Wall -ansi, > >besides a number of warnings because of unused variables, there is a > >problem which makes the compiler fail. > > > >/afs/cern.ch/sw/lcg/external/Boost/1.30.0/rh73_gcc32/boost/python/object/make_ptr_instance.hpp:37 invalid use of member `boost::mpl::bool_::type > > > >The same code works perfectly without those flags. > >Any idea? Since the code is quite long, I'll wait to see if this is a > >common error befor giving more information. > > > >Ciao, > >Giulio > >PS: dropping -pedantic -ansi -Wall -W is not an option...;-) > > > > > Hi Giulio, > > Could you post a (short) snipped of the code that manifests the problem > and the compiler message, so we can analyse what's wrong with the > generated code? > I overlooked this message, sorry... For one of the errors, the incriminated line of code is: .def("setNum", (QCString & (QCString::*)(float, char, int) )&QCString::setNum, return_internal_reference< 1 >(), QCString_setNum_overloads_1_3()) in QCString wrapping code.... I gotta go now, I will try to be more specific tomorrow. Thanks! Ciao, Giulio From giulio.eulisse at cern.ch Wed Apr 9 11:42:53 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 09 Apr 2003 11:42:53 +0200 Subject: [C++-sig] [patch] Unused variable warnings. Message-ID: <1049881374.4357.37.camel@lxcms25> When compiling with -W -Wall I get some unused variable warnings. In attachment you find a little patch which fixes some of them in boost/python/class.hpp (CVS version 1.69) The patch just casts the unused variables to void , so it should be harmless. There are more of them in boost/python/detail/default_def.hpp in the process of producing a patch for that as well. -- Giulio Eulisse Northeastern University, Boston, MA (USA) CERN, Geneve, GE (CH) Office: 40-3-A15 Office phone:76 71692 Cellphone:(+39) 3356972726 Homepage: http://home.cern.ch/eulisse/ -------------- next part -------------- A non-text attachment was scrubbed... Name: class.hpp.patch Type: text/x-patch Size: 1142 bytes Desc: not available URL: From giulio.eulisse at cern.ch Wed Apr 9 11:51:21 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 09 Apr 2003 11:51:21 +0200 Subject: [C++-sig] [patch] Unused variable warnings. In-Reply-To: <1049881374.4357.37.camel@lxcms25> References: <1049881374.4357.37.camel@lxcms25> Message-ID: <1049881881.4357.41.camel@lxcms25> The patch for boost/python/detail/default_def.hpp ... Ciao, Giulio -------------- next part -------------- A non-text attachment was scrubbed... Name: defaults_def.hpp.patch Type: text/x-patch Size: 520 bytes Desc: not available URL: From nico_ml at mgdesign.org Wed Apr 9 12:04:52 2003 From: nico_ml at mgdesign.org (Nicolas Lelong) Date: Wed, 9 Apr 2003 12:04:52 +0200 Subject: [C++-sig] [patch] Unused variable warnings. References: <1049881374.4357.37.camel@lxcms25> Message-ID: <003301c2fe7f$76f11d10$cb00a8c0@nico> > The patch just casts the unused variables to void , so it should be > harmless. Just my two cents, but it would maybe have been better if you had used the 'ignore_unused_variable_warning' function, which is defined in 'concept_check.hpp' - or maybe something similar already in use for boost.python (anyone?) Moreover, I may be wrong but, the common (standard?) way of preventing such warnings is to remove the unused parameter name - so the, for instance, the function inline void register_class_to_python(mpl::true_ copyable, SelectHolder selector, T* = 0) would become inline void register_class_to_python(mpl::true_ /*copyable*/, SelectHolder /*selector*/, T* = 0) Regards, Nicolas From giulio.eulisse at cern.ch Wed Apr 9 12:13:30 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 09 Apr 2003 12:13:30 +0200 Subject: [C++-sig] [patch] Unused variable warnings. In-Reply-To: <003301c2fe7f$76f11d10$cb00a8c0@nico> References: <1049881374.4357.37.camel@lxcms25> <003301c2fe7f$76f11d10$cb00a8c0@nico> Message-ID: <1049883210.4357.50.camel@lxcms25> > Just my two cents, but it would maybe have been better if you had used the > 'ignore_unused_variable_warning' function, which is defined in > 'concept_check.hpp' - or maybe something similar already in use for > boost.python (anyone?) Didn't know about the existance of such a function, sorry. > Moreover, I may be wrong but, the common (standard?) way of preventing such > warnings is to remove the unused parameter name - so the, for instance, the > function > > inline void register_class_to_python(mpl::true_ copyable, SelectHolder > selector, T* = 0) > > would become > > inline void register_class_to_python(mpl::true_ /*copyable*/, SelectHolder > /*selector*/, T* = 0) Didn't know about that as well, sorry again. -- Giulio Eulisse Northeastern University, Boston, MA (USA) CERN, Geneve, GE (CH) Office: 40-3-A15 Office phone:76 71692 Cellphone:(+39) 3356972726 Homepage: http://home.cern.ch/eulisse/ From nickm at sitius.com Wed Apr 9 18:04:49 2003 From: nickm at sitius.com (Nikolay Mladenov) Date: Wed, 09 Apr 2003 12:04:49 -0400 Subject: [C++-sig] Re: staticmethod usage References: Message-ID: <3E9444A1.E39B796B@sitius.com> An HTML attachment was scrubbed... URL: From patrick at vrac.iastate.edu Thu Apr 10 18:35:18 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Thu, 10 Apr 2003 11:35:18 -0500 Subject: [C++-sig] Pyste and inheritance from a templated class Message-ID: <3E959D46.8040005@vrac.iastate.edu> I just returned from a trip, and I am trying out the features added to Pyste during the last several days. With the latest code, I have encountered a problem related to inheritance relationships between C++ class. I am not sure if this is a bug or if there is something new I have to do in my .pyste file. What I am seeing is that Pyste does not include the boost::python::bases<> template parameter when a boost::python::class_<> is declared for a class derived from a templated class. The attached code demonstrates the problem. Pyste generates the correct Boost.Python code if I use AllFromHeader(), but I can't always use that function (unfortunately). Pyste from Boost 1.30.0 works as I expect, and again, this may be something that I missed while reviewing the large volume email I received while I was away. Thanks. -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: inherit.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: inherit.pyste URL: From nicodemus at globalite.com.br Fri Apr 11 06:12:27 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 11 Apr 2003 01:12:27 -0300 Subject: [C++-sig] Pyste and inheritance from a templated class In-Reply-To: <3E959D46.8040005@vrac.iastate.edu> References: <3E959D46.8040005@vrac.iastate.edu> Message-ID: <3E9640AB.904@globalite.com.br> Patrick Hartling wrote: > I just returned from a trip, and I am trying out the features added to > Pyste during the last several days. With the latest code, I have > encountered a problem related to inheritance relationships between C++ > class. I am not sure if this is a bug or if there is something new I > have to do in my .pyste file. What I am seeing is that Pyste does not > include the boost::python::bases<> template parameter when a > boost::python::class_<> is declared for a class derived from a > templated class. > > The attached code demonstrates the problem. Pyste generates the > correct Boost.Python code if I use AllFromHeader(), but I can't always > use that function (unfortunately). Pyste from Boost 1.30.0 works as I > expect, and again, this may be something that I missed while reviewing > the large volume email I received while I was away. Thanks. > > -Patrick It's a bug, for sure! I will take a look into it. Thanks! Regards, Nicodemus. From dave at boost-consulting.com Fri Apr 11 00:25:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 10 Apr 2003 18:25:23 -0400 Subject: [C++-sig] Re: Boost.Python documentation errors In-Reply-To: (Dirk Gerrits's message of "Tue, 08 Apr 2003 08:30:38 +0200") References: <3E91D916.6080102@gerrits.homeip.net> <006c01c2fd61$25dd4b70$bcd817d2@kim> <3E9220AD.5090204@globalite.com.br> <00bd01c2fd6d$55aeb210$bcd817d2@kim> Message-ID: Dirk Gerrits writes: > Joel de Guzman wrote: > [snip] >> I also committed the using_the_interpreter.html fixes. > > Great! Thanks. And thanks to everyone for taking care of this while I've been away at the ACCU and standards committee meetings! -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Apr 11 10:57:52 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 11 Apr 2003 04:57:52 -0400 Subject: [C++-sig] boost.python and MinGW In-Reply-To: <3E91A2A5.8030404@imb-jena.de> (Andreas Beyer's message of "Mon, 07 Apr 2003 18:09:09 +0200") References: <3E91A2A5.8030404@imb-jena.de> Message-ID: Andreas Beyer writes: > Hi, > > I am trying to compile and use boost.python with MinGW. > Although compiling works, I get strange errors when using it. The > hello world' example from the boost.python tutorial works > fine. However, as soon as I try to access a class attribute python > crashes without raising an exception (which makes it difficult for me > to debug the error). Weird. Works fine for me. > If I compile boost.python with MSVC it works fine. > > For compiling boost.python with MinGW I have taken the following steps: > 1. Create python22.def with pexports v. 0.43 > (Python 2.2.2) > 2. Create libpython22.a with dlltool v. 2.13 > 3. Run 'bjam -sTOOLS=mingw' in python\test, > (boost 1.30.0, bjam 3.1.4) > 4. Create libboost_python.a as above > 5. Compile the example from below with Python's distutil (I was too > lazy to create a jam-file) I'm too lazy to figure out how to get distutils to work reliably for C++. Creating a Jamfile is simple as pie. Please try that instead. > This is my example: > > #include > using namespace boost::python; > > char const * greet() { > return "hello world!"; > } > > struct World > { > int hallo; > }; > > BOOST_PYTHON_MODULE(hello) { > def("greet", greet); > class_("World") > .def_readwrite("hallo", &World::hallo); > } > > This is the compiler call for the example (no warnings): > C:\MinGW\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\boost_1_30_0 > -IC:\Python22\include -c hello.cpp -o > build\temp.win32-2.2\Release\hello.o > C:\MinGW\bin\dllwrap.exe -mno-cygwin -mdll -static --entry _DllMain at 12 > --output-lib build\temp.win32 > -2.2\Release\libhello.a --def build\temp.win32-2.2\Release\hello.def > -s > build\temp.win32-2.2\Release > \hello.o -LC:\Python22\libs -lstdc++ -lboost_python -lpython22 -o > build\lib.win32-2.2\hello.pyd > > > I cannot access the attribute 'hallo', although greet() works fine. > The following python session crashes in the last line without warning: > >>import hello > >>hello.greet() > 'hello world!' > >>ob=hello.World() > >>ob.hallo > > Any ideas? Well, you're reading unininitialized data, which is undefined behavior. I don't think it should crash MinGW, though. -- Dave Abrahams Boost Consulting www.boost-consulting.com From jacek.generowicz at cern.ch Fri Apr 11 13:55:07 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: 11 Apr 2003 13:55:07 +0200 Subject: [C++-sig] Passing std::string in SIP Message-ID: How would I use SIP to wrap the following class ? #include class text { private: std::string the_text; public: text(std::string); std::string get(); void set(std::string); }; From camelo at esss.com.br Fri Apr 11 21:10:47 2003 From: camelo at esss.com.br (Marcelo A. Camelo) Date: Fri, 11 Apr 2003 16:10:47 -0300 Subject: [C++-sig] IndexError when returning pointer In-Reply-To: Message-ID: <000501c3005e$1243e0b0$0d00000a@esss.com.br> Hi, I'm exporting a singleton class: struct foo { static foo* get_singleton() { return singleton; } foo* singleton; }; BOOST_PYTHON_MODULE( _frog ) { class_< foo, boost::noncopyable >( "foo", no_init ) .def( "bar", (foo*(*)() ) &foo::bar, return_internal_reference<>() ) .staticmethod( "bar" ) ; } But, when I try to use it, I get: >>> import _foo >>> a = _frog.foo.get_singleton() Traceback (most recent call last): File "", line 1, in ? IndexError: tuple index out of range >>> I couldn't figure out what I'm doing wrong. Can anyone shed some light on this? []'s Marcelo A. Camelo, M. Eng. - Project Leader ESSS - Engineering Simulation and Scientific Software E-mail: camelo at esss.com.br Phone: +55-48-239-2226 From camelo at esss.com.br Fri Apr 11 21:25:50 2003 From: camelo at esss.com.br (Marcelo A. Camelo) Date: Fri, 11 Apr 2003 16:25:50 -0300 Subject: [C++-sig] IndexError when returning pointer In-Reply-To: <000501c3005e$1243e0b0$0d00000a@esss.com.br> Message-ID: <000b01c30060$294e3ec0$0d00000a@esss.com.br> Oops, I've made a terrible mess on the sample code I've sent on my last message. Sorry!!! Here is the correct version: struct foo { static foo* get_singleton() { return singleton; } static foo* singleton; }; foo* foo::singleton = NULL; BOOST_PYTHON_MODULE( frog ) { using namespace boost::python; class_< foo, boost::noncopyable >( "foo", no_init ) .def( "get_singleton", (foo*(*)() ) &foo::get_singleton, return_internal_reference<>() ) .staticmethod( "get_singleton" ) ; } >>> import frog >>> a = frog.foo.get_singleton() Traceback (most recent call last): File "", line 1, in ? IndexError: tuple index out of range >>> -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of Marcelo A. Camelo Sent: sexta-feira, 11 de abril de 2003 16:11 To: c++-sig at python.org Subject: [C++-sig] IndexError when returning pointer Hi, I'm exporting a singleton class: struct foo { static foo* get_singleton() { return singleton; } foo* singleton; }; BOOST_PYTHON_MODULE( _frog ) { class_< foo, boost::noncopyable >( "foo", no_init ) .def( "bar", (foo*(*)() ) &foo::bar, return_internal_reference<>() ) .staticmethod( "bar" ) ; } But, when I try to use it, I get: >>> import _foo >>> a = _frog.foo.get_singleton() Traceback (most recent call last): File "", line 1, in ? IndexError: tuple index out of range >>> I couldn't figure out what I'm doing wrong. Can anyone shed some light on this? []'s Marcelo A. Camelo, M. Eng. - Project Leader ESSS - Engineering Simulation and Scientific Software E-mail: camelo at esss.com.br Phone: +55-48-239-2226 _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From nicodemus at globalite.com.br Fri Apr 11 22:25:54 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Fri, 11 Apr 2003 17:25:54 -0300 Subject: [C++-sig] IndexError when returning pointer In-Reply-To: <000b01c30060$294e3ec0$0d00000a@esss.com.br> References: <000b01c30060$294e3ec0$0d00000a@esss.com.br> Message-ID: <3E9724D2.5000708@globalite.com.br> Hail Camelo! Use return_value_policy for the policy of "get_singleton". That should do it. Pato! Nicodemus. Marcelo A. Camelo wrote: >Oops, > >I've made a terrible mess on the sample code >I've sent on my last message. Sorry!!! > >Here is the correct version: > > struct foo > { > static foo* get_singleton() { return singleton; } > static foo* singleton; > }; > > foo* foo::singleton = NULL; > > BOOST_PYTHON_MODULE( frog ) > { > using namespace boost::python; > > class_< foo, boost::noncopyable >( "foo", no_init ) > .def( "get_singleton", (foo*(*)() ) >&foo::get_singleton, return_internal_reference<>() ) > .staticmethod( "get_singleton" ) > ; > } > > > >>> import frog > >>> a = frog.foo.get_singleton() > Traceback (most recent call last): > File "", line 1, in ? > IndexError: tuple index out of range > >>> > >-----Original Message----- >From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On >Behalf Of Marcelo A. Camelo >Sent: sexta-feira, 11 de abril de 2003 16:11 >To: c++-sig at python.org >Subject: [C++-sig] IndexError when returning pointer > > >Hi, > >I'm exporting a singleton class: > > struct foo > { > static foo* get_singleton() { return singleton; } > foo* singleton; > }; > > BOOST_PYTHON_MODULE( _frog ) > { > class_< foo, boost::noncopyable >( "foo", no_init ) > .def( "bar", (foo*(*)() ) &foo::bar, >return_internal_reference<>() ) > .staticmethod( "bar" ) > ; > } > >But, when I try to use it, I get: > > >>> import _foo > >>> a = _frog.foo.get_singleton() > Traceback (most recent call last): > File "", line 1, in ? > IndexError: tuple index out of range > >>> > >I couldn't figure out what I'm doing wrong. >Can anyone shed some light on this? > >[]'s > > >Marcelo A. Camelo, M. Eng. - Project Leader >ESSS - Engineering Simulation and Scientific Software > >E-mail: camelo at esss.com.br >Phone: +55-48-239-2226 > > > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig > > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig > >. > > > From patrick at vrac.iastate.edu Sat Apr 12 00:04:44 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 11 Apr 2003 17:04:44 -0500 Subject: [C++-sig] Fatal Python errors related to virtual methods Message-ID: <3E973BFC.5000204@vrac.iastate.edu> I am having a problem that seems to be related to virtual methods with default implementations. If I derive a Python class from a C++ class that has virtual methods with default implementations, my application crashes quite frequently with this error message: Fatal Python error: GC object already in linked list Stack traces *always* show that a call is being made into the virtual method override in the wrapper class, and it's always with a method where there is no Python implementation. For example, here is one such stack trace (Boost 1.30.0, GCC 3.2, Red Hat Linux 8.0): #0 0x42028cc1 in kill () from /lib/i686/libc.so.6 #1 0x4003107d in raise () from /lib/i686/libpthread.so.0 #2 0x4202a019 in abort () from /lib/i686/libc.so.6 #3 0x0809703a in Py_FatalError () #4 0x0805eddd in PyTuple_New () #5 0x080b8238 in instancemethod_call () #6 0x080b1557 in PyObject_Call () #7 0x0807b339 in PyEval_CallObjectWithKeywords () #8 0x08093c70 in PyEval_CallMethod () #9 0x40131d5e in boost::python::detail::returnable::type boost::python::call_method(_object*, char const*, boost::type*) (self=0x81956cc, name=0x401b4526 "bufferPreDraw") at /mnt/rigby/home13/users/patrick/src/Juggler/main/juggler/build.linux-rh80.posix.gcc32/instlinks/include/boost/python/call_method.hpp:54 #10 0x40131101 in (anonymous namespace)::vrj_GlApp_Wrapper::bufferPreDraw() (this=0x8195720) at vrj.cpp:235 #11 0x40345c7e in vrj::GlPipe::renderWindow(vrj::GlWindow*) (this=0x827fe10, win=0x827f108) at /home/users/patrick/src/Juggler/main/juggler/modules/vrjuggler/vrj/Draw/OGL/GlPipe.cpp:350 #12 0x40344f36 in vrj::GlPipe::controlLoop(void*) (this=0x827fe10, nullParam=0x0) at /home/users/patrick/src/Juggler/main/juggler/modules/vrjuggler/vrj/Draw/OGL/GlPipe.cpp:188 #13 0x403482cb in vpr::ThreadMemberFunctor::operator()() (this=0x827fed8) at /mnt/rigby/home13/users/patrick/src/Juggler/main/juggler/build.linux-rh80.posix.gcc32/instlinks/include/vpr/Thread/ThreadFunctor.h:127 #14 0x40731386 in vpr::ThreadPosix::startThread(void*) (this=0x827fef0, null_param=0x0) at /home/users/patrick/src/Juggler/main/juggler/modules/vapor/vpr/md/POSIX/Thread/ThreadPosix.cpp:299 #15 0x40731e71 in vpr::ThreadMemberFunctor::operator()() (this=0x827ff50) at /home/users/patrick/src/Juggler/main/juggler/modules/vapor/vpr/Thread/ThreadFunctor.h:127 #16 0x4072d072 in vprThreadFunctorFunction (args=0x827ff50) at /home/users/patrick/src/Juggler/main/juggler/modules/vapor/vpr/Thread/ThreadFunctor.cpp:79 #17 0x4002e941 in pthread_start_thread () from /lib/i686/libpthread.so.0 The wrapper class in question has the following code (generated by Pyste): struct vrj_GlApp_Wrapper: vrj::GlApp { ... void bufferPreDraw() { call_method< void >(self, "bufferPreDraw"); // line 235 } void default_bufferPreDraw() { vrj::GlApp::bufferPreDraw(); } ... }; The relevant Boost.Python code is this: BOOST_PYTHON_MODULE(vrj) { ... class_< vrj::GlApp, bases< vrj::App > , boost::noncopyable, vrj_GlApp_Wrapper >("GlApp", init< >()) .def("bufferPreDraw", &vrj::GlApp::bufferPreDraw, &vrj_GlApp_Wrapper::default_bufferPreDraw) ... } The Python class, which derives from vrj.GlApp, does not override the virtual method bufferPreDraw(). It doesn't have to be this method, though. If I override it in my Python class, the error just happens with a different virtual method that is not overridden. The C++ application framework I am mixing with Python is multi-threaded, and the Python object has its methods invoked from a spawned thread (as is evident from the stack trace above). I saw a message or two on comp.lang.python that led me to believe that threads may be an issue. I don't know for sure, though. I have tried disabling the Python garbage collector, but that doesn't help things. Does anyone have any suggestions about how I can debug this? It's been a problem for me ever since I started using Boost.Python v2, but I always thought I was doing something wrong. It may very well be my error, but at this point, I'm stumped as to how I can move forward. -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 RaoulGough at yahoo.co.uk Sat Apr 12 11:47:00 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Sat, 12 Apr 2003 10:47:00 +0100 Subject: [C++-sig] Less than transparent proxies Message-ID: I have a situation where I want to expose a C++ proxy class to Python, and have access to features of the original object *and* the proxy object. As a very simple example of this, boost::shared_ptr provides a member function unique(). However, using shared_ptr as a holder (or proxy) for your own type T leaves the features of the shared_ptr object invisible to Python, and so the unique() function is inaccessible. I've thought of various ways of trying to work the proxies into Python. Obviously Python doesn't have an indirection operator->(), which is how this is often done in C++ (i.e. client code has to know about the proxy object, and uses operator->() when accessing features of the referant). One option might be to try and set up some kind of IS-A relationship between the Python types (referant IS-A proxy), but I'm starting to think the cleanest option would be to provide a __cxxholder__ method so that client code can explicitly access the holder/proxy when necessary. e.g. obj = HeldViaProxyType() if obj.__cxxholder__().unique(): # ... Unfortunately, I seem to have hit a serious problem right away. The test code (below) produces "already has a registered to_python_converter" at load time, when defining the shared_ptr class which is already registered as a holder for the referant. I guess this was inevitable. Any suggestions or interest in the idea? -- Raoul Gough see http://home.clara.net/raoulgough/ for my work availability ----8<---- code starts ----8<---- #include #include #include #include struct Hello { Hello () { std::cout << "Hello::Hello\n"; } ~Hello () { std::cout << "Hello::~Hello\n"; } void hello () { std::cout << "hello\n"; } }; BOOST_PYTHON_MODULE (proxy) { using namespace boost::python; try { class_ > hello_class ("Hello"); hello_class.def ("hello", &Hello::hello); class_ > ptr_class ("HelloPtr"); ptr_class.def ("unique", &boost::shared_ptr::unique); } catch(...) { handle_exception(); } } ----8<---- example error ----8<---- $ 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 proxy Traceback (most recent call last): File "", line 1, in ? RuntimeError: trying to register to_python_converter for a type which already has a registered to_python_converter >>> ^Z From nico_ml at mgdesign.org Mon Apr 14 10:52:53 2003 From: nico_ml at mgdesign.org (Nicolas Lelong) Date: Mon, 14 Apr 2003 10:52:53 +0200 Subject: [C++-sig] bug? : binding a method returning a possibly NULL polymorphic pointer Message-ID: <00c201c30263$3d4cd850$cb00a8c0@nico> Hi, I have a method that returns a shared_ptr object, where Base is a polymorphic class, and the shared_ptr can reference no object. I found out that when this method effectively returns a shared_ptr-wrapped NULL, I get an exception that tells me that typeid can't be applied on NULL - or that RTTI can't be extracted from a NULL object (I did not note the exact message provided by VC7). This error comes from 'get_derived_class_object(mpl::true_, [...])' in make_instance_ptr.hpp. The original code is : template static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x) { converter::registration const* r = converter::registry::query(type_info(typeid(*x))); return r ? r->m_class_object : 0; } I'd like to suggest the following implementation that does not execute typeid on a dereferenced NULL pointer, and lets the Python script deal with a None value : template static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x) { converter::registration const* r = x ? converter::registry::query(type_info(typeid(*x))) : 0; return r ? r->m_class_object : 0; } I had a quick look and this modification seems to be sufficient to correct the problem. Cheers, Nicolas -------------- next part -------------- An HTML attachment was scrubbed... URL: From jacek.generowicz at cern.ch Mon Apr 14 17:15:20 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: 14 Apr 2003 17:15:20 +0200 Subject: [C++-sig] Boost: overloads documentation Message-ID: References: Tutorial (Tut): http://www.boost.org/libs/python/doc/tutorial/doc/default_arguments.html Reference Manual (RM): http://www.boost.org/libs/python/doc/v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec The example in the RM introduces an overload dispatcher with the name "f_overloads" in the line BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3) This appears not to be used anywhere. Is this right ? The Tut suggests that overload dispatchers should be passed to def thus (in this case the overload dispatcher is called "foo_overloads"): .def("foo", foo, foo_overloads()); Should the dot preceding "def" in the line above really be there? foo is a non-member function; but the line is quoted without context, so I can't see (or imagine) what the scope might be. Is my confusion caused my by inability to read docs, or is there something Not Quite As It Should Be ? From dave at boost-consulting.com Fri Apr 11 10:23:11 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 11 Apr 2003 04:23:11 -0400 Subject: [C++-sig] Re: staticmethod usage In-Reply-To: <3E9444A1.E39B796B@sitius.com> (Nikolay Mladenov's message of "Wed, 09 Apr 2003 12:04:49 -0400") References: <3E9444A1.E39B796B@sitius.com> Message-ID: Nikolay Mladenov writes: > I think the only way is to use different names. That's correct. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Apr 15 01:35:41 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 14 Apr 2003 20:35:41 -0300 Subject: [C++-sig] Pyste and inheritance from a templated class In-Reply-To: <3E9640AB.904@globalite.com.br> References: <3E959D46.8040005@vrac.iastate.edu> <3E9640AB.904@globalite.com.br> Message-ID: <3E9B45CD.5060401@globalite.com.br> Nicodemus wrote: > Patrick Hartling wrote: > >> I just returned from a trip, and I am trying out the features added >> to Pyste during the last several days. With the latest code, I have >> encountered a problem related to inheritance relationships between >> C++ class. I am not sure if this is a bug or if there is something >> new I have to do in my .pyste file. What I am seeing is that Pyste >> does not include the boost::python::bases<> template parameter when a >> boost::python::class_<> is declared for a class derived from a >> templated class. >> >> The attached code demonstrates the problem. Pyste generates the >> correct Boost.Python code if I use AllFromHeader(), but I can't >> always use that function (unfortunately). Pyste from Boost 1.30.0 >> works as I expect, and again, this may be something that I missed >> while reviewing the large volume email I received while I was away. >> Thanks. >> >> -Patrick > > > > It's a bug, for sure! I will take a look into it. Thanks! Fixed in CVS. Thanks again for the report Patrick! Regards, Nicodemus. From nicodemus at globalite.com.br Tue Apr 15 01:52:32 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 14 Apr 2003 20:52:32 -0300 Subject: [C++-sig] shared_ptr converters Message-ID: <3E9B49C0.8030404@globalite.com.br> Hi all! I'm having some troubles with the boost::shared_ptr support. Suppose this code: test.h ------------------------------------------------------- #include struct A { virtual int f() = 0; }; struct B: A { int f() { return 1; } }; boost::shared_ptr New() { return boost::shared_ptr( new B() ); } test.cpp ------------------------------------------------------- // Includes ==================================================================== #include #include // Using ======================================================================= using namespace boost::python; // Declarations ================================================================ struct A_Wrapper: A { A_Wrapper(PyObject* self_): A(), self(self_) {} int f() { return call_method< int >(self, "f"); } PyObject* self; }; // Module ====================================================================== BOOST_PYTHON_MODULE(test) { class_ >("A") ; def("New", &New); } The code compiles fine, without any errors or warnings. Now, inside Python: ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> from test import * >>> New() Traceback (most recent call last): File "", line 1, in ? TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr >>> Is this a bug, or am I missing something? I tried changing the order of the template parameters of class_, but then the code either doesn't compile, or compiles but gives the same results (I don't think the error messages from the compiler are revelant in this case, but I will post if there's need). Regards, Nicodemus. From hfeltman at vbbn.com Tue Apr 15 08:18:19 2003 From: hfeltman at vbbn.com (Hamilton Feltman) Date: Mon, 14 Apr 2003 23:18:19 -0700 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3E9B49C0.8030404@globalite.com.br> Message-ID: <000001c30316$cfa77d50$67fea8c0@venus> Hello! So I'm not the only one stumbling on this. Unfortunately I don't have an answer, but I boiled down the code to demonstrate the problem: struct SomeClass { int a, b; SomeClass (int a, int b) : a(a), b(b) {} }; boost::shared_ptr SomeFunction (int a, int b) { return boost::shared_ptr (new SomeClass(a, b)); } BOOST_PYTHON_MODULE(Test) { class_("SomeClass", init()); def ("SomeFunction", SomeFunction); } >>> from Test import * import Test # dynamically loaded from Test_d.dll [9005 refs] >>> obj = SomeFunction (3,3) Traceback (most recent call last): File "", line 1, in ? TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr [9021 refs] Anyone have a clue? Seems like a fairly straightforward conversion, but I don't know enough about boost python, or all the internal amazements going on inside it (but learning quick). I'm running vc7 on windows. Hamilton Feltman Harmonicdog Entertainment -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of Nicodemus Sent: Monday, April 14, 2003 4:53 PM To: c++-sig at python.org Subject: [C++-sig] shared_ptr converters Hi all! I'm having some troubles with the boost::shared_ptr support. Suppose this code: test.h ------------------------------------------------------- #include struct A { virtual int f() = 0; }; struct B: A { int f() { return 1; } }; boost::shared_ptr New() { return boost::shared_ptr( new B() ); } test.cpp ------------------------------------------------------- // Includes ==================================================================== #include #include // Using ======================================================================= using namespace boost::python; // Declarations ================================================================ struct A_Wrapper: A { A_Wrapper(PyObject* self_): A(), self(self_) {} int f() { return call_method< int >(self, "f"); } PyObject* self; }; // Module ====================================================================== BOOST_PYTHON_MODULE(test) { class_ >("A") ; def("New", &New); } The code compiles fine, without any errors or warnings. Now, inside Python: ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>> from test import * >>> New() Traceback (most recent call last): File "", line 1, in ? TypeError: No to_python (by-value) converter found for C++ type: class boost::shared_ptr >>> Is this a bug, or am I missing something? I tried changing the order of the template parameters of class_, but then the code either doesn't compile, or compiles but gives the same results (I don't think the error messages from the compiler are revelant in this case, but I will post if there's need). Regards, Nicodemus. _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From nicodemus at globalite.com.br Tue Apr 15 12:48:41 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 15 Apr 2003 07:48:41 -0300 Subject: [C++-sig] shared_ptr converters In-Reply-To: <000001c30316$cfa77d50$67fea8c0@venus> References: <000001c30316$cfa77d50$67fea8c0@venus> Message-ID: <3E9BE389.6080404@globalite.com.br> Hamilton Feltman wrote: >Hello! So I'm not the only one stumbling on this. Unfortunately I don't >have an answer, but I boiled down the code to demonstrate the problem: > > >struct SomeClass >{ > int a, b; > SomeClass (int a, int b) : a(a), b(b) {} >}; > >boost::shared_ptr SomeFunction (int a, int b) >{ > return boost::shared_ptr (new SomeClass(a, b)); >} > >BOOST_PYTHON_MODULE(Test) >{ > class_("SomeClass", init()); > def ("SomeFunction", SomeFunction); >} > > I believe the conversion of shared_ptr's are automatic only from-python. For to-python conversions you need to specify the holder for your class: class >(...); That should work. Problem with my example is that, even thought the converter is being registered, it's not working. 8( >>>>from Test import * >>>> >>>> >import Test # dynamically loaded from Test_d.dll >[9005 refs] > > >>>>obj = SomeFunction (3,3) >>>> >>>> >Traceback (most recent call last): > File "", line 1, in ? >TypeError: No to_python (by-value) converter found for C++ type: class >boost::shared_ptr >[9021 refs] > >Anyone have a clue? Seems like a fairly straightforward conversion, but >I don't know enough about boost python, or all the internal amazements >going on inside it (but learning quick). I'm running vc7 on windows. > > Hope that helps, Nicodemus. From dave at boost-consulting.com Tue Apr 15 13:11:29 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 15 Apr 2003 07:11:29 -0400 Subject: [C++-sig] Boost: overloads documentation In-Reply-To: (Jacek Generowicz's message of "14 Apr 2003 17:15:20 +0200") References: Message-ID: Jacek Generowicz writes: > References: > > Tutorial (Tut): > > http://www.boost.org/libs/python/doc/tutorial/doc/default_arguments.html > > Reference Manual (RM): > > http://www.boost.org/libs/python/doc/v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec > > The example in the RM introduces an overload dispatcher with the name > "f_overloads" in the line > > BOOST_PYTHON_FUNCTION_OVERLOADS(f_overloads, f, 0, 3) > > This appears not to be used anywhere. Is this right ? Fixed in CVS, thanks! > The Tut suggests that overload dispatchers should be passed to def > thus (in this case the overload dispatcher is called "foo_overloads"): > > .def("foo", foo, foo_overloads()); > > Should the dot preceding "def" in the line above really be there? foo > is a non-member function; but the line is quoted without context, so I > can't see (or imagine) what the scope might be. I'll leave this one to Joel. > Is my confusion caused my by inability to read docs, or is there > something Not Quite As It Should Be ? Definitely the lattter ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com From djowel at gmx.co.uk Tue Apr 15 14:52:57 2003 From: djowel at gmx.co.uk (Joel de Guzman) Date: Tue, 15 Apr 2003 20:52:57 +0800 Subject: [C++-sig] Boost: overloads documentation References: Message-ID: <022e01c3034d$f3e48230$d85e4eca@kim> David Abrahams wrote: >> The Tut suggests that overload dispatchers should be passed to def >> thus (in this case the overload dispatcher is called >> "foo_overloads"): >> >> .def("foo", foo, foo_overloads()); >> >> Should the dot preceding "def" in the line above really be there? foo >> is a non-member function; but the line is quoted without context, so >> I >> can't see (or imagine) what the scope might be. Yes, it's an error. Fixed and committed to CVS. Thanks for spotting this. -- Joel de Guzman joel at boost-consulting.com http://www.boost-consulting.com http://spirit.sf.net From jacek.generowicz at cern.ch Tue Apr 15 16:10:59 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: 15 Apr 2003 16:10:59 +0200 Subject: [C++-sig] SWIG: overriding virtual functions in Python. Message-ID: given a C++ class struct foo { virtual void one() { cout << "This is foo::one() calling two()" << endl; two(); } virtual void two() { cout << "This is foo::two()" << endl; } }; I would like to subclass it in Python and override "two()" thus: class bar(foo): def two(self): print "This is bar.two()" in such a way that calling bar.one() ... bar().one() gives the result This is foo::one() calling two() This is bar.two() rather than This is foo::one() calling two() This is foo.two() In Boost this is achieved by doing providing a wrapper class around the original C++ implementation, and giving it a default implementation of the virtual function, which calls back into Python. Is there a way of doing it in SWIG? From dave at boost-consulting.com Tue Apr 15 16:22:56 2003 From: dave at boost-consulting.com (Dave Abrahams) Date: Tue, 15 Apr 2003 10:22:56 -0400 Subject: [C++-sig] IndexError when returning pointer References: <000b01c30060$294e3ec0$0d00000a@esss.com.br> Message-ID: <00d901c3035a$afe18bc0$9101a8c0@penguin> On Friday, April 11, 2003 3:25 PM [GMT+1=CET], Marcelo A. Camelo wrote: > Oops, > > I've made a terrible mess on the sample code > I've sent on my last message. Sorry!!! > > Here is the correct version: > > struct foo > { > static foo* get_singleton() { return singleton; } > static foo* singleton; > }; > > foo* foo::singleton = NULL; > > BOOST_PYTHON_MODULE( frog ) > { > using namespace boost::python; > > class_< foo, boost::noncopyable >( "foo", no_init ) > .def( "get_singleton", (foo*(*)() ) ^^^^^^^^^^^^ > &foo::get_singleton, return_internal_reference<>() ) > .staticmethod( "get_singleton" ) > ; > } > > > > > > import frog > > > > a = frog.foo.get_singleton() > Traceback (most recent call last): > File "", line 1, in ? > IndexError: tuple index out of range It's got nothing to do with your problem, but it's usually bad form to use a cast (especially a C-style cast) when it's not needed. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com From dave at boost-consulting.com Tue Apr 15 16:44:28 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 15 Apr 2003 10:44:28 -0400 Subject: [C++-sig] Fatal Python errors related to virtual methods In-Reply-To: <3E973BFC.5000204@vrac.iastate.edu> (Patrick Hartling's message of "Fri, 11 Apr 2003 17:04:44 -0500") References: <3E973BFC.5000204@vrac.iastate.edu> Message-ID: Patrick Hartling writes: > The C++ application framework I am mixing with Python is > multi-threaded, and the Python object has its methods invoked from a > spawned thread (as is evident from the stack trace above). I saw a > message or two on comp.lang.python that led me to believe that threads > may be an issue. I don't know for sure, though. It certainly is /an/ issue. Can't say for sure if it's /the/ issue. Here's what you need to do, in a nutshell: Any place that call_method<...>(...) can be invoked on a thread that isn't the thread running the Python interpreter, you need to surround it with macro invocations which acquire the Global Interpreter Lock (GIL) and establishes the thread state (and then subsequently release it): http://www.python.org/dev/doc/devel/api/threads.html#l2h-751 has a description. It looks as though you'll need to save away a copy of the thread state in your module initialization function or something to accomplish the above. Any place that you a wrapping a function which might invoke such a surrounded call_method<...> invocation, you must release the GIL and then subsequently acquire it. You can do this by wrapping a "thin wrapper" function which just adds the neccessary GIL management. Adding the ability to do this stuff automatically (so you don't have to do as much of it by hand) globally for an extension module or on a function-by-function basis is something I've been meaning to get to for a while. If you figure out the formula, we'll have a head start at integrating the functionality into Boost.Python. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Apr 15 17:16:56 2003 From: dave at boost-consulting.com (Dave Abrahams) Date: Tue, 15 Apr 2003 11:16:56 -0400 Subject: [C++-sig] Less than transparent proxies References: Message-ID: <000801c30363$31948b10$9101a8c0@penguin> Raoul Gough wrote: > I have a situation where I want to expose a C++ proxy class to Python, > and have access to features of the original object *and* the proxy > object. As a very simple example of this, boost::shared_ptr provides a > member function unique(). However, using shared_ptr as a holder (or > proxy) for your own type T leaves the features of the shared_ptr > object invisible to Python, and so the unique() function is > inaccessible. OK... > I've thought of various ways of trying to work the proxies into > Python. Obviously Python doesn't have an indirection operator->(), > which is how this is often done in C++ (i.e. client code has to know > about the proxy object, and uses operator->() when accessing features > of the referant). One option might be to try and set up some kind of > IS-A relationship between the Python types (referant IS-A proxy), but > I'm starting to think the cleanest option would be to provide a > __cxxholder__ method so that client code can explicitly access the > holder/proxy when necessary. > > e.g. > > obj = HeldViaProxyType() > if obj.__cxxholder__().unique(): > # ... Normally proxies in Python don't give you a way to distinguish the proxy from the target class. > Unfortunately, I seem to have hit a serious problem right away. The > test code (below) produces "already has a registered > to_python_converter" at load time, when defining the shared_ptr class > which is already registered as a holder for the referant. I guess this > was inevitable. Any suggestions or interest in the idea? It's interesting, but I don't think you've got the best approach here. Why the cumbersome extra syntax? Why the redundant exception-handling code in your module initialization function? And why not just: ----8<---- code starts ----8<---- #include #include #include #include struct Hello { Hello () { std::cout << "Hello::Hello\n"; } ~Hello () { std::cout << "Hello::~Hello\n"; } void hello () { std::cout << "hello\n"; } }; BOOST_PYTHON_MODULE (proxy) { using namespace boost::python; class_ >("Hello") .def ("hello", &Hello::hello) .def ("_unique", &boost::shared_ptr::unique) ; } ----8<---- example error ----8<---- ?? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com From patrick at vrac.iastate.edu Tue Apr 15 17:41:23 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Tue, 15 Apr 2003 10:41:23 -0500 Subject: [C++-sig] Fatal Python errors related to virtual methods References: <3E973BFC.5000204@vrac.iastate.edu> Message-ID: <3E9C2823.5020704@vrac.iastate.edu> David, Thank you very much for this insight. My Python/C knowledge is quite limited (I dove into Boost.Python without having background in Python/C), and I didn't know about the GIL. This sounds very promising. If I do come up with a helpful "formula" for you, I'll be sure to pass it on. -Patrick David Abrahams wrote: > Patrick Hartling writes: > > >>The C++ application framework I am mixing with Python is >>multi-threaded, and the Python object has its methods invoked from a >>spawned thread (as is evident from the stack trace above). I saw a >>message or two on comp.lang.python that led me to believe that threads >>may be an issue. I don't know for sure, though. > > > It certainly is /an/ issue. Can't say for sure if it's /the/ issue. > > Here's what you need to do, in a nutshell: > > Any place that call_method<...>(...) can be invoked on a > thread that isn't the thread running the Python interpreter, > you need to surround it with macro invocations which acquire > the Global Interpreter Lock (GIL) and establishes the thread > state (and then subsequently release it): > > http://www.python.org/dev/doc/devel/api/threads.html#l2h-751 > has a description. > > It looks as though you'll need to save away a copy of the > thread state in your module initialization function or > something to accomplish the above. > > Any place that you a wrapping a function which might invoke > such a surrounded call_method<...> invocation, you must release > the GIL and then subsequently acquire it. You can do this by > wrapping a "thin wrapper" function which just adds the > neccessary GIL management. > > Adding the ability to do this stuff automatically (so you don't > have to do as much of it by hand) globally for an extension module > or on a function-by-function basis is something I've been meaning > to get to for a while. If you figure out the formula, we'll have a > head start at integrating the functionality into Boost.Python. > > HTH, -- 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 dave at boost-consulting.com Tue Apr 15 19:07:14 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 15 Apr 2003 13:07:14 -0400 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3E9B49C0.8030404@globalite.com.br> (Nicodemus's message of "Mon, 14 Apr 2003 20:52:32 -0300") References: <3E9B49C0.8030404@globalite.com.br> Message-ID: Nicodemus writes: > BOOST_PYTHON_MODULE(test) > { > class_ >("A") > ; > > def("New", &New); > } The code compiles fine, without any errors or warnings. Now, > inside Python: > > ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on > Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> > >>> from test import * > >>> New() > Traceback (most recent call last): > File "", line 1, in ? > TypeError: No to_python (by-value) converter found for C++ type: class > boost::shared_ptr > >>> > > Is this a bug, or am I missing something? I tried changing the order > of the template parameters of class_, but then the code either doesn't > compile, or compiles but gives the same results (I don't think the > error messages from the compiler are revelant in this case, but I will > post if there's need). What happens if you get rid of boost::noncopyable and give f a default implementation (but use the same wrapping code otherwise)? If everything works, it is a bug wherein noncopyable prevents registration of the converter for the holding smart pointer. -- Dave Abrahams Boost Consulting www.boost-consulting.com From RaoulGough at yahoo.co.uk Tue Apr 15 21:10:37 2003 From: RaoulGough at yahoo.co.uk (Raoul Gough) Date: Tue, 15 Apr 2003 20:10:37 +0100 Subject: [C++-sig] Re: Less than transparent proxies References: <000801c30363$31948b10$9101a8c0@penguin> Message-ID: "Dave Abrahams" wrote in message news:000801c30363$31948b10$9101a8c0 at penguin... > Raoul Gough wrote: [snip] > > I've thought of various ways of trying to work the proxies into > > Python. Obviously Python doesn't have an indirection operator->(), > > which is how this is often done in C++ (i.e. client code has to know > > about the proxy object, and uses operator->() when accessing features > > of the referant). One option might be to try and set up some kind of > > IS-A relationship between the Python types (referant IS-A proxy), but > > I'm starting to think the cleanest option would be to provide a > > __cxxholder__ method so that client code can explicitly access the > > holder/proxy when necessary. > > > > e.g. > > > > obj = HeldViaProxyType() > > if obj.__cxxholder__().unique(): > > # ... > > Normally proxies in Python don't give you a way to distinguish the proxy > from the target class. So the C++ style of proxies doesn't fit Python. I guess I was trying to transfer the concepts directly, but there's no actual need for this. > > > Unfortunately, I seem to have hit a serious problem right away. The > > test code (below) produces "already has a registered > > to_python_converter" at load time, when defining the shared_ptr class > > which is already registered as a holder for the referant. I guess this > > was inevitable. Any suggestions or interest in the idea? > > It's interesting, but I don't think you've got the best approach here. Why > the cumbersome extra syntax? Why the redundant exception-handling code in > your module initialization function? Don't really remember why the exception handler is there - unless it was necessary with the earlier version of the library (I converted all my boost C++ Python code a while back). > And why not just: > > > ----8<---- code starts ----8<---- > > #include > #include > #include > #include > > struct Hello { > Hello () { > std::cout << "Hello::Hello\n"; > } > > ~Hello () { > std::cout << "Hello::~Hello\n"; > } > > void hello () { std::cout << "hello\n"; } > }; > > BOOST_PYTHON_MODULE (proxy) > { > using namespace boost::python; > > class_ >("Hello") > .def ("hello", &Hello::hello) > .def ("_unique", &boost::shared_ptr::unique) > ; > } I'm surprised to learn that this works at all, so it's no wonder I didn't think of doing it that way :-) I would have thought that the Python object (e.g. "") would not be suitable for the call to shared_ptr::unique(). On the C++ side, an object is _either_ a Hello or a shared_ptr, and neither one of them provides both functions (hello and unique). So does the Python object get converted to the shared_ptr, rather than its target object, depending on the type of the C++ function being applied? Anyway, it looks like a nice and easy solution - thanks very much! -- Raoul Gough see http://home.clara.net/raoulgough/ for my work availability From dave at boost-consulting.com Tue Apr 15 21:33:19 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 15 Apr 2003 15:33:19 -0400 Subject: [C++-sig] Re: Less than transparent proxies In-Reply-To: ("Raoul Gough"'s message of "Tue, 15 Apr 2003 20:10:37 +0100") References: <000801c30363$31948b10$9101a8c0@penguin> Message-ID: "Raoul Gough" writes: > "Dave Abrahams" wrote in message > news:000801c30363$31948b10$9101a8c0 at penguin... >> >> Normally proxies in Python don't give you a way to distinguish the > proxy >> from the target class. > > So the C++ style of proxies doesn't fit Python. I'm not sure I'd say that. All I meant is that the proxy generally forwards everything to its delegate. > I guess I was trying > to transfer the concepts directly, but there's no actual need for > this. Maybe not. >> >> > Unfortunately, I seem to have hit a serious problem right away. >> > The test code (below) produces "already has a registered >> > to_python_converter" at load time, when defining the shared_ptr >> > class which is already registered as a holder for the referant. I >> > guess this was inevitable. Any suggestions or interest in the >> > idea? >> >> It's interesting, but I don't think you've got the best approach >> here. Why the cumbersome extra syntax? Why the redundant >> exception-handling code in your module initialization function? > > Don't really remember why the exception handler is there - unless it > was necessary with the earlier version of the library It was. >> And why not just: >> >> >> ----8<---- code starts ----8<---- >> >> #include >> #include >> #include >> #include >> >> struct Hello { >> Hello () { >> std::cout << "Hello::Hello\n"; >> } >> >> ~Hello () { >> std::cout << "Hello::~Hello\n"; >> } >> >> void hello () { std::cout << "hello\n"; } >> }; >> >> BOOST_PYTHON_MODULE (proxy) >> { >> using namespace boost::python; >> >> class_ >("Hello") >> .def ("hello", &Hello::hello) >> .def ("_unique", &boost::shared_ptr::unique) >> ; >> } > > I'm surprised to learn that this works at all, so it's no wonder I > didn't think of doing it that way :-) I would have thought that the > Python object (e.g. "") would not be > suitable for the call to shared_ptr::unique(). On the C++ side, an > object is _either_ a Hello or a shared_ptr, and neither one of > them provides both functions (hello and unique). So does the Python > object get converted to the shared_ptr, rather than its target object, > depending on the type of the C++ function being applied? Precisely. Basically, when you try to call a wrapped C++ function, Boost.Python tries to convert each of the Python arguments to the corresponding C++ argument type. Since any Hello object held by shared_ptr can be converted to a shared_ptr&, that should work just fine. > Anyway, it looks like a nice and easy solution - thanks very much! No sweat. -Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Apr 15 22:48:15 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 15 Apr 2003 17:48:15 -0300 Subject: [C++-sig] shared_ptr converters In-Reply-To: References: <3E9B49C0.8030404@globalite.com.br> Message-ID: <3E9C700F.8050904@globalite.com.br> David Abrahams wrote: >What happens if you get rid of boost::noncopyable and give f a default >implementation (but use the same wrapping code otherwise)? If >everything works, it is a bug wherein noncopyable prevents >registration of the converter for the holding smart pointer. > Removing boost::noncopyable didn't help, it compiles fine (I just had to add a copy constructor to the wrapper class, which was expected), but calling New() raises the same exception. Now, removing the wrapper class and putting back boost::noncopyable worked fine. For clarification: BOOST_PYTHON_MODULE(test) { class_ >("A") ; def("New", &New); } So, it is related to the wrapper class. Here it is again: struct A_Wrapper: A { A_Wrapper(PyObject* self_): A(), self(self_) {} A_Wrapper(PyObject* self_, const A& a): A(a), self(self_) {} int f() { return call_method< int >(self, "f"); } PyObject* self; }; Any ideas? Regards, Nicodemus. From camelo at esss.com.br Tue Apr 15 23:08:45 2003 From: camelo at esss.com.br (Marcelo A. Camelo) Date: Tue, 15 Apr 2003 18:08:45 -0300 Subject: [C++-sig] IndexError when returning pointer In-Reply-To: <00d901c3035a$afe18bc0$9101a8c0@penguin> Message-ID: <000a01c30393$345e3190$0d00000a@esss.com.br> > It's got nothing to do with your problem, > but it's usually bad form to use a cast > (especially a C-style cast) when it's not > needed. Thank you for the reminder. But I do still need it when exporting overloaded methods, don't I? If so, I will make sure my bindings generator only specify the cast when exporting overloaded methods. Greetings, Marcelo A. Camelo, M. Eng. ? Project Leader ESSS ? Engineering Simulation and Scientific Software E-mail: camelo at esss.com.br Phone: +55-48-239-2226 -----Original Message----- From: c++-sig-admin at python.org [mailto:c++-sig-admin at python.org] On Behalf Of Dave Abrahams Sent: ter?a-feira, 15 de abril de 2003 11:23 To: c++-sig at python.org Subject: Re: [C++-sig] IndexError when returning pointer On Friday, April 11, 2003 3:25 PM [GMT+1=CET], Marcelo A. Camelo wrote: > Oops, > > I've made a terrible mess on the sample code > I've sent on my last message. Sorry!!! > > Here is the correct version: > > struct foo > { > static foo* get_singleton() { return singleton; } > static foo* singleton; > }; > > foo* foo::singleton = NULL; > > BOOST_PYTHON_MODULE( frog ) > { > using namespace boost::python; > > class_< foo, boost::noncopyable >( "foo", no_init ) > .def( "get_singleton", (foo*(*)() ) ^^^^^^^^^^^^ > &foo::get_singleton, return_internal_reference<>() ) .staticmethod( > "get_singleton" ) ; > } > > > > > > import frog > > > > a = frog.foo.get_singleton() > Traceback (most recent call last): > File "", line 1, in ? > IndexError: tuple index out of range It's got nothing to do with your problem, but it's usually bad form to use a cast (especially a C-style cast) when it's not needed. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From dave at boost-consulting.com Wed Apr 16 02:18:09 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 15 Apr 2003 20:18:09 -0400 Subject: [C++-sig] IndexError when returning pointer In-Reply-To: <000a01c30393$345e3190$0d00000a@esss.com.br> ("Marcelo A. Camelo"'s message of "Tue, 15 Apr 2003 18:08:45 -0300") References: <000a01c30393$345e3190$0d00000a@esss.com.br> Message-ID: "Marcelo A. Camelo" writes: >> It's got nothing to do with your problem, >> but it's usually bad form to use a cast >> (especially a C-style cast) when it's not >> needed. > > Thank you for the reminder. But I do still need > it when exporting overloaded methods, don't I? > If so, I will make sure my bindings generator > only specify the cast when exporting overloaded > methods. You don't need to cast; you can declare a variable of the appropriate type and assign into that: void (*pf)(int, double) = f; def("f", pf, ...); I've been meaning to submit this implicit_cast function (which would also be safe) to Boost: template T implicit_cast(T x) { return x; } def("f", implicit_cast(f)); -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Apr 16 15:35:34 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 16 Apr 2003 09:35:34 -0400 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3E9B49C0.8030404@globalite.com.br> (Nicodemus's message of "Mon, 14 Apr 2003 20:52:32 -0300") References: <3E9B49C0.8030404@globalite.com.br> Message-ID: Nicodemus writes: > Is this a bug, or am I missing something? I tried changing the order > of the template parameters of class_, but then the code either doesn't > compile, or compiles but gives the same results (I don't think the > error messages from the compiler are revelant in this case, but I will > post if there's need). Argh! Well, it's not a bug exactly, but the library needs to change a bit to accomodate this use-case. If you want instances of A to be held by shared_ptr, the appropriate way to wrap your class is: class_ >("A") ; or class_, boost::noncopyable>("A") ; Of course, the problem with this is that you are also wrapping a function which returns a shared_ptr (New), and there's no automatic to_python conversion for shared_ptr for any X. If you don't care that your instances of A are held by shared_ptr, you can wrap them as follows: class_("A") ; or class_("A") ; but then the same problem holds (there's no to-python converter for shared_ptr). The right answer is to change the library so that shared_ptr can be automatically converted to_python for any X (and likewise for any smart pointer) as long as a class_ for X is registered. That change will require some work. In the meantime, you can do this horrible thing: objects::class_value_wrapper< shared_ptr , objects::make_ptr_instance,A> > >(); Which will register a to_python converter for shared_ptr. P.S. The number of issues like this one is piling up. If there are any companies out there who depend on Boost.Python, it might be a good investment to fund some development so that we can keep the project healthy (hint, hint)! -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Apr 16 16:36:14 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 16 Apr 2003 10:36:14 -0400 Subject: [C++-sig] bug? : binding a method returning a possibly NULL polymorphic pointer In-Reply-To: <00c201c30263$3d4cd850$cb00a8c0@nico> ("Nicolas Lelong"'s message of "Mon, 14 Apr 2003 10:52:53 +0200") References: <00c201c30263$3d4cd850$cb00a8c0@nico> Message-ID: "Nicolas Lelong" writes: > Hi, > > I have a method that returns a shared_ptr object, where Base > is a polymorphic class, and the shared_ptr can reference no object. > > I found out that when this method effectively returns a >shared_ptr-wrapped NULL, I get an exception that tells me that typeid >can't be applied on NULL - or that RTTI can't be extracted from a >NULL object (I did not note the exact message provided by VC7). This >error comes from 'get_derived_class_object(mpl::true_, [...])' in >make_instance_ptr.hpp. > > The original code is : > > template > static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x) > { > converter::registration const* r = converter::registry::query(type_info(typeid(*x))); > return r ? r->m_class_object : 0; > } > > I'd like to suggest the following implementation that does not > execute typeid on a dereferenced NULL pointer, and lets the Python > script deal with a None value : > > template > static inline PyTypeObject* get_derived_class_object(mpl::true_, U const volatile* x) > { > converter::registration const* r = x ? converter::registry::query(type_info(typeid(*x))) : 0; > return r ? r->m_class_object : 0; > } > > I had a quick look and this modification seems to be sufficient to > correct the problem. Cheers, That's not quite the right fix because shared_ptr() gets converted to a Python A object with no C++ data, whereas it should get converted to None. I made the right fix in CVS and merged it to RC_1_30_0 in case we do a 1.30.1 release. Thanks for the report, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From okuda1 at llnl.gov Wed Apr 16 20:33:52 2003 From: okuda1 at llnl.gov (chuzo okuda) Date: Wed, 16 Apr 2003 11:33:52 -0700 Subject: [C++-sig] What version of compiler is it using? References: <00c201c30263$3d4cd850$cb00a8c0@nico> Message-ID: <3E9DA210.F1C4BC60@llnl.gov> Hello, From rwgk at yahoo.com Wed Apr 16 20:56:57 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 16 Apr 2003 11:56:57 -0700 (PDT) Subject: [C++-sig] What version of compiler is it using? In-Reply-To: <3E9DA210.F1C4BC60@llnl.gov> Message-ID: <20030416185657.51817.qmail@web20205.mail.yahoo.com> We use the same bjam command line for all gcc compilers, but before calling bjam we source a tiny script to set PATH and LD_LIBRARY_PATH. For example: set path=(/usr/local_cci/gcc-3.0.3/bin $path) if ( $?LD_LIBRARY_PATH ) then setenv LD_LIBRARY_PATH "/usr/local_cci/gcc-3.0.3/lib:${LD_LIBRARY_PATH}" else setenv LD_LIBRARY_PATH "/usr/local_cci/gcc-3.0.3/lib" endif HTH, Ralf --- chuzo okuda wrote: > Hello, > From executing bjam, and getting output to the terminal, it is not clear > which version of g++/gcc compiler I am getting to compile sources. There > is newer g++ installed in our computer center: __________________________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo http://search.yahoo.com From dave at boost-consulting.com Wed Apr 16 21:09:07 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 16 Apr 2003 15:09:07 -0400 Subject: [C++-sig] What version of compiler is it using? In-Reply-To: <3E9DA210.F1C4BC60@llnl.gov> (chuzo okuda's message of "Wed, 16 Apr 2003 11:33:52 -0700") References: <00c201c30263$3d4cd850$cb00a8c0@nico> <3E9DA210.F1C4BC60@llnl.gov> Message-ID: chuzo okuda writes: > Hello, > From executing bjam, and getting output to the terminal, it is not clear > which version of g++/gcc compiler I am getting to compile sources. There > is newer g++ installed in our computer center: > > pengra0(828) which g++-3.2.1 > /usr/local/bin/g++-3.2.1 > > pengra0(829) ../../../tools/build/jam_src/bin.linuxx86/bjam -sTOOLS=gcc > -sBUILD=debug -sJAMBASE= -sBOOST_ROOT= -sBOOST_BUILD_PATH= > -sGXX=g++-3.2.1 -sGCC=gcc-3.2.1 > > The output to my terminal does not give me info that g++-3.2.1 is used > as follow: > > gcc-C++-action > ../../../libs/test/build/bin/libunit_test_framework.a/gcc/debug/runtime-link-dynamic/unit_test_result.o > > So, could you please tell me how to find out whether g++-3.2.1 was used > or just g++ (which uses version 2.9.6)? Invoke bjam with -d+2 as the first option and you can see the exact command-lines it uses to invoke the compiler. Invoke with "-sBUILD=debug -v" and it will pass -v on the g++ command-line, which makes g++ report its version. > Also, please tell me if the command line above is the correct way to use > g++-3.2.1 compiler? > > g++-3.2.1 compiler is symbolically linked to > /usr/local/tools/gnu/gcc/3.2.1_redhat_7a_ia32/bin/g++, so I can simply > do: > > 1) setenv GCC_ROOT_DIRECTORY > /usr/local/tools/gnu/gcc/3.2.1_redhat_7a_ia32 > 2) ../../../tools/build/jam_src/bin.linuxx86/bjam -sTOOLS=gcc > -sBUILD=debug -sJAMBASE= -sBOOST_ROOT= -sBOOST_BUILD_PATH= > > without using -sGXX=g++-3.2.1 ? Yes. In fact, that's the best way to do it. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Apr 16 23:15:45 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 16 Apr 2003 18:15:45 -0300 Subject: [C++-sig] shared_ptr converters In-Reply-To: References: <3E9B49C0.8030404@globalite.com.br> Message-ID: <3E9DC801.50802@globalite.com.br> David Abrahams wrote: >In the meantime, you can do this horrible thing: > > objects::class_value_wrapper< > shared_ptr > , objects::make_ptr_instance,A> > > >(); > >Which will register a to_python converter for shared_ptr. > Hmm, no problem. Thanks for the help! I will make Pyste generate this code instead of the usual "class_ >", at least until the necessary changes in Boost.Python are made. 8) Thanks again, Nicodemus. From dave at boost-consulting.com Thu Apr 17 04:30:00 2003 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 16 Apr 2003 22:30:00 -0400 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3E9DC801.50802@globalite.com.br> (Nicodemus's message of "Wed, 16 Apr 2003 18:15:45 -0300") References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> Message-ID: Nicodemus writes: > David Abrahams wrote: > >>In the meantime, you can do this horrible thing: >> >> objects::class_value_wrapper< >> shared_ptr >> , objects::make_ptr_instance,A> > >> >(); >> Which will register a to_python converter for shared_ptr. >> > > Hmm, no problem. Thanks for the help! > > I will make Pyste generate this code instead of the usual "class_ boost::shared_ptr >", at least until the necessary changes in > Boost.Python are made. 8) One is not, in general, a substitute for the other. If you don't use shared_ptr in your class_ (where X may be the same as Y) then instances of X constructed from Python will not be held by shared_ptr. Whether or not that is important anymore is, of course, debatable, especially now that we have all the special shared_ptr treatment in Boost.Python. However, there is one significant difference: if you don't specify shared_ptr then you will not be able to pass a Python X object as a shared_ptr& argument. Among other things that means you will not be able to expose member functions of the shared_ptr as methods of the wrapped X (see Raoul Gough's recent postings about proxies). You will still be able to pass a Python X object as shared_ptr, shared_ptr, shared_ptr const&, or shared_ptr const&. Cheers, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From christophe.grimault at novagrid.com Thu Apr 17 09:18:29 2003 From: christophe.grimault at novagrid.com (christophe grimault) Date: Thu, 17 Apr 2003 09:18:29 +0200 Subject: [C++-sig] Blitz++ and boost.python and Pyste ... Message-ID: <3E9E5545.4070002@novagrid.com> Hi all, I have have been developping a signal processing library, for quite some time now, and it is based on blitz++ arrays and of course in C++. I would like to call the classes and function developped from python, using boost.python and why not, pyste. Is it possible or will I face some difficulties ? For example, how can get a blitz::Array,1> into my python interpreter ? Any idea on how and where to start woul be really appreciated... Thanks in advance ! C. Grimault From rwgk at yahoo.com Thu Apr 17 14:19:22 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 17 Apr 2003 05:19:22 -0700 (PDT) Subject: [C++-sig] Blitz++ and boost.python and Pyste ... In-Reply-To: <3E9E5545.4070002@novagrid.com> Message-ID: <20030417121922.16215.qmail@web20204.mail.yahoo.com> --- christophe grimault wrote: > For example, how can get a blitz::Array,1> into my python > interpreter ? I've done something similar for my own reference-counted array types. You can find some related notes in the Boost.Python FAQ and in the WIKI: http://www.boost.org/libs/python/doc/v2/faq.html#question2 http://www.python.org/cgi-bin/moinmoin/boost_2epython_2fStlContainers I've done the wrappers manually before pyste was born. I think as a start I'd still do a little bit of the work by hand just to learn about the issues. I have no experience with pyste, but I can imagine that it could help reducing the amount of time you need for the job. Please don't hesitate to post more specific questions. Ralf __________________________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo http://search.yahoo.com From paustin at eos.ubc.ca Thu Apr 17 18:16:43 2003 From: paustin at eos.ubc.ca (Philip Austin) Date: Thu, 17 Apr 2003 09:16:43 -0700 Subject: [C++-sig] Blitz++ and boost.python and Pyste ... In-Reply-To: <3E9E5545.4070002@novagrid.com> References: <3E9E5545.4070002@novagrid.com> Message-ID: <16030.54123.651467.274039@gull.eos.ubc.ca> > For example, how can get a blitz::Array,1> into my python > interpreter ? Any idea > on how and where to start woul be really appreciated... > Here's one way to do something similar for a contiguous n-dimensional array of doubles: numeric::array makeNum(double * data, std::vector dims){ int total = 1; std::vector::iterator iter = dims.begin(); while(iter != dims.end()){ total *= *iter; ++iter; } object obj(handle<>(PyArray_FromDims(dims.size(),&dims[0], PyArray_DOUBLE))); char *arr_data = ((PyArrayObject*) obj.ptr())->data; memcpy(arr_data, data, sizeof(double) * total); return extract(obj); } The data pointer would be pointing to the beginning of the Blitz array. boost::python::numeric::array is a registered type that wraps a Numeric Python array. We have some example code and a set of utility functions that demonstrate this approach, and will put them up in the next day or so -- regards, Phil From john at holj.de Fri Apr 18 11:12:54 2003 From: john at holj.de (John Holland) Date: Fri, 18 Apr 2003 11:12:54 +0200 Subject: [C++-sig] unresolved symbols Message-ID: <200304181112.54328.john@holj.de> hi there, i'm new to boost and extending python. i'm trying to write a boost-python module. it currently contains three files: module header, module boost definition and a class definition. this module is currently being built outside the boost build directory structure. i've copied the files Jamfile, Jamrule and boost-build.jam from the examples directory and altered them to reflect my build directory structure. the entire module has been held as basic as possible. the module implementation file is as follows: ################################################################## ################################################################## ################################################################## // boost.cpp #include #include #include namespace py = boost::python; using namespace logger; using namespace py; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(log_overloads, Client::log, 1, 2) BOOST_PYTHON_MODULE(logger) { class_("Client", init()) .def("__call__", &Client::log, log_overloads()) .add_property("source", &Client::getSource) .add_property("level", &Client::getLevel, &Client::setLevel) ; enum_("level") .value("debug", debug) .value("test", test) .value("review", review) .value("warning", warning) .value("error", error)#ifndef __logger_hpp__ .value("critical", critical) .value("fatal", fatal) ; } ################################################################## ################################################################## ################################################################## the module header and class implementation are equally simple: ################################################################## ################################################################## ################################################################## // logger.hpp #ifndef __logger_hpp__ #define __logger_hpp__ #include namespace logger { // defines all basic log levels known to this module enum LogLevel { all = 1 << 31, debug = 1 << 31, test = 1 << 21, review = 1 << 16, info = 1 << 11, warning = 1 << 4, error = 1 << 3, critical = 1 << 2, fatal = 1 << 1, off = 1 << 0, none = -1 }; // enum LogLevel /****************************************************************************** * * * */ class Client { public: Client (std::string& name); ~Client (void); std::string getSource (void) { return source; } LogLevel setLevel (const LogLevel level); LogLevel getLevel (void) { return this->level; } int log (const std::string& message, const LogLevel locallevel = none); protected: private: std::string source; LogLevel level; }; // class Client }; // namespace logger #endif // __logger_hpp__ ################################################################## ################################################################## ################################################################## // Client.cpp #include #include #include using namespace logger; Client::Client (std::string& name) { this->source = name; this->level = none; } LogLevel Client::setLevel (const LogLevel newlevel) { if (none == newlevel) { return none; } return this->level = newlevel; } int Client::log (const std::string& message, const LogLevel level) { LogLevel localLevel = (none == level) ? level : this->level; std::cout << ":" << localLevel << ":" << message; return 1; } ################################################################## ################################################################## ################################################################## using bjam the module complies w/o warnings or errors. however, while importing the newly generated python module the interpreter spits out an unresolved symbols error message: Python 2.2.1 (#1, Sep 10 2002, 17:49:17) [GCC 3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import logger Traceback (most recent call last): File "", line 1, in ? ImportError: /home/jh/Projects/boost/src/logger/bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so: undefined symbol: _ZN6logger6ClientD1Ev >>> the bjam verbose output is: gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "logger.cpp" gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" "LogClient.cpp" gcc-Link-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so LD_LIBRARY_PATH=:/usr/lib/python2.2/config export LD_LIBRARY_PATH g++ -s -fPIC -shared -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so" -L"" -L"/usr/lib/python2.2/config" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" -lboost_python -Wl,-rpath-link,. and the g++ version is: #g++ --version g++ (GCC) 3.2 Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. could someone be so kind as to help me resolve this problem? thanx in advance, John Holland john at holj.de From john at holj.de Fri Apr 18 11:19:09 2003 From: john at holj.de (John Holland) Date: Fri, 18 Apr 2003 11:19:09 +0200 Subject: [C++-sig] unresolved symbols Message-ID: <200304181119.09915.john@holj.de> hi there, i'm new to boost and extending python. i'm trying to write a boost-python module. it currently contains three files: module header, module boost definition and a class definition. this module is currently being built outside the boost build directory structure. i've copied the files Jamfile, Jamrule and boost-build.jam from the examples directory and altered them to reflect my build directory structure. the entire module has been held as basic as possible. the module implementation file is as follows: ################################################################## ################################################################## ################################################################## // boost.cpp #include #include #include namespace py = boost::python; using namespace logger; using namespace py; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(log_overloads, Client::log, 1, 2) BOOST_PYTHON_MODULE(logger) { class_("Client", init()) .def("__call__", &Client::log, log_overloads()) .add_property("source", &Client::getSource) .add_property("level", &Client::getLevel, &Client::setLevel) ; enum_("level") .value("debug", debug) .value("test", test) .value("review", review) .value("warning", warning) .value("error", error)#ifndef __logger_hpp__ .value("critical", critical) .value("fatal", fatal) ; } ################################################################## ################################################################## ################################################################## the module header and class implementation are equally simple: ################################################################## ################################################################## ################################################################## // logger.hpp #ifndef __logger_hpp__ #define __logger_hpp__ #include namespace logger { // defines all basic log levels known to this module enum LogLevel { all = 1 << 31, debug = 1 << 31, test = 1 << 21, review = 1 << 16, info = 1 << 11, warning = 1 << 4, error = 1 << 3, critical = 1 << 2, fatal = 1 << 1, off = 1 << 0, none = -1 }; // enum LogLevel /****************************************************************************** * * * */ class Client { public: Client (std::string& name); ~Client (void); std::string getSource (void) { return source; } LogLevel setLevel (const LogLevel level); LogLevel getLevel (void) { return this->level; } int log (const std::string& message, const LogLevel locallevel = none); protected: private: std::string source; LogLevel level; }; // class Client }; // namespace logger #endif // __logger_hpp__ ################################################################## ################################################################## ################################################################## // Client.cpp #include #include #include using namespace logger; Client::Client (std::string& name) { this->source = name; this->level = none; } LogLevel Client::setLevel (const LogLevel newlevel) { if (none == newlevel) { return none; } return this->level = newlevel; } int Client::log (const std::string& message, const LogLevel level) { LogLevel localLevel = (none == level) ? level : this->level; std::cout << ":" << localLevel << ":" << message; return 1; } ################################################################## ################################################################## ################################################################## using bjam the module complies w/o warnings or errors. however, while importing the newly generated python module the interpreter spits out an unresolved symbols error message: Python 2.2.1 (#1, Sep 10 2002, 17:49:17) [GCC 3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import logger Traceback (most recent call last): File "", line 1, in ? ImportError: /home/jh/Projects/boost/src/logger/bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so: undefined symbol: _ZN6logger6ClientD1Ev >>> the bjam verbose output is: gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "logger.cpp" gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" "LogClient.cpp" gcc-Link-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so LD_LIBRARY_PATH=:/usr/lib/python2.2/config export LD_LIBRARY_PATH g++ -s -fPIC -shared -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so" -L"" -L"/usr/lib/python2.2/config" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" -lboost_python -Wl,-rpath-link,. and the g++ version is: #g++ --version g++ (GCC) 3.2 Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. could someone be so kind as to help me resolve this problem? thanx in advance, John Holland john at holj.de From john at holj.de Fri Apr 18 11:09:07 2003 From: john at holj.de (John Holland) Date: Fri, 18 Apr 2003 11:09:07 +0200 Subject: [C++-sig] unresolved symbols Message-ID: <200304181109.07408.john@holj.de> hi there, i'm new to boost and extending python. i'm trying to write a boost-python module. it currently contains three files: module header, module boost definition and a class definition. this module is currently being built outside the boost build directory structure. i've copied the files Jamfile, Jamrule and boost-build.jam from the examples directory and altered them to reflect my build directory structure. the entire module has been held as basic as possible. the module implementation file is as follows: ################################################################## ################################################################## ################################################################## // boost.cpp #include #include #include namespace py = boost::python; using namespace logger; using namespace py; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(log_overloads, Client::log, 1, 2) BOOST_PYTHON_MODULE(logger) { class_("Client", init()) .def("__call__", &Client::log, log_overloads()) .add_property("source", &Client::getSource) .add_property("level", &Client::getLevel, &Client::setLevel) ; enum_("level") .value("debug", debug) .value("test", test) .value("review", review) .value("warning", warning) .value("error", error)#ifndef __logger_hpp__ .value("critical", critical) .value("fatal", fatal) ; } ################################################################## ################################################################## ################################################################## the module header and class implementation are equally simple: ################################################################## ################################################################## ################################################################## // logger.hpp #ifndef __logger_hpp__ #define __logger_hpp__ #include namespace logger { // defines all basic log levels known to this module enum LogLevel { all = 1 << 31, debug = 1 << 31, test = 1 << 21, review = 1 << 16, info = 1 << 11, warning = 1 << 4, error = 1 << 3, critical = 1 << 2, fatal = 1 << 1, off = 1 << 0, none = -1 }; // enum LogLevel /****************************************************************************** * * * */ class Client { public: Client (std::string& name); ~Client (void); std::string getSource (void) { return source; } LogLevel setLevel (const LogLevel level); LogLevel getLevel (void) { return this->level; } int log (const std::string& message, const LogLevel locallevel = none); protected: private: std::string source; LogLevel level; }; // class Client }; // namespace logger #endif // __logger_hpp__ ################################################################## ################################################################## ################################################################## // Client.cpp #include #include #include using namespace logger; Client::Client (std::string& name) { this->source = name; this->level = none; } LogLevel Client::setLevel (const LogLevel newlevel) { if (none == newlevel) { return none; } return this->level = newlevel; } int Client::log (const std::string& message, const LogLevel level) { LogLevel localLevel = (none == level) ? level : this->level; std::cout << ":" << localLevel << ":" << message; return 1; } ################################################################## ################################################################## ################################################################## using bjam the module complies w/o warnings or errors. however, while importing the newly generated python module the interpreter spits out an unresolved symbols error message: Python 2.2.1 (#1, Sep 10 2002, 17:49:17) [GCC 3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import logger Traceback (most recent call last): File "", line 1, in ? ImportError: /home/jh/Projects/boost/src/logger/bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so: undefined symbol: _ZN6logger6ClientD1Ev >>> the bjam verbose output is: gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "logger.cpp" gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" "LogClient.cpp" gcc-Link-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so LD_LIBRARY_PATH=:/usr/lib/python2.2/config export LD_LIBRARY_PATH g++ -s -fPIC -shared -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so" -L"" -L"/usr/lib/python2.2/config" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" -lboost_python -Wl,-rpath-link,. and the g++ version is: #g++ --version g++ (GCC) 3.2 Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. could someone be so kind as to help me resolve this problem? thanx in advance, John Holland john at holj.de From john at holj.de Fri Apr 18 11:45:47 2003 From: john at holj.de (John Holland) Date: Fri, 18 Apr 2003 11:45:47 +0200 Subject: [C++-sig] unresolved symbols Message-ID: <200304181145.47900.john@holj.de> hi there, i'm new to boost and extending python. i'm trying to write a boost-python module. it currently contains three files: module header, module boost definition and a class definition. this module is currently being built outside the boost build directory structure. i've copied the files Jamfile, Jamrule and boost-build.jam from the examples directory and altered them to reflect my build directory structure. the entire module has been held as basic as possible. the module implementation file is as follows: ################################################################## ################################################################## ################################################################## // boost.cpp #include #include #include namespace py = boost::python; using namespace logger; using namespace py; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(log_overloads, Client::log, 1, 2) BOOST_PYTHON_MODULE(logger) { class_("Client", init()) .def("__call__", &Client::log, log_overloads()) .add_property("source", &Client::getSource) .add_property("level", &Client::getLevel, &Client::setLevel) ; enum_("level") .value("debug", debug) .value("test", test) .value("review", review) .value("warning", warning) .value("error", error)#ifndef __logger_hpp__ .value("critical", critical) .value("fatal", fatal) ; } ################################################################## ################################################################## ################################################################## the module header and class implementation are equally simple: ################################################################## ################################################################## ################################################################## // logger.hpp #ifndef __logger_hpp__ #define __logger_hpp__ #include namespace logger { // defines all basic log levels known to this module enum LogLevel { all = 1 << 31, debug = 1 << 31, test = 1 << 21, review = 1 << 16, info = 1 << 11, warning = 1 << 4, error = 1 << 3, critical = 1 << 2, fatal = 1 << 1, off = 1 << 0, none = -1 }; // enum LogLevel /****************************************************************************** * * * */ class Client { public: Client (std::string& name); ~Client (void); std::string getSource (void) { return source; } LogLevel setLevel (const LogLevel level); LogLevel getLevel (void) { return this->level; } int log (const std::string& message, const LogLevel locallevel = none); protected: private: std::string source; LogLevel level; }; // class Client }; // namespace logger #endif // __logger_hpp__ ################################################################## ################################################################## ################################################################## // Client.cpp #include #include #include using namespace logger; Client::Client (std::string& name) { this->source = name; this->level = none; } LogLevel Client::setLevel (const LogLevel newlevel) { if (none == newlevel) { return none; } return this->level = newlevel; } int Client::log (const std::string& message, const LogLevel level) { LogLevel localLevel = (none == level) ? level : this->level; std::cout << ":" << localLevel << ":" << message; return 1; } ################################################################## ################################################################## ################################################################## using bjam the module complies w/o warnings or errors. however, while importing the newly generated python module the interpreter spits out an unresolved symbols error message: Python 2.2.1 (#1, Sep 10 2002, 17:49:17) [GCC 3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import logger Traceback (most recent call last): File "", line 1, in ? ImportError: /home/jh/Projects/boost/src/logger/bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so: undefined symbol: _ZN6logger6ClientD1Ev >>> the bjam verbose output is: gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "logger.cpp" gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" "LogClient.cpp" gcc-Link-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so LD_LIBRARY_PATH=:/usr/lib/python2.2/config export LD_LIBRARY_PATH g++ -s -fPIC -shared -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so" -L"" -L"/usr/lib/python2.2/config" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClient.o" -lboost_python -Wl,-rpath-link,. and the g++ version is: #g++ --version g++ (GCC) 3.2 Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. could someone be so kind as to help me resolve this problem? thanx in advance, John Holland john at holj.de From john.holland at bancotec.de Fri Apr 18 11:39:23 2003 From: john.holland at bancotec.de (Holland, John) Date: Fri, 18 Apr 2003 11:39:23 +0200 Subject: [C++-sig] unresolved symbols Message-ID: hi there, i'm new to boost and extending python. i'm trying to write a boost-python module. it currently contains three files: module header, module boost definition and a class definition. this module is currently being built outside the boost build directory structure. i've copied the files Jamfile, Jamrule and boost-build.jam from the examples directory and altered them to reflect my build directory structure. the entire module has been held as basic as possible. the module implementation file is as follows: ################################################################## ################################################################## ################################################################## // boost.cpp #include #include #include namespace py = boost::python; using namespace logger; using namespace py; BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(log_overloads, Client::log, 1, 2) BOOST_PYTHON_MODULE(logger) { class_("Client", init()) .def("__call__", &Client::log, log_overloads()) .add_property("source", &Client::getSource) .add_property("level", &Client::getLevel, &Client::setLevel) ; enum_("level") .value("debug", debug) .value("test", test) .value("review", review) .value("warning", warning) .value("error", error)#ifndef __logger_hpp__ .value("critical", critical) .value("fatal", fatal) ; } ################################################################## ################################################################## ################################################################## the module header and class implementation are equally simple: ################################################################## ################################################################## ################################################################## // logger.hpp #ifndef __logger_hpp__ #define __logger_hpp__ #include namespace logger { // defines all basic log levels known to this module enum LogLevel { all = 1 << 31, debug = 1 << 31, test = 1 << 21, review = 1 << 16, info = 1 << 11, warning = 1 << 4, error = 1 << 3, critical = 1 << 2, fatal = 1 << 1, off = 1 << 0, none = -1 }; // enum LogLevel /*************************************************************************** *** * * * */ class Client { public: Client (std::string& name); ~Client (void); std::string getSource (void) { return source; } LogLevel setLevel (const LogLevel level); LogLevel getLevel (void) { return this->level; } int log (const std::string& message, const LogLevel locallevel = none); protected: private: std::string source; LogLevel level; }; // class Client }; // namespace logger #endif // __logger_hpp__ ################################################################## ################################################################## ################################################################## // Client.cpp #include #include #include using namespace logger; Client::Client (std::string& name) { this->source = name; this->level = none; } LogLevel Client::setLevel (const LogLevel newlevel) { if (none == newlevel) { return none; } return this->level = newlevel; } int Client::log (const std::string& message, const LogLevel level) { LogLevel localLevel = (none == level) ? level : this->level; std::cout << ":" << localLevel << ":" << message; return 1; } ################################################################## ################################################################## ################################################################## using bjam the module complies w/o warnings or errors. however, while importing the newly generated python module the interpreter spits out an unresolved symbols error message: Python 2.2.1 (#1, Sep 10 2002, 17:49:17) [GCC 3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import logger Traceback (most recent call last): File "", line 1, in ? ImportError: /home/jh/Projects/boost/src/logger/bin/logger.so/gcc/release/runtime-link-dy namic/shared-linkable-true/logger.so: undefined symbol: _ZN6logger6ClientD1Ev >>> the bjam verbose output is: gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger. o" "logger.cpp" gcc-C++-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClien t.o g++ -c -Wall -ftemplate-depth-100 -DNDEBUG -DBOOST_PYTHON_DYNAMIC_LIB -O3 -finline-functions -Wno-inline -fPIC -I"." -I "/usr/include/python2.2" -I "/usr/local" -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClie nt.o" "LogClient.cpp" gcc-Link-action bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.s o LD_LIBRARY_PATH=:/usr/lib/python2.2/config export LD_LIBRARY_PATH g++ -s -fPIC -shared -o "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger. so" -L"" -L"/usr/lib/python2.2/config" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger. o" "bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/LogClie nt.o" -lboost_python -Wl,-rpath-link,. and the g++ version is: #g++ --version g++ (GCC) 3.2 Copyright (C) 2002 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. could someone be so kind as to help me resolve this problem? thanx in advance, John Holland Consultant BANCOTEC Ein Unternehmen der Cellent AG. Calwer Strasse 33, 70173 Stuttgart Tel: ++49 711 222 992 900 Fax: ++49 711 222 992 999 Mobile: ++49 172 7886719 mailto:john.holland at bancotec.de mailto:john at holj.de http:\\www.bancotec.de http:\\www.cellent.de From john at holj.de Fri Apr 18 11:49:47 2003 From: john at holj.de (John Holland) Date: Fri, 18 Apr 2003 11:49:47 +0200 Subject: [C++-sig] sorry about the redundant mails Message-ID: <200304181149.47478.john@holj.de> hello, my mail wasn't working properly. -- John Holland john at holj.de From dave at boost-consulting.com Fri Apr 18 12:49:55 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 18 Apr 2003 06:49:55 -0400 Subject: [C++-sig] unresolved symbols In-Reply-To: <200304181109.07408.john@holj.de> (John Holland's message of "Fri, 18 Apr 2003 11:09:07 +0200") References: <200304181109.07408.john@holj.de> Message-ID: John Holland writes: > Type "help", "copyright", "credits" or "license" for more information. >>>> import logger > Traceback (most recent call last): > File "", line 1, in ? > ImportError: > /home/jh/Projects/boost/src/logger/bin/logger.so/gcc/release/runtime-link-dynamic/shared-linkable-true/logger.so: > undefined symbol: _ZN6logger6ClientD1Ev >>>> Here's your answer: $ echo '_ZN6logger6ClientD1Ev' | c++filt logger::Client::~Client [in-charge]() ^^^^^^^^^^^^^^^^^^^^^^^ You're missing a destructor. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Fri Apr 18 16:04:15 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 18 Apr 2003 10:04:15 -0400 Subject: [C++-sig] Re: [boost] luabind In-Reply-To: <000b01c305af$3c7fa5c0$1d00a8c0@pdimov2> (Peter Dimov's message of "Fri, 18 Apr 2003 16:34:27 +0300") References: <000b01c305af$3c7fa5c0$1d00a8c0@pdimov2> Message-ID: "Peter Dimov" writes: > Just FYI, I recently stumbled across http://luabind.sf.net - a library that > seems to be a boost.python "port" for the Lua language (www.lua.org). It also seems to draw some inspiration from Joel's work on Phoenix syntax: class_(L, "A") .enum_("constants") [ value("my_enum", 4), value("my_2nd_enum", 7), value("another_enum", 6) ]; > It might be an interesting project to isolate the language-independent parts > into a core library. :-) Mos' def! It seems as though there must be a great deal of common work here. It also seems as though pyste could easily(?) be adapted to generate bindings for various languages. I'd really like to see all this work brought together in Boost so the common elements could be factored out and re-used (say, for Perl!). -- Dave Abrahams Boost Consulting www.boost-consulting.com From code_cold at sina.com.cn Fri Apr 18 16:05:24 2003 From: code_cold at sina.com.cn (code_cold) Date: Fri, 18 Apr 2003 22:05:24 +0800 Subject: [C++-sig] How to embed python to c++ Message-ID: As I wish, I wanna visual c++6.0 and python to work together, and python should be embeded in the c++, so, How python get the c++ class object ?? As example: In c++: class cObj { ... }; then, how python use this object ?? Thanks for reading ^^ From patrick at vrac.iastate.edu Fri Apr 18 19:08:26 2003 From: patrick at vrac.iastate.edu (Patrick Hartling) Date: Fri, 18 Apr 2003 12:08:26 -0500 Subject: [C++-sig] Threads and Boost.Python Message-ID: <3EA0310A.4070604@vrac.iastate.edu> I was able to sort out the multi-threading issues I was having earlier this week with Boost.Python thanks to David Abrahams' suggestions. What I came up with is a relatively simple guard object that is instantiated whenever C++ code calls into the Python interpreter. To make this guard work, I had to deal with two key issues: 1. Ensuring that threads created by C/C++ bootstrapped themselves with the Python interpreter. 2. Preventing deadlocks if the same thread tried to acquire the GIL more than once. Issue #1 was straightforward enough to handle. The C++ code base that I am exposing to Python includes a cross-platform data structure for thread-specific data (TSD). Within the guard, there is a static data member that is an instance of this TSD structure. Our TSD handler is a templated type, and the struct I gave it contained two fields: struct State { State() : isLocked(false), pyState(NULL) {} bool isLocked; PyThreadState* pyState; }; The boolean field is used to deal with Issue #2 from above; the thread state object needs to be different for each unique thread calling into the Python interpreter. The nice thing about our TSD handler is that a new instance of the above structure will be instantiated automatically for each thread, so whenever a new thread creates an instance of the guard, the guard constructor handles filling in the State instance fields. The code from my guard constructor is this: Guard::Guard() : mMyLock(false) { if ( NULL == mState->pyState ) { mState->pyState = PyThreadState_New(PyInterpreterState_New()); } if ( ! mState->isLocked ) { // Acquire the GIL. PyEval_AcquireThread(mState->pyState); mState->isLocked = true; mMyLock = true; } } Here, Guard::mState is the static data member that is an instance of our TSD handler. The destructor is this: Guard::~Guard() { if ( mMyLock && mState->isLocked ) { // Release the GIL. PyEval_ReleaseThread(mState->pyState); mState->isLocked = false; } } The last detail is the data member Guard::mMyLock. That is a boolean to handle keep track of which guard instance actually acquired the GIL so that it is the one to release it upon destruction. Dealing with the recursive lock problem was probably the trickiest part. It's too bad that the GIL cannot be locked twice by the same thread, but perhaps that behavior doesn't exist for all the threading implementations upon which the Python interpreter runs. On the whole, this guard concept is working very well for me, though I haven't even been using it for 48 hours yet. Conceptually, I think something like a "synchronized call" (to steal a Java concept) in Boost.Python would help automate this process. At this time, however, I don't know how well my guard will apply to arbitrary calls into the Python interpreter from a thread. It works like a charm for boost::python::call_method<>(), and that's what I care about the most right now. Two side issues I ran into involved deciding when to call PyEval_InitThreads() and where to put the two macros for allowing and disallowing threads. With the way our software works, the main thread basically doesn't do anything once it starts a microkernel's control thread. The primordial thread just sits and blocks on a semaphore waiting for the microkernel to shut down. From there on, all calls into the Python interpreter from C++ are guaranteed to come from a thread other than the one that started the interpreter. So, I put Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in a wrapper function that is exposed to Python where the Python "main" function makes the sempahore wait call. There will be other cases I'll have to hunt down as we expand our use of Boost.Python, but at least I have the general idea of what to watch out for. -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 cplusplus-sig at brewer.com Sat Apr 19 02:37:04 2003 From: cplusplus-sig at brewer.com (c++-sig) Date: Fri, 18 Apr 2003 17:37:04 -0700 Subject: [C++-sig] function with void * parameter on MSVC 7, Boost.Python Message-ID: <3C609AD34AAF22488364057AA72EAC14019EE2F4@adsl-64-170-107-114.dsl.snfc21.pacbell.net> I am trying to wrap a C++ api that makes use of void *'s internally but my problem boils down to a very simple example where I get a compiler error. The error occurs in a section of Boost.Python code where msvc RTTI type info names are undecorated (this code is only compiled into MSVC compiler builds). My question can be reduced to what happens if I remove this undecoration (which makes my compile work). Ok, now the details: #include #include using namespace boost::python; void dog(void *x); BOOST_PYTHON_MODULE(test) { def("dog",dog); } When I compile using Visual Studio .NET (I am assuming the same problem exists on VC++ 6), I get the following error: c:\projects\XPython\boost\boost\python\detail\msvc_typeinfo.hpp(45) : error C2784: 'boost::python::detail::typeinfo boost::python::detail::typeid_ref_1(T &(__stdcall *)(void))' : could not deduce template argument for ' &(__stdcall *)(void)' from 'void (__stdcall *)(void)' It appears as though the msvc_typeinfo.hpp file exists for the following reason in a comment at the top of the file: // Fix for MSVC's broken typeid() implementation which doesn't strip // decoration. This fix doesn't handle cv-qualified array types. It // could probably be done, but I haven't figured it out yet. And the template on which it dies looks like this: template inline typeinfo msvc_typeid(boost::type* = 0) { return detail::typeid_ref( (boost::type*)0, detail::is_ref_tester1(type()) ); } If I replace the return statement with return typeid(T); things compile just fine (this is what happens on other compilers). But I'm wondering what the effects are of not undecorating the msvc type names? Would it mean that if Python were compiled with a non-microsoft compiler, automatic type conversion would not work? Thank you, Jeff Brewer From dave at boost-consulting.com Sat Apr 19 16:40:51 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sat, 19 Apr 2003 10:40:51 -0400 Subject: [C++-sig] function with void * parameter on MSVC 7, Boost.Python In-Reply-To: <3C609AD34AAF22488364057AA72EAC14019EE2F4@adsl-64-170-107-114.dsl.snfc21.pacbell.net> (c.'s message of "Fri, 18 Apr 2003 17:37:04 -0700") References: <3C609AD34AAF22488364057AA72EAC14019EE2F4@adsl-64-170-107-114.dsl.snfc21.pacbell.net> Message-ID: <84y926turw.fsf@boost-consulting.com> "c++-sig" writes: > I am trying to wrap a C++ api that makes use of void *'s internally but > my problem boils down to a very simple example where I get a compiler > error. The error occurs in a section of Boost.Python code where msvc > RTTI type info names are undecorated (this code is only compiled into > MSVC compiler builds). My question can be reduced to what happens if I > remove this undecoration (which makes my compile work). I don't think that has anything to do with the actual problem. Boost.Python simply doesn't convert void* to/from python, and wasn't designed to. I tried using Gottfried Gaunsage's opaque pointer converter stuff to treat void* as an opaque pointer, but it doesn't work out simply for various uninteresting reasons. > Ok, now the details: > > #include > #include > > using namespace boost::python; > > void dog(void *x); > > BOOST_PYTHON_MODULE(test) > { > def("dog",dog); > } > I suppose it would be good to modify Boost.Python to accomodate void*, but it will take some work and is not high on my list at the moment (that could be chaged - funded development gets the highest priority). In the meantime I suggest you use thin wrappers which cast the void* to/from some other opaque pointer type, as follows: #include #include using namespace boost::python; struct void_; void dog(void *x); inline void dog2(void_* x) { dog(x); } BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_); BOOST_PYTHON_MODULE(test) { def("dog",dog2); } > When I compile using Visual Studio .NET (I am assuming the same problem > exists on VC++ 6), I get the following error: > c:\projects\XPython\boost\boost\python\detail\msvc_typeinfo.hpp(45) : > error C2784: 'boost::python::detail::typeinfo > boost::python::detail::typeid_ref_1(T &(__stdcall *)(void))' : could not > deduce template argument for ' &(__stdcall *)(void)' from 'void > (__stdcall *)(void)' > > It appears as though the msvc_typeinfo.hpp file exists for the following > reason in a comment at the top of the file: > // Fix for MSVC's broken typeid() implementation which doesn't strip > // decoration. This fix doesn't handle cv-qualified array types. It > // could probably be done, but I haven't figured it out yet. > > And the template on which it dies looks like this: > template > inline typeinfo msvc_typeid(boost::type* = 0) > { > return detail::typeid_ref( > (boost::type*)0, detail::is_ref_tester1(type()) > ); > } > > If I replace the return statement with return typeid(T); things compile > just fine (this is what happens on other compilers). Yes, but you'll still have no way to convert a void* _to_ python, so you can't wrap any functions that return them. > But I'm wondering what the effects are of not undecorating the msvc > type names? Lots of bad effects, trust me. If you really think this workaround is good enough (I don't see how it could be, since you need to produce a Python object that can be converted to/from void*), you should do it with specialization: template <> inline typeinfo msvc_typeid(boost::type* = 0) { return typeid(void); } (actually, I suppose I should have that specialization anyway for completeness). > Would it mean that if Python were compiled with a > non-microsoft compiler, automatic type conversion would not work? No, nothing like that. Boost.Python simply relies in several places on the fact that: typeid(T) == typeid(T const) == typeid(T const volatile) == typeid(T&) == typeid(T const&) ... but vc6 and vc7 don't act that way, so msvc_typeinfo takes care of the problem for us. -- Dave Abrahams Boost Consulting www.boost-consulting.com From talsit at talsit.org Mon Apr 21 15:48:26 2003 From: talsit at talsit.org (tALSit de CoD) Date: Mon, 21 Apr 2003 23:48:26 +1000 Subject: [C++-sig] Trouble wrapping a function returning a pointer to a class. Message-ID: <5.2.0.9.2.20030421233737.00b0e0f8@talsit.org> Hey there! I'm very very very new to this boost.python, so i might probably be looking in all the wrong places. I have a class and a function: namespace kikura { class cKernel { ... }; cKernel * getKikuraKernel (); } // namespace kikura and I want to wrap it like so: namespace kikura { BOOST_PYTHON_MODULE (kikura) { class_ ("cKernel", init()); def ("getKikuraKernel", getKikuraKernel); } } // namespace kikura And it barfs at me with this error: d:\data\users\tALSit\code\c.c++\usr\boost\boost\python\detail\invoke.hpp(80) : error C2514: 'boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning' : class has no constructors I am using msvc 7, and boost 1.30.0. If i wrap only the class, it compiles fine, but if i try to wrap the function aswell, it gives the above error. If i try to export _only_ the function, it gives the same error. I don't know if this has anything to do with namespaces, which I imagine not, but just asking anyway. tALSit de CoD | talsit.org From dave at boost-consulting.com Mon Apr 21 16:07:06 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 10:07:06 -0400 Subject: [C++-sig] Trouble wrapping a function returning a pointer to a class. In-Reply-To: <5.2.0.9.2.20030421233737.00b0e0f8@talsit.org> (tALSit de CoD's message of "Mon, 21 Apr 2003 23:48:26 +1000") References: <5.2.0.9.2.20030421233737.00b0e0f8@talsit.org> Message-ID: <84y924kkqd.fsf@boost-consulting.com> tALSit de CoD writes: > I'm very very very new to this boost.python, so i might probably be > looking in all the wrong places. > > I have a class and a function: > > namespace kikura { > class cKernel { ... }; > cKernel * getKikuraKernel (); > } // namespace kikura > > and I want to wrap it like so: > > namespace kikura { > BOOST_PYTHON_MODULE (kikura) { > class_ ("cKernel", init()); > def ("getKikuraKernel", getKikuraKernel); > } > > } // namespace kikura > > And it barfs at me with this error: > d:\data\users\tALSit\code\c.c++\usr\boost\boost\python\detail\invoke.hpp(80) > : error C2514: > 'boost::python::detail::specify_a_return_value_policy_to_wrap_functions_returning' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > : class has no constructors Note that it probably also says: T = cKernel* See http://www.boost.org/libs/python/doc/tutorial/doc/call_policies.html for a description of call policies. Please also read the reference documentation at http://www.boost.org/libs/python/doc/v2/reference.html#models_of_call_policies and http://www.boost.org/libs/python/doc/v2/reference.html#result_converter_generators before attempting to use them; people often choose the wrong policy until they understand all of the options. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Mon Apr 21 16:41:12 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 21 Apr 2003 11:41:12 -0300 Subject: [C++-sig] shared_ptr converters In-Reply-To: References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> Message-ID: <3EA40308.8000604@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > >However, there is one significant difference: if you don't specify >shared_ptr then you will not be able to pass a Python X object as a >shared_ptr& argument. Among other things that means you will not >be able to expose member functions of the shared_ptr as methods of the >wrapped X (see Raoul Gough's recent postings about proxies). You will >still be able to pass a Python X object as shared_ptr, >shared_ptr, shared_ptr const&, or shared_ptr const&. > You mean that a function that receives a shared_ptr& wouldn't work? Because the following does: int Test(boost::shared_ptr& a) { return a->f(); } >>> from test import * >>> a = New() >>> Test(a) 1 Or am I misunderstood your response? If the only drawback is not being able to expose member functions of the shared_ptr as methods of the wrapped object, I think it is acceptable for Pyste to do the more common thing, since this is a rare use case anyway. 8) Regards, Nicodemus. From dave at boost-consulting.com Mon Apr 21 17:24:49 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 11:24:49 -0400 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3EA40308.8000604@globalite.com.br> (nicodemus@globalite.com.br's message of "Mon, 21 Apr 2003 11:41:12 -0300") References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> <3EA40308.8000604@globalite.com.br> Message-ID: <84d6jfrhz2.fsf@boost-consulting.com> Nicodemus writes: > David Abrahams wrote: > >>Nicodemus writes: >> However, there is one significant difference: if you don't specify >>shared_ptr then you will not be able to pass a Python X object as a >>shared_ptr& argument. Among other things that means you will not >>be able to expose member functions of the shared_ptr as methods of the >>wrapped X (see Raoul Gough's recent postings about proxies). You will >>still be able to pass a Python X object as shared_ptr, >>shared_ptr, shared_ptr const&, or shared_ptr const&. >> > > You mean that a function that receives a shared_ptr& wouldn't work? > Because the following does: > > int Test(boost::shared_ptr& a) > { > return a->f(); > } >>> from test import * > >>> a = New() > >>> Test(a) > 1 > > Or am I misunderstood your response? Yes, my response was badly-phrased. I should've said: if you don't specify shared_ptr, you won't be able to pass an X object _constructed from Python_ to a function expecting shared_ptr&: >>> a = A() >>> Test(a) Traceback... > If the only drawback is not being > able to expose member functions of the shared_ptr as methods of the > wrapped object And also not being able to detach the C++ object from the python object: int Detach(boost::shared_ptr& a) { a.reset(); } > I think it is acceptable for Pyste to do the more > common thing, since this is a rare use case anyway. 8) I agree. -- Dave Abrahams Boost Consulting www.boost-consulting.com From talsit at talsit.org Mon Apr 21 17:29:14 2003 From: talsit at talsit.org (tALSit de CoD) Date: Tue, 22 Apr 2003 01:29:14 +1000 Subject: [C++-sig] std::string ? Message-ID: <5.2.0.9.2.20030422012307.03fa36e0@talsit.org> Ok... thanks for that before, now i think i'm actually starting to understand how this big scary monster works, thanks! Now, i got another question. If i got this: class cKernel { const std::string & getName () const { return m_name; } } and I wrap it like so: namespace kikura { BOOST_PYTHON_MODULE (kikura) { class_ ("cKernel", no_init) .def ("getName", cKernel::getName, return_internal_reference <> ()); } When I go to use that method in python it gives me this error: >>> k.getName () Traceback (most recent call last): File "", line 1, in ? TypeError: No Python class registered for C++ class class std::basic_string,class std::allocator > But if i change the method call to not return a reference, and wrap it without a call policy, it works just fine. Am i missing something here, or do i have to do it another way? As in use copy_const_reference or similar? Thank you for all, Regards tALSit de CoD | talsit.org From dave at boost-consulting.com Mon Apr 21 18:07:11 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 12:07:11 -0400 Subject: [C++-sig] std::string ? In-Reply-To: <5.2.0.9.2.20030422012307.03fa36e0@talsit.org> (tALSit de CoD's message of "Tue, 22 Apr 2003 01:29:14 +1000") References: <5.2.0.9.2.20030422012307.03fa36e0@talsit.org> Message-ID: <847k9nrg0g.fsf@boost-consulting.com> tALSit de CoD writes: > Ok... thanks for that before, now i think i'm actually starting to > understand how this big scary monster works, thanks! > > Now, i got another question. If i got this: > > class cKernel { > const std::string & getName () const { return m_name; } > } > > and I wrap it like so: > > namespace kikura { > BOOST_PYTHON_MODULE (kikura) { > class_ ("cKernel", no_init) > .def ("getName", cKernel::getName, > return_internal_reference <> ()); > } > > When I go to use that method in python it gives me this error: > > >>> k.getName () > Traceback (most recent call last): > File "", line 1, in ? > TypeError: No Python class registered for C++ class class > std::basic_string,class > std::allocator > > > But if i change the method call to not return a reference, and wrap it > without a call policy, it works just fine. Am i missing something > here, or do i have to do it another way? As in use > > copy_const_reference or similar? ^^^^^^^^^^^^^^^^^^^^ Yes. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Mon Apr 21 20:46:08 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 21 Apr 2003 15:46:08 -0300 Subject: [C++-sig] shared_ptr converters In-Reply-To: <84d6jfrhz2.fsf@boost-consulting.com> References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> <3EA40308.8000604@globalite.com.br> <84d6jfrhz2.fsf@boost-consulting.com> Message-ID: <3EA43C70.8040506@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>David Abrahams wrote: >> >> >> >>>Nicodemus writes: >>> However, there is one significant difference: if you don't specify >>>shared_ptr then you will not be able to pass a Python X object as a >>>shared_ptr& argument. Among other things that means you will not >>>be able to expose member functions of the shared_ptr as methods of the >>>wrapped X (see Raoul Gough's recent postings about proxies). You will >>>still be able to pass a Python X object as shared_ptr, >>>shared_ptr, shared_ptr const&, or shared_ptr const&. >>> >>> >>> >>You mean that a function that receives a shared_ptr& wouldn't work? >>Because the following does: >> >>int Test(boost::shared_ptr& a) >>{ >> return a->f(); >>} >>> from test import * >> >>> a = New() >> >>> Test(a) >>1 >> >>Or am I misunderstood your response? >> >> > >Yes, my response was badly-phrased. I should've said: if you don't >specify shared_ptr, you won't be able to pass an X object >_constructed from Python_ to a function expecting shared_ptr&: > > >>> a = A() > >>> Test(a) > Traceback... > > I see... then that solution doesn't solve this more common case (at least more common than trying to use shared_ptr's with virtual wrappers, as in my original post). I believe that reverting Pyste back to specify the shared_ptr as holder for class_ is the better thing to do for now. What do you think Dave? Thanks for helping! Regards, Nicodemus. From dave at boost-consulting.com Mon Apr 21 21:18:04 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 15:18:04 -0400 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3EA43C70.8040506@globalite.com.br> (nicodemus@globalite.com.br's message of "Mon, 21 Apr 2003 15:46:08 -0300") References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> <3EA40308.8000604@globalite.com.br> <84d6jfrhz2.fsf@boost-consulting.com> <3EA43C70.8040506@globalite.com.br> Message-ID: <84adejpslv.fsf@boost-consulting.com> Nicodemus writes: > David Abrahams wrote: > >>Nicodemus writes: >> >> >>>David Abrahams wrote: >>> >>> >>>>Nicodemus writes: >>>> However, there is one significant difference: if you don't specify >>>>shared_ptr then you will not be able to pass a Python X object as a >>>>shared_ptr& argument. Among other things that means you will not >>>>be able to expose member functions of the shared_ptr as methods of the >>>>wrapped X (see Raoul Gough's recent postings about proxies). You will >>>>still be able to pass a Python X object as shared_ptr, >>>>shared_ptr, shared_ptr const&, or shared_ptr const&. >>>> >>>> >>>You mean that a function that receives a shared_ptr& wouldn't work? >>>Because the following does: >>> >>>int Test(boost::shared_ptr& a) >>>{ >>> return a->f(); >>>} >>> from test import * >>> >>> a = New() >>> >>> Test(a) >>>1 >>> >>> Or am I misunderstood your response? >> >>Yes, my response was badly-phrased. I should've said: if you don't >>specify shared_ptr, you won't be able to pass an X object >>_constructed from Python_ to a function expecting shared_ptr&: >> >> >>> a = A() >> >>> Test(a) >> Traceback... >> > > I see... then that solution doesn't solve this more common case (at > least more common than trying to use shared_ptr's with virtual wrappers, > as in my original post). Do you really think it's so common? int Test1(boost::shared_ptr a) { return a->f(); } int Test2(boost::shared_ptr const& a) { return a->f(); } >>> from test import * >>> Test1(A()) # OK >>> Test2(A()) # OK >>> Test(A()) # Oops Traceback ... It's pretty unusal, IMO, to pass shared_ptr by *non-const* reference. > I believe that reverting Pyste back to specify the shared_ptr as > holder for class_ is the better thing to do for now. What do you > think Dave? Thanks for helping! I'm not convinced. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Mon Apr 21 22:42:22 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 21 Apr 2003 17:42:22 -0300 Subject: [C++-sig] shared_ptr converters In-Reply-To: <84adejpslv.fsf@boost-consulting.com> References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> <3EA40308.8000604@globalite.com.br> <84d6jfrhz2.fsf@boost-consulting.com> <3EA43C70.8040506@globalite.com.br> <84adejpslv.fsf@boost-consulting.com> Message-ID: <3EA457AE.9050906@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>David Abrahams wrote: >> >> >> >>>Nicodemus writes: >>> >>> >>> >>> >>>>David Abrahams wrote: >>>> >>>> >>>> >>>> >>>>>Nicodemus writes: >>>>>However, there is one significant difference: if you don't specify >>>>>shared_ptr then you will not be able to pass a Python X object as a >>>>>shared_ptr& argument. Among other things that means you will not >>>>>be able to expose member functions of the shared_ptr as methods of the >>>>>wrapped X (see Raoul Gough's recent postings about proxies). You will >>>>>still be able to pass a Python X object as shared_ptr, >>>>>shared_ptr, shared_ptr const&, or shared_ptr const&. >>>>> >>>>> >>>>> >>>>> >>>>You mean that a function that receives a shared_ptr& wouldn't work? >>>>Because the following does: >>>> >>>>int Test(boost::shared_ptr& a) >>>>{ >>>> return a->f(); >>>>} >>> from test import * >>>> >>>> >>>>>>>a = New() >>>>>>>Test(a) >>>>>>> >>>>>>> >>>>1 >>>> >>>>Or am I misunderstood your response? >>>> >>>> >>>Yes, my response was badly-phrased. I should've said: if you don't >>>specify shared_ptr, you won't be able to pass an X object >>>_constructed from Python_ to a function expecting shared_ptr&: >>> >>> >>> a = A() >>> >>> Test(a) >>> Traceback... >>> >>> >>> >>I see... then that solution doesn't solve this more common case (at >>least more common than trying to use shared_ptr's with virtual wrappers, >>as in my original post). >> >> > >Do you really think it's so common? > > int Test1(boost::shared_ptr a) > { > return a->f(); > } > > int Test2(boost::shared_ptr const& a) > { > return a->f(); > } > > >>> from test import * > >>> Test1(A()) # OK > >>> Test2(A()) # OK > >>> Test(A()) # Oops > Traceback ... > >It's pretty unusal, IMO, to pass shared_ptr by *non-const* reference. > > Sorry, I meant being able to create the class on the Python side and pass it to functions that accept shared_ptr, but I didn't realize that you can do it, except if the function receives by non-const reference. That is certainly unusual, like you said. Sorry about the confusion. >>I believe that reverting Pyste back to specify the shared_ptr as >>holder for class_ is the better thing to do for now. What do you >>think Dave? Thanks for helping! >> >> > >I'm not convinced. > Sorry again for the confusion, you're right. To resume, pyste is generating the following code when the user requests shared_ptr support for a class X: // Temporary code for smart pointers objects::class_value_wrapper< boost::shared_ptr< X >, objects::make_ptr_instance< X, objects::pointer_holder< boost::shared_ptr< X >, X > > >(); Thanks again for the help David, Nicodemus. From dave at boost-consulting.com Mon Apr 21 23:10:06 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 17:10:06 -0400 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3EA457AE.9050906@globalite.com.br> (nicodemus@globalite.com.br's message of "Mon, 21 Apr 2003 17:42:22 -0300") References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> <3EA40308.8000604@globalite.com.br> <84d6jfrhz2.fsf@boost-consulting.com> <3EA43C70.8040506@globalite.com.br> <84adejpslv.fsf@boost-consulting.com> <3EA457AE.9050906@globalite.com.br> Message-ID: <84ptnfo8up.fsf@boost-consulting.com> Nicodemus writes: > To resume, pyste is generating the following code when the user requests > shared_ptr support for a class X: > > // Temporary code for smart pointers > objects::class_value_wrapper< > boost::shared_ptr< X >, objects::make_ptr_instance< > X, objects::pointer_holder< > boost::shared_ptr< X >, X > > > > >(); Perhaps you'd like to contribute a nice wrapper function for this to the Boost.Python codebase, e.g.: template void register_ptr_to_python(P* = 0) { typedef pointee

::type X; objects::class_value_wrapper< P , objects::make_ptr_instance< X , objects::pointer_holder > >(); } ?? -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Apr 22 00:13:20 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 21 Apr 2003 19:13:20 -0300 Subject: [C++-sig] shared_ptr converters In-Reply-To: <84ptnfo8up.fsf@boost-consulting.com> References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> <3EA40308.8000604@globalite.com.br> <84d6jfrhz2.fsf@boost-consulting.com> <3EA43C70.8040506@globalite.com.br> <84adejpslv.fsf@boost-consulting.com> <3EA457AE.9050906@globalite.com.br> <84ptnfo8up.fsf@boost-consulting.com> Message-ID: <3EA46D00.3040507@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > > >>To resume, pyste is generating the following code when the user requests >>shared_ptr support for a class X: >> >> // Temporary code for smart pointers >> objects::class_value_wrapper< >> boost::shared_ptr< X >, objects::make_ptr_instance< >> X, objects::pointer_holder< >> boost::shared_ptr< X >, X > >> > >> >(); >> >> > >Perhaps you'd like to contribute a nice wrapper function for this to >the Boost.Python codebase, e.g.: > > template > void register_ptr_to_python(P* = 0) > { > typedef pointee

::type X; > objects::class_value_wrapper< > P > , objects::make_ptr_instance< > X > , objects::pointer_holder > > > >(); > } > >?? > Well, you already did all the work! ;) Attached are the needed changes to the current CVS: register_ptr_to_python.hpp should go to boost/python/converter, and a diff for boost/python.hpp. I tested in my example like so: class_< A, boost::noncopyable, A_Wrapper >("A"); register_ptr_to_python< boost::shared_ptr >(); and it seems to work fine. Thanks again for the help Dave! -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: python.hpp.diff URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: register_ptr_to_python.hpp URL: From dave at boost-consulting.com Tue Apr 22 00:22:08 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 18:22:08 -0400 Subject: [C++-sig] shared_ptr converters In-Reply-To: <3EA46D00.3040507@globalite.com.br> (nicodemus@globalite.com.br's message of "Mon, 21 Apr 2003 19:13:20 -0300") References: <3E9B49C0.8030404@globalite.com.br> <3E9DC801.50802@globalite.com.br> <3EA40308.8000604@globalite.com.br> <84d6jfrhz2.fsf@boost-consulting.com> <3EA43C70.8040506@globalite.com.br> <84adejpslv.fsf@boost-consulting.com> <3EA457AE.9050906@globalite.com.br> <84ptnfo8up.fsf@boost-consulting.com> <3EA46D00.3040507@globalite.com.br> Message-ID: <844r4ro5in.fsf@boost-consulting.com> Nicodemus writes: > David Abrahams wrote: > >>Nicodemus writes: >> >> >>>To resume, pyste is generating the following code when the user requests >>>shared_ptr support for a class X: >>> >>> // Temporary code for smart pointers >>> objects::class_value_wrapper< >>> boost::shared_ptr< X >, objects::make_ptr_instance< >>> X, objects::pointer_holder< >>> boost::shared_ptr< X >, X > >>> > >>> >(); >>> >> >>Perhaps you'd like to contribute a nice wrapper function for this to >>the Boost.Python codebase, e.g.: >> >> template >> void register_ptr_to_python(P* = 0) >> { >> typedef pointee

::type X; >> objects::class_value_wrapper< >> P >> , objects::make_ptr_instance< >> X >> , objects::pointer_holder >> > >> >(); >> } >> >>?? >> > > Well, you already did all the work! ;) Haha, gotcha! Still needs documentation and tests... I just did the easy part. > Attached are the needed changes to the current CVS: > register_ptr_to_python.hpp should go to boost/python/converter, and a > diff for boost/python.hpp. I tested in my example like so: > > class_< A, boost::noncopyable, A_Wrapper >("A"); > register_ptr_to_python< boost::shared_ptr >(); > > and it seems to work fine. > Thanks for testing. When you post a doc patch, I'll commit the whole wad ;-) -- Dave Abrahams Boost Consulting www.boost-consulting.com From dominique.devriese at student.kuleuven.ac.be Tue Apr 22 01:07:26 2003 From: dominique.devriese at student.kuleuven.ac.be (Dominique Devriese) Date: 22 Apr 2003 01:07:26 +0200 Subject: [C++-sig] exclude an entire class with pyste ? Message-ID: <87adejlaa9.fsf@student.kuleuven.ac.be> Hi, I'm working on playing around with embedding python in my application using Boost.Python for exposing the API. This is going really great, I hadn't imagined it being so easy. Boost.python is certainly somewhere at the top in my list of great libraries ( together with most of the rest of Boost, actually :) ). Anyway, I'd like to use pyste for generating some of the relevant code. I have a header containing a lot of free functions like Point calcCircleCenter( const Point& a, const Point& b,const Point& c ); and it would be really convenient to use pyste here, cause there are a *lot* of these functions. However, there is the problem that in front of the header, I have class declarations like class SomeClass; and when pyste sees this, it outputs code like class_< SomeClass, boost::noncopyable >("SomeClass", no_init) ; which is not what I want, since SomeClass is in another header, and also being exported to python. So my question basically is, is there a way to exclude an entire class from the pyste output, since ch = AllFromHeader( "some_header.h" ); exclude( ch.SomeClass ); doesn't seem to do the trick.. thanks domi -- A tall, dark stranger will have more fun than you. From nicodemus at globalite.com.br Tue Apr 22 01:23:17 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 21 Apr 2003 20:23:17 -0300 Subject: [C++-sig] exclude an entire class with pyste ? In-Reply-To: <87adejlaa9.fsf@student.kuleuven.ac.be> References: <87adejlaa9.fsf@student.kuleuven.ac.be> Message-ID: <3EA47D65.4030804@globalite.com.br> Dominique Devriese wrote: >Hi, >I'm working on playing around with embedding python in my application >using Boost.Python for exposing the API. This is going really great, >I hadn't imagined it being so easy. Boost.python is certainly >somewhere at the top in my list of great libraries ( together with >most of the rest of Boost, actually :) ). > >Anyway, I'd like to use pyste for generating some of the relevant >code. I have a header containing a lot of free functions like >Point calcCircleCenter( const Point& a, const Point& b,const Point& c ); >and it would be really convenient to use pyste here, cause there are a >*lot* of these functions. >However, there is the problem that in front of the header, I have >class declarations like >class SomeClass; > >and when pyste sees this, it outputs code like > class_< SomeClass, boost::noncopyable >("SomeClass", no_init) > ; >which is not what I want, since SomeClass is in another header, and >also being exported to python. So my question basically is, is there >a way to exclude an entire class from the pyste output, since >ch = AllFromHeader( "some_header.h" ); >exclude( ch.SomeClass ); >doesn't seem to do the trick.. > Indeed, that is a "misfeature" of pyste, because it shouldn't export forward declared classes at all. I believe the desired behaviour would be to show a warning in case the user tries to export an forward declared class explicitly (using "Class"), or silently ignore them when the AllFromHeader construct is used. The fact that you can't exclude a class is a bug too. I will work on this. Thanks for the feedback Dominique! Regards, Nicodemus. From dominique.devriese at student.kuleuven.ac.be Tue Apr 22 02:04:10 2003 From: dominique.devriese at student.kuleuven.ac.be (Dominique Devriese) Date: 22 Apr 2003 02:04:10 +0200 Subject: [C++-sig] g++ -Wall complains Message-ID: <8765p7l7np.fsf@student.kuleuven.ac.be> Hi again, now that I'm complaining here anyway, I thought I'd give them all at once :) I'm in the habit of compiling with lots of -W* options like -Wall etc. cause these are often helpful for finding bugs early. However, there are some functions in Boost.python that don't use some of their arguments, and this causes gcc to complain about "unused arguments". This kinda clutters the gcc output with useless ( and long ) warnings.. There's an easy fix for this: void myfunction( int /* a */ ) { // ... }; I'm not sure if this is still a problem with the most recent cvs versions, but if it is, it would be great if you could fix this ( I'm using the debian packages ). If you want, I can provide you with a patch for this, but well, fixing this is really easy, and there aren't much of these probs, so I'm not sure if it's necessary.. thanks domi -- The abuse of greatness is when it disjoins remorse from power. -- William Shakespeare, "Julius Caesar" From dominique.devriese at student.kuleuven.ac.be Tue Apr 22 02:08:54 2003 From: dominique.devriese at student.kuleuven.ac.be (Dominique Devriese) Date: 22 Apr 2003 02:08:54 +0200 Subject: [C++-sig] exclude an entire class with pyste ? In-Reply-To: <3EA47D65.4030804@globalite.com.br> References: <87adejlaa9.fsf@student.kuleuven.ac.be> <3EA47D65.4030804@globalite.com.br> Message-ID: <871xzvl7ft.fsf@student.kuleuven.ac.be> nicodemus writes: nicodemus> Indeed, that is a "misfeature" of pyste, because it nicodemus> shouldn't export forward declared classes at all. I nicodemus> believe the desired behaviour would be to show a warning nicodemus> in case the user tries to export an forward declared nicodemus> class explicitly (using "Class"), or silently ignore them nicodemus> when the AllFromHeader construct is used. I'm not sure if silently ignoring is a good option, since I can imagine that if someone has code like class SomeInternalClass; SomeInternalClass& getClass(); doSomething( SomeInternalClass& ); he'll want it to be exported.. nicodemus> The fact that you can't exclude a class is a bug too. i think this would be a better solution.. nicodemus> I will work on this. great, thanks :) domi -- You are going to have a new love affair. From jeff at brewer.com Tue Apr 22 02:26:40 2003 From: jeff at brewer.com (Jeff Brewer) Date: Mon, 21 Apr 2003 17:26:40 -0700 Subject: [C++-sig] MSVC calling conventions __stdcall, __fastcall, __cdecl and Boost Python Message-ID: <3C609AD34AAF22488364057AA72EAC14019EE2FC@adsl-64-170-107-114.dsl.snfc21.pacbell.net> I am trying to wrap a library that contains methods and functions that use explicit calling conventions (__stdcall, __fastcall, __cdecl). My example is this: #include using namespace boost::python; int __stdcall f() { return 0; } class dog { public: int __stdcall f() { return 0; } }; BOOST_PYTHON_MODULE(test) { def("f",&f); class_("dog") .def("f", &dog::f) ; } Apparently, MSVC treats a int (__stdcall *)() as a totally different type than int (*)() type. To make this work in Boost.Python, I added some get_signature function templates, I added a couple templates to the member_function_cast.hpp file and also updated Boost's type_traits module to recognize int (__stdcall dog::*)() as a valid member function pointer. All of this stuff has ifdef BOOST_MSVC's around it. I guess I have two questions. One, is there any way to tell if I missed anything or is there another way of wrapping my functions besides writing manual wrappers (my example seems to compile and run)? Two, does it make sense to incorporate changes like these into Boost and Boost.Python? This is very compiler specific stuff, but it seems like anyone wrapping Windows APIs or DLLs that use explicit calling conventions would run into this problem (I haven't been reading this group very long, so forgive me if this topic has already been covered). I'd be happy to contribute my templates. Thank you, Jeff Brewer p.s. I haven't been using Boost Python very long, but I am constantly amazed at how well it works and from what little I know about how it works (my brain hurts from looking through the template definitions :). I also appreciate the help on this mailing list. From dave at boost-consulting.com Tue Apr 22 02:36:38 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 20:36:38 -0400 Subject: [C++-sig] exclude an entire class with pyste ? In-Reply-To: <871xzvl7ft.fsf@student.kuleuven.ac.be> (Dominique Devriese's message of "22 Apr 2003 02:08:54 +0200") References: <87adejlaa9.fsf@student.kuleuven.ac.be> <3EA47D65.4030804@globalite.com.br> <871xzvl7ft.fsf@student.kuleuven.ac.be> Message-ID: <84ptnfmkq1.fsf@boost-consulting.com> Dominique Devriese writes: > nicodemus writes: > > nicodemus> Indeed, that is a "misfeature" of pyste, because it > nicodemus> shouldn't export forward declared classes at all. I > nicodemus> believe the desired behaviour would be to show a warning > nicodemus> in case the user tries to export an forward declared > nicodemus> class explicitly (using "Class"), or silently ignore them > nicodemus> when the AllFromHeader construct is used. > > I'm not sure if silently ignoring is a good option, since I can > imagine that if someone has code like > class SomeInternalClass; > > SomeInternalClass& getClass(); > > doSomething( SomeInternalClass& ); > > he'll want it to be exported.. But you can't export a class unless you can see its definition (ignoring the use of opaque pointer converters, of course). In fact, if such a forward declaration is visible it's quite likely the class is being exported in a different extension module. You know, the Boost.Python documentation hardly mentions that extension modules can interoperate with one another's exported classes. We probably ought to say something about that... > nicodemus> The fact that you can't exclude a class is a bug too. > > i think this would be a better solution.. I think Nicodemus has the right idea in this case. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Apr 22 02:40:23 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 20:40:23 -0400 Subject: [C++-sig] g++ -Wall complains In-Reply-To: <8765p7l7np.fsf@student.kuleuven.ac.be> (Dominique Devriese's message of "22 Apr 2003 02:04:10 +0200") References: <8765p7l7np.fsf@student.kuleuven.ac.be> Message-ID: <84n0ijmkjs.fsf@boost-consulting.com> Dominique Devriese writes: > Hi again, > now that I'm complaining here anyway, I thought I'd give them all at > once :) > I'm in the habit of compiling with lots of -W* options like -Wall > etc. cause these are often helpful for finding bugs early. > However, there are some functions in Boost.python that don't use some > of their arguments, and this causes gcc to complain about "unused > arguments". This kinda clutters the gcc output with useless ( and > long ) warnings.. > There's an easy fix for this: > void myfunction( int /* a */ ) > { // ... > }; We've been through the code to do that at one point, but some new ones may have crept in. > I'm not sure if this is still a problem with the most recent cvs > versions, but if it is, it would be great if you could fix this ( I'm > using the debian packages ). If you want, I can provide you with a > patch for this, but well, fixing this is really easy, and there aren't > much of these probs, so I'm not sure if it's necessary.. > thanks > domi You could at least hunt down the places where the problem occurs and let us know. That would help. There's probably no way anyone will invest the effort to find these just to squash some warnings we're not seeing. -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Tue Apr 22 02:45:10 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 21 Apr 2003 21:45:10 -0300 Subject: [C++-sig] exclude an entire class with pyste ? In-Reply-To: <871xzvl7ft.fsf@student.kuleuven.ac.be> References: <87adejlaa9.fsf@student.kuleuven.ac.be> <3EA47D65.4030804@globalite.com.br> <871xzvl7ft.fsf@student.kuleuven.ac.be> Message-ID: <3EA49096.1060207@globalite.com.br> Dominique Devriese wrote: >nicodemus writes: > > nicodemus> Indeed, that is a "misfeature" of pyste, because it > nicodemus> shouldn't export forward declared classes at all. I > nicodemus> believe the desired behaviour would be to show a warning > nicodemus> in case the user tries to export an forward declared > nicodemus> class explicitly (using "Class"), or silently ignore them > nicodemus> when the AllFromHeader construct is used. > >I'm not sure if silently ignoring is a good option, since I can >imagine that if someone has code like >class SomeInternalClass; > >SomeInternalClass& getClass(); > >doSomething( SomeInternalClass& ); > >he'll want it to be exported.. > Certainly, but not with this header, since it doesn't contain any useful info about SomeInternalClass. The user will have to export the class from SomeInternalClass.h, using Class or AllFromHeader constructs, as any other class. But If you don't want to use the methods and attributes of SomeInternalClass, you just want to use functions that pass the class around, you should use return_opaque_pointer as a call policy. So your example would be exported as: h = AllFromHeader('foo.h') set_policy(h.getClass, return_value_policy(return_opaque_pointer)) and that's all. 8) > nicodemus> I will work on this. > >great, thanks :) > You're welcome! Thanks again for the feedback. Nicodemus. From dave at boost-consulting.com Tue Apr 22 04:32:54 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 21 Apr 2003 22:32:54 -0400 Subject: [C++-sig] exclude an entire class with pyste ? In-Reply-To: <3EA49096.1060207@globalite.com.br> (nicodemus@globalite.com.br's message of "Mon, 21 Apr 2003 21:45:10 -0300") References: <87adejlaa9.fsf@student.kuleuven.ac.be> <3EA47D65.4030804@globalite.com.br> <871xzvl7ft.fsf@student.kuleuven.ac.be> <3EA49096.1060207@globalite.com.br> Message-ID: <84el3vmfc9.fsf@boost-consulting.com> Nicodemus writes: > Dominique Devriese wrote: > > But If you don't want to use the methods and attributes of > SomeInternalClass, you just want to use functions that pass the class > around, you should use return_opaque_pointer as a call policy. So your > example would be exported as: > > h = AllFromHeader('foo.h') > set_policy(h.getClass, return_value_policy(return_opaque_pointer)) > > and that's all. 8) Well, if the class is wrapped elsewhere with class_<...> you don't want to do that; just use the usual call policies in that case. -- Dave Abrahams Boost Consulting www.boost-consulting.com From dominique.devriese at student.kuleuven.ac.be Tue Apr 22 14:31:02 2003 From: dominique.devriese at student.kuleuven.ac.be (Dominique Devriese) Date: 22 Apr 2003 14:31:02 +0200 Subject: [C++-sig] exclude an entire class with pyste ? In-Reply-To: <3EA49096.1060207@globalite.com.br> References: <87adejlaa9.fsf@student.kuleuven.ac.be> <3EA47D65.4030804@globalite.com.br> <871xzvl7ft.fsf@student.kuleuven.ac.be> <3EA49096.1060207@globalite.com.br> Message-ID: <87ptnek92x.fsf@student.kuleuven.ac.be> nicodemus writes: nicodemus> Indeed, that is a "misfeature" of pyste, because it nicodemus> shouldn't export forward declared classes at all. I nicodemus> believe the desired behaviour would be to show a warning nicodemus> in case the user tries to export an forward declared nicodemus> class explicitly (using "Class"), or silently ignore them nicodemus> when the AllFromHeader construct is used. >> I'm not sure if silently ignoring is a good option, since I can >> imagine that if someone has code like class SomeInternalClass; >> SomeInternalClass& getClass(); >> doSomething( SomeInternalClass& ); >> he'll want it to be exported.. nicodemus> Certainly, but not with this header, since it doesn't nicodemus> contain any useful info about SomeInternalClass. The user nicodemus> will have to export the class from SomeInternalClass.h, nicodemus> using Class or AllFromHeader constructs, as any other nicodemus> class. nicodemus> But If you don't want to use the methods and attributes nicodemus> of SomeInternalClass, you just want to use functions that nicodemus> pass the class around, you should use nicodemus> return_opaque_pointer as a call policy. So your example nicodemus> would be exported as: having read up on return_opaque_pointer, I must agree that you're right, sorry :) cheers domi -- You will outgrow your usefulness. From dominique.devriese at student.kuleuven.ac.be Tue Apr 22 14:53:32 2003 From: dominique.devriese at student.kuleuven.ac.be (Dominique Devriese) Date: 22 Apr 2003 14:53:32 +0200 Subject: [C++-sig] g++ -Wall complains In-Reply-To: <84n0ijmkjs.fsf@boost-consulting.com> References: <8765p7l7np.fsf@student.kuleuven.ac.be> <84n0ijmkjs.fsf@boost-consulting.com> Message-ID: <87lly2k81f.fsf@student.kuleuven.ac.be> David Abrahams writes: >> I'm in the habit of compiling with lots >> of -W* options like -Wall etc. cause these are often helpful >> for >> finding bugs early. However, there are some functions in >> Boost.python that don't use some of their arguments, and this >> causes gcc to complain about "unused arguments". This kinda >> clutters the gcc output with useless ( and long ) warnings.. >> I'm not sure if this is still a problem with the most recent cvs >> versions, but if it is, it would be great if you could fix this ( >> I'm using the debian packages ). If you want, I can provide you >> with a patch for this, but well, fixing this is really easy, and >> there aren't much of these probs, so I'm not sure if it's >> necessary.. thanks domi David> You could at least hunt down the places where the problem David> occurs and let us know. That would help. There's probably David> no way anyone will invest the effort to find these just to David> squash some warnings we're not seeing. here's a patch with three fixes that remove all of the spurious output for me.. It's against the boost.python headers from the debian packages, which means b.p version 1.30.0.. -------------- next part -------------- A non-text attachment was scrubbed... Name: boost.diff Type: application/x-patch Size: 1402 bytes Desc: not available URL: -------------- next part -------------- cheers domi -- You will hear good news from one you thought unfriendly to you. From talsit at talsit.org Tue Apr 22 15:52:41 2003 From: talsit at talsit.org (tALSit de CoD) Date: Tue, 22 Apr 2003 23:52:41 +1000 Subject: [C++-sig] Interface design. Message-ID: <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> Ok, just a quick question. I'm now writing an interface to a whole engine with boost (and loving it!), but I'm experiencing extremely long compile times, as one would imagine, with all the magic going on. Is it possible / recommended to split the file that defines the interface into various files? This is also because I want to split it into separate logical units as well, just like my engine, mainly two groups: core & nodes. BTW: this stuff is great? Does anyone have a fansite for this? And the peer-support on this is absolute magnificent!! Cheers and keep up the incredible work! tALSit de CoD | talsit.org From dave at boost-consulting.com Tue Apr 22 16:21:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 22 Apr 2003 10:21:46 -0400 Subject: [C++-sig] g++ -Wall complains In-Reply-To: <87lly2k81f.fsf@student.kuleuven.ac.be> (Dominique Devriese's message of "22 Apr 2003 14:53:32 +0200") References: <8765p7l7np.fsf@student.kuleuven.ac.be> <84n0ijmkjs.fsf@boost-consulting.com> <87lly2k81f.fsf@student.kuleuven.ac.be> Message-ID: <84d6jeliit.fsf@boost-consulting.com> Dominique Devriese writes: > here's a patch with three fixes that remove all of the spurious output > for me.. It's against the boost.python headers from the debian > packages, which means b.p version 1.30.0.. Applied, thanks! -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Tue Apr 22 16:27:46 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 22 Apr 2003 10:27:46 -0400 Subject: [C++-sig] Interface design. In-Reply-To: <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> (tALSit de CoD's message of "Tue, 22 Apr 2003 23:52:41 +1000") References: <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> Message-ID: <84adeili8t.fsf@boost-consulting.com> tALSit de CoD writes: > Ok, just a quick question. > > I'm now writing an interface to a whole engine with boost (and > loving it!), but I'm experiencing extremely long compile times, as > one would imagine, with all the magic going on. > > Is it possible / recommended to split the file that defines the > interface into various files? This is also because I want to split > it into separate logical units as well, just like my engine, mainly > two groups: core & nodes. Yes. You can either take the approach shown here: http://www.boost.org/libs/python/doc/v2/faq.html#c1204 Or you can actually break your extension module into separate extension modules. It's a little-known and underutilized feature of Boost.Python that component-based development is supported. > BTW: this stuff is great? Is that a question ? I guess I'd answer "yes" ;-) > Does anyone have a fansite for this? http://www.python.org/cgi-bin/moinmoin/boost_2epython is the closest thing I've found. Why don't you start an actual fansite? > And the peer-support on this is absolute magnificent!! Cheers and > keep up the incredible work! Thanks very much; I'm glad to hear it's working well for you. -- Dave Abrahams Boost Consulting www.boost-consulting.com From talsit at talsit.org Tue Apr 22 16:47:52 2003 From: talsit at talsit.org (tALSit de CoD) Date: Wed, 23 Apr 2003 00:47:52 +1000 Subject: [C++-sig] Interface design. In-Reply-To: <84adeili8t.fsf@boost-consulting.com> References: <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> Message-ID: <5.2.0.9.2.20030423004232.05ab9a70@talsit.org> At 10:27 22/04/2003 -0400, you wrote: >tALSit de CoD writes: > >Or you can actually break your extension module into separate >extension modules. It's a little-known and underutilized feature of >Boost.Python that component-based development is supported. But can you have nested modules? As in: BOOST_PYTHON_MODULE (kikura) { BOOST_PYTHON_MODULE (kikuraCore) { ... stuff ... } BOOST_PYTHON_MODULE (kikuraNode) { ... stuff ... } } Or would you need something like so: BOOST_PYTHON_MODULE (kikuraCore) { ... stuff ... } BOOST_PYTHON_MODULE (kikuraNode) { ... stuff ... } In this case (or both really), how would you import the modules from python? I'm not too sure how python looks for dynamic libs, but would you have to put each module in a separate dynamic library, and then call from python: import kikuraCore import kikuraNode ? For now, I'll be using the "unpreferred" approach to splitting up the thingy, as long as it works. Cheers! > > BTW: this stuff is great? > >Is that a question ? I guess I'd answer "yes" ;-) > > > Does anyone have a fansite for this? > > http://www.python.org/cgi-bin/moinmoin/boost_2epython > >is the closest thing I've found. Why don't you start an actual >fansite? > > > And the peer-support on this is absolute magnificent!! Cheers and > > keep up the incredible work! > >Thanks very much; I'm glad to hear it's working well for you. > >-- >Dave Abrahams >Boost Consulting >www.boost-consulting.com > > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig tALSit de CoD | talsit.org From niki at vintech.bg Tue Apr 22 17:00:14 2003 From: niki at vintech.bg (Niki Spahiev) Date: Tue, 22 Apr 2003 18:00:14 +0300 Subject: [C++-sig] Interface design. In-Reply-To: <5.2.0.9.2.20030423004232.05ab9a70@talsit.org> References: <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> <5.2.0.9.2.20030423004232.05ab9a70@talsit.org> Message-ID: <3EA558FE.1050103@vintech.bg> tALSit de CoD wrote: > > But can you have nested modules? As in: Look for "scope" examples. Niki Spahiev From nicodemus at globalite.com.br Tue Apr 22 18:24:44 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 22 Apr 2003 13:24:44 -0300 Subject: [C++-sig] Interface design. In-Reply-To: <5.2.0.9.2.20030423004232.05ab9a70@talsit.org> References: <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> <5.2.0.9.2.20030422234218.00a7cb08@talsit.org> <5.2.0.9.2.20030423004232.05ab9a70@talsit.org> Message-ID: <3EA56CCC.7010006@globalite.com.br> tALSit de CoD wrote: > At 10:27 22/04/2003 -0400, you wrote: > >> tALSit de CoD writes: >> >> Or you can actually break your extension module into separate >> extension modules. It's a little-known and underutilized feature of >> Boost.Python that component-based development is supported. > > > But can you have nested modules? As in: > > BOOST_PYTHON_MODULE (kikura) { > BOOST_PYTHON_MODULE (kikuraCore) { > ... stuff ... > } > BOOST_PYTHON_MODULE (kikuraNode) { > ... stuff ... > } > } > > Or would you need something like so: > > BOOST_PYTHON_MODULE (kikuraCore) { > ... stuff ... > } > BOOST_PYTHON_MODULE (kikuraNode) { > ... stuff ... > } > > In this case (or both really), how would you import the modules from > python? I'm not too sure how python looks for dynamic libs, but would > you have to put each module in a separate dynamic library, and then > call from python: > > import kikuraCore > import kikuraNode > > ? > > For now, I'll be using the "unpreferred" approach to splitting up the > thingy, as long as it works. > > Cheers! Hi! Suppose you want to have a top level package in python named kikura, with two sub-modules, core and node, so that a user uses your package like this: import kikura.core import kikura.node kikura.core.Foo() You can acomplish this generating the two sub-modules (core and node) using Boost.Python, like any other module: // file core.cpp BOOST_PYTHON_MODULE(core) { ... } // file node.cpp BOOST_PYTHON_MODULE(node) { ... } And creating the following directory structure: /kikura __init__.py core.pyd node.pyd And that's it (the file __init__.py indicates that the directory is a package. It can be empty, but it can be useful to provide a more friendly interface for your users. See below). I suggest that you name your bindings _core and _node, thought, and make the sub-modules *python* modules which import the funcionality of the bindings, like so: /kikura __init__.py /core __init__.py _core.pyd /node __init__.py _node.pyd with /kikura/core/__init__.py contains the statement "from _core import *". The same for the node package. Why do it like this? Well, because then you can easily implement some things in python in a way that is transparent for the user (I am assuming here that you're developing this library). Suppose you want to add a new utility function into the core package, made in python. You just create a file "foo.py" and put it inside /kikura/core, and add this line to its __init__.py: from foo import util_function, other_function and your users will access it like so: import kikura.core kikura.core.util_function(10) Back to the compilation time issue, notice that you don't have to write all class_ declarations inside the BOOST_PYTHON_MODULE macro directly, you can split them in any number of files you like. For example: // file Foo.cpp #include void export_foo() { class_()... } // file Bar.cpp #include void export_bar() { class_()... } // file core.cpp void export_foo(); void export_bar(); BOOST_PYTHON_MODULE(core) { export_foo(); export_bar(); } This will take longer to compile than a single file (because the Boost.Python headers must be compiled for each cpp), but if your developing the library this is a big help, because a change in a header doesn't mean the entire bindings will have to be recompiled. Hope that helps, Nicodemus. From dave at boost-consulting.com Tue Apr 22 20:01:17 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 22 Apr 2003 14:01:17 -0400 Subject: [C++-sig] MSVC calling conventions __stdcall, __fastcall, __cdecl and Boost Python In-Reply-To: <3C609AD34AAF22488364057AA72EAC14019EE2FC@adsl-64-170-107-114.dsl.snfc21.pacbell.net> (Jeff Brewer's message of "Mon, 21 Apr 2003 17:26:40 -0700") References: <3C609AD34AAF22488364057AA72EAC14019EE2FC@adsl-64-170-107-114.dsl.snfc21.pacbell.net> Message-ID: <84adeijtsi.fsf@boost-consulting.com> "Jeff Brewer" writes: > I am trying to wrap a library that contains methods and functions that > use explicit calling conventions (__stdcall, __fastcall, __cdecl). My > example is this: > > #include > using namespace boost::python; > > int __stdcall f() > { > return 0; > } > > class dog > { > public: > int __stdcall f() { return 0; } > }; > > BOOST_PYTHON_MODULE(test) > { > def("f",&f); > > class_("dog") > .def("f", &dog::f) > ; > } > > Apparently, MSVC treats a int (__stdcall *)() as a totally different > type than int (*)() type. Yup. > To make this work in Boost.Python, I added some get_signature > function templates, I added a couple templates to the > member_function_cast.hpp file and also updated Boost's type_traits > module to recognize int (__stdcall dog::*)() as a valid member > function pointer. All of this stuff has ifdef BOOST_MSVC's around > it. > > I guess I have two questions. One, is there any way to tell if I missed > anything Try more examples. You could try tweaking all of the files in libs/python/test to use __stdcall somewhere. > or is there another way of wrapping my functions besides writing > manual wrappers There are other wrapping systems ;-) > (my example seems to compile and run)? Two, does it make sense to > incorporate changes like these into Boost and Boost.Python? Yes, definitely. It would also be good to handle __fastcall and extern "C" functions. > This is very compiler specific stuff, but it seems like anyone > wrapping Windows APIs or DLLs that use explicit calling conventions > would run into this problem (I haven't been reading this group very > long, so forgive me if this topic has already been covered). I'd be > happy to contribute my templates. We have a precedent for this kind of stuff already; see http://www.boost.org/libs/bind/mem_fn.html#stdcall. I'd love to see it handled the same way. > p.s. I haven't been using Boost Python very long, but I am constantly > amazed at how well it works and from what little I know about how it > works (my brain hurts from looking through the template definitions :). Mine too :) > I also appreciate the help on this mailing list. You're welcome! -- Dave Abrahams Boost Consulting www.boost-consulting.com From rwgk at yahoo.com Tue Apr 22 20:20:25 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 22 Apr 2003 11:20:25 -0700 (PDT) Subject: [C++-sig] Interface design. In-Reply-To: <3EA56CCC.7010006@globalite.com.br> Message-ID: <20030422182025.93702.qmail@web20210.mail.yahoo.com> Hi! This is a very nice overview of component based development with Boost.Python! I'd like to add one more great discovery (thanks to Dave): It is easily possible to add member functions/methods from Python. For example: In C++: class_("point") ... ; Now in Python, e.g. in Bruno's __init__.py file: # a regular function def point_repr(self): return str((self.x, self.y)) # now we turn it into a member function point.__repr__ = point_repr *All* point instances created from C++ will have this pure-Python member function! We use this trick to: - keep all I/O related code out of our C++ libraries (no trouble with redirecting) - cut down compile times to zero for these additional functions - reduce the memory footprint to virtually zero - minimize the need to recompile - rapid prototyping (you can move the code to C++ if required without changing the interface) - have less source code Another useful idea is to replace constructors with factory functions: _point = point def point(x=0, y=0): return _point(x, y) In this simple case there is not much gained, but for constructurs with many overloads and/or arguments this is often a great simplification, again with virtually zero memory footprint and zero compile-time overhead for the keyword support. Ralf --- Nicodemus wrote: > Hi! > > Suppose you want to have a top level package in python named kikura, > with two sub-modules, core and node, so that a user uses your package > like this: > > import kikura.core > import kikura.node > kikura.core.Foo() > > > You can acomplish this generating the two sub-modules (core and node) > using Boost.Python, like any other module: > > // file core.cpp > BOOST_PYTHON_MODULE(core) > { > ... > } > > // file node.cpp > BOOST_PYTHON_MODULE(node) > { > ... > } > > And creating the following directory structure: > > /kikura > __init__.py > core.pyd > node.pyd > > > And that's it (the file __init__.py indicates that the directory is a > package. It can be empty, but it can be useful to provide a more > friendly interface for your users. See below). > > I suggest that you name your bindings _core and _node, thought, and make > the sub-modules *python* modules which import the funcionality of the > bindings, like so: > > /kikura > __init__.py > /core > __init__.py > _core.pyd > /node > __init__.py > _node.pyd > > > with /kikura/core/__init__.py contains the statement "from _core import > *". The same for the node package. Why do it like this? Well, because > then you can easily implement some things in python in a way that is > transparent for the user (I am assuming here that you're developing this > library). Suppose you want to add a new utility function into the core > package, made in python. You just create a file "foo.py" and put it > inside /kikura/core, and add this line to its __init__.py: > > from foo import util_function, other_function > > > and your users will access it like so: > > import kikura.core > kikura.core.util_function(10) > > > Back to the compilation time issue, notice that you don't have to write > all class_ declarations inside the BOOST_PYTHON_MODULE macro directly, > you can split them in any number of files you like. For example: > > // file Foo.cpp > #include > void export_foo() > { > class_()... > } > > // file Bar.cpp > #include > void export_bar() > { > class_()... > } > > // file core.cpp > void export_foo(); > void export_bar(); > BOOST_PYTHON_MODULE(core) > { > export_foo(); > export_bar(); > } > > > This will take longer to compile than a single file (because the > Boost.Python headers must be compiled for each cpp), but if your > developing the library this is a big help, because a change in a header > doesn't mean the entire bindings will have to be recompiled. > > Hope that helps, > Nicodemus. __________________________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo http://search.yahoo.com From dave at boost-consulting.com Wed Apr 23 00:09:06 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 22 Apr 2003 18:09:06 -0400 Subject: [C++-sig] Interface design. In-Reply-To: <20030422182025.93702.qmail@web20210.mail.yahoo.com> (Ralf W. Grosse-Kunstleve's message of "Tue, 22 Apr 2003 11:20:25 -0700 (PDT)") References: <20030422182025.93702.qmail@web20210.mail.yahoo.com> Message-ID: <84el3ui3r1.fsf@boost-consulting.com> Bruno (Nicodemus) and Ralf, it would be super if we could get this stuff into the official docs somewhere. Perhaps in the tutorial or in a "Techniques" section? Thoughts? "Ralf W. Grosse-Kunstleve" writes: > Hi! > > This is a very nice overview of component based development with Boost.Python! > I'd like to add one more great discovery (thanks to Dave): > > It is easily possible to add member functions/methods from Python. > For example: > > In C++: > > class_("point") ... ; > > Now in Python, e.g. in Bruno's __init__.py file: > > # a regular function > def point_repr(self): > return str((self.x, self.y)) > > # now we turn it into a member function > point.__repr__ = point_repr > > *All* point instances created from C++ will have this pure-Python > member function! > > We use this trick to: > > - keep all I/O related code out of our C++ libraries (no trouble with > redirecting) > - cut down compile times to zero for these additional functions > - reduce the memory footprint to virtually zero > - minimize the need to recompile > - rapid prototyping (you can move the code to C++ if required without > changing the interface) > - have less source code Exercise for the reader: finish the following proof-of-concept code which uses metaclasses to allow a nicer syntax for injection of additional methods: # The one Boost.Python uses for all wrapped classes. class BoostPythonMetaclass(type): pass # some Boost.Python wrapped class class foo(object): __metaclass__ = BoostPythonMetaclass class injector(object): class __metaclass__(BoostPythonMetaclass): def __init__(self, name, bases, dict): for b in bases: if type(b) not in (self, type): for k,v in dict.items(): setattr(b,k,v) return type.__init__(self, name, bases, dict) # inject some methods in foo class more_foo(injector, foo): def __repr__(self): return 'foobar' def ga(self, x): return getattr(self, x) print repr(foo()) print foo().ga('__repr__') Its biggest problem is that it sets some attributes it shouldn't, like __module__ and, well, __metaclass__ ;-) > Another useful idea is to replace constructors with factory functions: > > _point = point > > def point(x=0, y=0): > return _point(x, y) > > In this simple case there is not much gained, but for constructurs with > many overloads and/or arguments this is often a great simplification, again > with virtually zero memory footprint and zero compile-time overhead for > the keyword support. Yep, another nice technique! > --- Nicodemus wrote: >> Hi! >> >> Suppose you want to have a top level package in python named kikura, >> with two sub-modules, core and node, so that a user uses your package >> like this: >> >> import kikura.core >> import kikura.node >> kikura.core.Foo() >> >> >> You can acomplish this generating the two sub-modules (core and node) >> using Boost.Python, like any other module: >> >> // file core.cpp >> BOOST_PYTHON_MODULE(core) >> { >> ... >> } >> >> // file node.cpp >> BOOST_PYTHON_MODULE(node) >> { >> ... >> } >> >> And creating the following directory structure: >> >> /kikura >> __init__.py >> core.pyd >> node.pyd >> >> >> And that's it (the file __init__.py indicates that the directory is a >> package. It can be empty, but it can be useful to provide a more >> friendly interface for your users. See below). >> >> I suggest that you name your bindings _core and _node, thought, and make >> the sub-modules *python* modules which import the funcionality of the >> bindings, like so: >> >> /kikura >> __init__.py >> /core >> __init__.py >> _core.pyd >> /node >> __init__.py >> _node.pyd >> >> >> with /kikura/core/__init__.py contains the statement "from _core import >> *". The same for the node package. Why do it like this? Well, because >> then you can easily implement some things in python in a way that is >> transparent for the user (I am assuming here that you're developing this >> library). Suppose you want to add a new utility function into the core >> package, made in python. You just create a file "foo.py" and put it >> inside /kikura/core, and add this line to its __init__.py: >> >> from foo import util_function, other_function >> >> >> and your users will access it like so: >> >> import kikura.core >> kikura.core.util_function(10) >> >> >> Back to the compilation time issue, notice that you don't have to write >> all class_ declarations inside the BOOST_PYTHON_MODULE macro directly, >> you can split them in any number of files you like. For example: >> >> // file Foo.cpp >> #include >> void export_foo() >> { >> class_()... >> } >> >> // file Bar.cpp >> #include >> void export_bar() >> { >> class_()... >> } >> >> // file core.cpp >> void export_foo(); >> void export_bar(); >> BOOST_PYTHON_MODULE(core) >> { >> export_foo(); >> export_bar(); >> } >> >> >> This will take longer to compile than a single file (because the >> Boost.Python headers must be compiled for each cpp), but if your >> developing the library this is a big help, because a change in a header >> doesn't mean the entire bindings will have to be recompiled. >> >> Hope that helps, >> Nicodemus. > > > __________________________________________________ > Do you Yahoo!? > The New Yahoo! Search - Faster. Easier. Bingo > http://search.yahoo.com > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Apr 23 00:35:40 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 22 Apr 2003 19:35:40 -0300 Subject: [C++-sig] Interface design. In-Reply-To: <84el3ui3r1.fsf@boost-consulting.com> References: <20030422182025.93702.qmail@web20210.mail.yahoo.com> <84el3ui3r1.fsf@boost-consulting.com> Message-ID: <3EA5C3BC.2010608@globalite.com.br> David Abrahams wrote: >Bruno (Nicodemus) and Ralf, > >it would be super if we could get this stuff into the official docs >somewhere. Perhaps in the tutorial or in a "Techniques" section? >Thoughts? > > > I think a section Techniques in the tutorial would be good enough. I volunteer to write it, with input from you both, of course. Unfortunetely this week I'm overloaded, but next week it's fine. >> "Ralf W. Grosse-Kunstleve" writes: >>Hi! >> >>This is a very nice overview of component based development with Boost.Python! >>I'd like to add one more great discovery (thanks to Dave): >> >>It is easily possible to add member functions/methods from Python. >>For example: >> >>In C++: >> >> class_("point") ... ; >> >>Now in Python, e.g. in Bruno's __init__.py file: >> >># a regular function >>def point_repr(self): >> return str((self.x, self.y)) >> >># now we turn it into a member function >>point.__repr__ = point_repr >> >>*All* point instances created from C++ will have this pure-Python >>member function! >> >>We use this trick to: >> >> - keep all I/O related code out of our C++ libraries (no trouble with >> redirecting) >> - cut down compile times to zero for these additional functions >> - reduce the memory footprint to virtually zero >> - minimize the need to recompile >> - rapid prototyping (you can move the code to C++ if required without >> changing the interface) >> - have less source code >> >> > >Exercise for the reader: finish the following proof-of-concept code >which uses metaclasses to allow a nicer syntax for injection of >additional methods: > > # The one Boost.Python uses for all wrapped classes. > class BoostPythonMetaclass(type): pass > > # some Boost.Python wrapped class > class foo(object): > __metaclass__ = BoostPythonMetaclass > > class injector(object): > class __metaclass__(BoostPythonMetaclass): > def __init__(self, name, bases, dict): > for b in bases: > if type(b) not in (self, type): > for k,v in dict.items(): > setattr(b,k,v) > return type.__init__(self, name, bases, dict) > > # inject some methods in foo > class more_foo(injector, foo): > def __repr__(self): > return 'foobar' > def ga(self, x): > return getattr(self, x) > > print repr(foo()) > print foo().ga('__repr__') > >Its biggest problem is that it sets some attributes it shouldn't, >like __module__ and, well, __metaclass__ ;-) > > > >>Another useful idea is to replace constructors with factory functions: >> >>_point = point >> >>def point(x=0, y=0): >> return _point(x, y) >> >>In this simple case there is not much gained, but for constructurs with >>many overloads and/or arguments this is often a great simplification, again >>with virtually zero memory footprint and zero compile-time overhead for >>the keyword support. >> >> > >Yep, another nice technique! > > > >>--- Nicodemus wrote: >> >> >>>Hi! >>> >>>Suppose you want to have a top level package in python named kikura, >>>with two sub-modules, core and node, so that a user uses your package >>>like this: >>> >>> import kikura.core >>> import kikura.node >>> kikura.core.Foo() >>> >>> >>>You can acomplish this generating the two sub-modules (core and node) >>>using Boost.Python, like any other module: >>> >>> // file core.cpp >>> BOOST_PYTHON_MODULE(core) >>> { >>> ... >>> } >>> >>> // file node.cpp >>> BOOST_PYTHON_MODULE(node) >>> { >>> ... >>> } >>> >>> And creating the following directory structure: >>> >>> /kikura >>> __init__.py >>> core.pyd >>> node.pyd >>> >>> >>>And that's it (the file __init__.py indicates that the directory is a >>>package. It can be empty, but it can be useful to provide a more >>>friendly interface for your users. See below). >>> >>>I suggest that you name your bindings _core and _node, thought, and make >>>the sub-modules *python* modules which import the funcionality of the >>>bindings, like so: >>> >>> /kikura >>> __init__.py >>> /core >>> __init__.py >>> _core.pyd >>> /node >>> __init__.py >>> _node.pyd >>> >>> >>>with /kikura/core/__init__.py contains the statement "from _core import >>>*". The same for the node package. Why do it like this? Well, because >>>then you can easily implement some things in python in a way that is >>>transparent for the user (I am assuming here that you're developing this >>>library). Suppose you want to add a new utility function into the core >>>package, made in python. You just create a file "foo.py" and put it >>>inside /kikura/core, and add this line to its __init__.py: >>> >>> from foo import util_function, other_function >>> >>> >>>and your users will access it like so: >>> >>> import kikura.core >>> kikura.core.util_function(10) >>> >>> >>>Back to the compilation time issue, notice that you don't have to write >>>all class_ declarations inside the BOOST_PYTHON_MODULE macro directly, >>>you can split them in any number of files you like. For example: >>> >>> // file Foo.cpp >>> #include >>> void export_foo() >>> { >>> class_()... >>> } >>> >>> // file Bar.cpp >>> #include >>> void export_bar() >>> { >>> class_()... >>> } >>> >>> // file core.cpp >>> void export_foo(); >>> void export_bar(); >>> BOOST_PYTHON_MODULE(core) >>> { >>> export_foo(); >>> export_bar(); >>> } >>> >>> >>>This will take longer to compile than a single file (because the >>>Boost.Python headers must be compiled for each cpp), but if your >>>developing the library this is a big help, because a change in a header >>>doesn't mean the entire bindings will have to be recompiled. >>> >>>Hope that helps, >>>Nicodemus. >>> >>> >>__________________________________________________ >>Do you Yahoo!? >>The New Yahoo! Search - Faster. Easier. Bingo >>http://search.yahoo.com >> >>_______________________________________________ >>C++-sig mailing list >>C++-sig at python.org >>http://mail.python.org/mailman/listinfo/c++-sig >> >> > > > From rwgk at yahoo.com Wed Apr 23 01:00:47 2003 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 22 Apr 2003 16:00:47 -0700 (PDT) Subject: [C++-sig] Interface design. In-Reply-To: <84el3ui3r1.fsf@boost-consulting.com> Message-ID: <20030422230047.91432.qmail@web20208.mail.yahoo.com> --- David Abrahams wrote: > Exercise for the reader: finish the following proof-of-concept code > which uses metaclasses to allow a nicer syntax for injection of > additional methods: > > # The one Boost.Python uses for all wrapped classes. > class BoostPythonMetaclass(type): pass > > # some Boost.Python wrapped class > class foo(object): > __metaclass__ = BoostPythonMetaclass > > class injector(object): > class __metaclass__(BoostPythonMetaclass): > def __init__(self, name, bases, dict): > for b in bases: > if type(b) not in (self, type): > for k,v in dict.items(): > setattr(b,k,v) > return type.__init__(self, name, bases, dict) > > # inject some methods in foo > class more_foo(injector, foo): > def __repr__(self): > return 'foobar' > def ga(self, x): > return getattr(self, x) > > print repr(foo()) > print foo().ga('__repr__') > > Its biggest problem is that it sets some attributes it shouldn't, > like __module__ and, well, __metaclass__ ;-) Cool! A few simple conventions could solve this in a general way. E.g.: - Only function names starting with a letter are injected. - The prefix "inject" is stripped. So __repr__ could be def'ed as inject__repr__. FWIW: here is an alternative that I am actually using: Create a new module foo_inject.py. def all additional functions at module scope. In another module (e.g. __init__.py): for v in foo_inject.__dict__.values(): if (hasattr(v, "func_name")): setattr(foo, v.func_name, v) Ralf __________________________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo http://search.yahoo.com From dave at boost-consulting.com Wed Apr 23 01:38:41 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 22 Apr 2003 19:38:41 -0400 Subject: [C++-sig] Interface design. In-Reply-To: <3EA5C3BC.2010608@globalite.com.br> (nicodemus@globalite.com.br's message of "Tue, 22 Apr 2003 19:35:40 -0300") References: <20030422182025.93702.qmail@web20210.mail.yahoo.com> <84el3ui3r1.fsf@boost-consulting.com> <3EA5C3BC.2010608@globalite.com.br> Message-ID: <84znmigl1a.fsf@boost-consulting.com> Nicodemus writes: > David Abrahams wrote: > >>Bruno (Nicodemus) and Ralf, >> >>it would be super if we could get this stuff into the official docs >>somewhere. Perhaps in the tutorial or in a "Techniques" section? >>Thoughts? >> >> > > I think a section Techniques in the tutorial would be good enough. I > volunteer to write it, with input from you both, of > course. Unfortunetely this week I'm overloaded, but next week it's > fine. No hurry, that sounds great! [Please try to limit the length of cited text.] Gratefully y'rs, -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Wed Apr 23 02:48:52 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Tue, 22 Apr 2003 21:48:52 -0300 Subject: [C++-sig] exclude an entire class with pyste ? In-Reply-To: <3EA47D65.4030804@globalite.com.br> References: <87adejlaa9.fsf@student.kuleuven.ac.be> <3EA47D65.4030804@globalite.com.br> Message-ID: <3EA5E2F4.1060806@globalite.com.br> Nicodemus wrote: > Indeed, that is a "misfeature" of pyste, because it shouldn't export > forward declared classes at all. I believe the desired behaviour would > be to show a warning in case the user tries to export an forward > declared class explicitly (using "Class"), or silently ignore them > when the AllFromHeader construct is used. > > The fact that you can't exclude a class is a bug too. > > I will work on this. Thanks for the feedback Dominique! Fixed in the current CVS. The behaviour above was implemented, and also the "exclude" bug was fixed. Regards, Nicodemus. From giulio.eulisse at cern.ch Fri Apr 25 11:54:55 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 25 Apr 2003 11:54:55 +0200 Subject: [C++-sig] pyste again... Message-ID: <1051264495.19287.88.camel@lxcms25> When trying to do wrappers for QTextEdit class from QT 3.0.5 with the following pyste file --CUT HERE-- Include("qscrollview.h") Include("qstylesheet.h") Include("qptrvector.h") Include("qvaluelist.h") Include("qpixmap.h") Include("qbitmap.h") Include("qcursor.h") Include("qstyle.h") Include("qvariant.h") Include("qobject.h") Include("qobjectdefs.h") Include("qpopupmenu.h") Include("qpainter.h") Include("qmetaobject.h") Include("private/qrichtext_p.h") Include("private/qucom_p.h") Include("private/qcom_p.h") Include("X11/Xlib.h") QTextEdit=Class("QTextEdit","qtextedit.h") exclude(QTextEdit.staticMetaObject) exclude(QTextEdit.qObject) exclude(QTextEdit.styleSheet) exclude(QTextEdit.mimeSourceFactory) exclude(QTextEdit.setGeometry) exclude(QTextEdit.setMask) exclude(QTextEdit.createPopupMenu) exclude(QTextEdit.drawContents) exclude(QTextEdit.zoomIn) exclude(QTextEdit.zoomOut) --- CUT HERE--- I get the following error: /afs/cern.ch/sw/lhcxx/specific/redhat73/gcc-3.2/Qt/3.0.5/include/qscrollview.h: In copy constructor `QTextEdit::QTextEdit(const QTextEdit&)': /afs/cern.ch/sw/lhcxx/specific/redhat73/gcc-3.2/Qt/3.0.5/include/qscrollview.h:238: `QScrollView::QScrollView(const QScrollView&)' is private Any idea? Is this a known bug? I'm using 25-4-2002 HEAD. Ciao, Giulio From dave at boost-consulting.com Fri Apr 25 13:57:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Fri, 25 Apr 2003 07:57:50 -0400 Subject: [C++-sig] Threads and Boost.Python In-Reply-To: <3EA0310A.4070604@vrac.iastate.edu> (Patrick Hartling's message of "Fri, 18 Apr 2003 12:08:26 -0500") References: <3EA0310A.4070604@vrac.iastate.edu> Message-ID: Patrick, I just wanted to say "thank you for your research and your posting". This information will definitely be useful, and I haven't forgotten it. Patrick Hartling writes: > I was able to sort out the multi-threading issues I was having earlier > this week with Boost.Python thanks to David Abrahams' suggestions. > What I came up with is a relatively simple guard object that is > instantiated whenever C++ code calls into the Python interpreter. -- Dave Abrahams Boost Consulting www.boost-consulting.com From talsit at talsit.org Sun Apr 27 07:04:23 2003 From: talsit at talsit.org (tALSit de CoD) Date: Sun, 27 Apr 2003 15:04:23 +1000 Subject: [C++-sig] Ownership question. Message-ID: <5.2.0.9.2.20030427145130.00b0d200@talsit.org> I have a class method that takes ownership of the object passed into it, and I want to know, how do I let boost.python know about this and not to manage that object anymore? Should i do a kludge job like make a function that return a new object, but telling boost.python not to manage it, then, when I add it into the method, it's "disappeared" from boost.python? Original thing: class cAnimCurveKey { /* stuff */ } class cAnimCurve { void addKey (cAnimCurveKey * key); // takes ownership of the key } When i wrap that in boost.python, and i create a key and then add it to the animation curve: >>> aninCurve = cAnimCurve () >>> key = cAninCurveKey () >>> animCurve.addKey (key) What happens there?? Is python the owner of the object key? I was thinking of this hack: (In C++ / boost.python) cAnimCurveKey * newAnimCurveKey () { return new cAnimCurveKey (); } BOOST_PYTHON_MODULE (kikura) { def ("newAnimCurveKey", newAnimCurveKey, return_value_policy ()); } And that way, python is not in charge of that object, and in theory, every key that gets created, is created to be put in an AnimCurve, so it's not _that_ bad, is it? OOOOORRRRRR Is there a way to specify to boost.python that you don't want it to manage or track that object anymore? Thanks folks Cheers! tALSit de CoD | talsit.org From nicodemus at globalite.com.br Sun Apr 27 09:00:16 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 27 Apr 2003 04:00:16 -0300 Subject: [C++-sig] Ownership question. In-Reply-To: <5.2.0.9.2.20030427145130.00b0d200@talsit.org> References: <5.2.0.9.2.20030427145130.00b0d200@talsit.org> Message-ID: <3EAB8000.1000909@globalite.com.br> tALSit de CoD wrote: > I have a class method that takes ownership of the object passed into > it, and I want to know, how do I let boost.python know about this and > not to manage that object anymore? > > Should i do a kludge job like make a function that return a new > object, but telling boost.python not to manage it, then, when I add it > into the method, it's "disappeared" from boost.python? > > Original thing: > > class cAnimCurveKey { /* stuff */ } > > class cAnimCurve { > void addKey (cAnimCurveKey * key); // takes ownership of the key > } > > When i wrap that in boost.python, and i create a key and then add it > to the animation curve: > > >>> aninCurve = cAnimCurve () > >>> key = cAninCurveKey () > >>> animCurve.addKey (key) > > What happens there?? Is python the owner of the object key? I was > thinking of this hack: > (In C++ / boost.python) > > cAnimCurveKey * newAnimCurveKey () { return new cAnimCurveKey (); } > > BOOST_PYTHON_MODULE (kikura) { > def ("newAnimCurveKey", newAnimCurveKey, return_value_policy > ()); > } > > And that way, python is not in charge of that object, and in theory, > every key that gets created, is created to be put in an AnimCurve, so > it's not _that_ bad, is it? > > > OOOOORRRRRR Is there a way to specify to boost.python that you don't > want it to manage or track that object anymore? > > Thanks folks > Cheers! Unfortunately, I don't think you will get a "nice" way to acomplish this, because of how garbage collection works in Python. Consider: >>> def foo(s): ... # use s ... del s # useless, but just to illustrate the point ... >>> x = [1, 2, 3] >>> foo(x) >>> x [1, 2, 3] So, there's simply no way for a Python function to delete a variable passed as parameter... actually, you can't delete any variable and be sure that it was actually release, because there could still be references to it somewhere else. In python, there's no ownership (you can have references with no ownership - weak references), just references to an object, that will be disposed when no more references exist. Regards, Nicodemus. > > > tALSit de CoD | talsit.org > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > . > From nicodemus at globalite.com.br Sun Apr 27 09:09:35 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 27 Apr 2003 04:09:35 -0300 Subject: [C++-sig] pyste again... In-Reply-To: <1051264495.19287.88.camel@lxcms25> References: <1051264495.19287.88.camel@lxcms25> Message-ID: <3EAB822F.5050102@globalite.com.br> Hi Giulio, sorry for not replying earlier. Giulio Eulisse wrote: >When trying to do wrappers for QTextEdit class from QT 3.0.5 with the >following pyste file > >--CUT HERE-- >Include("qscrollview.h") >Include("qstylesheet.h") >Include("qptrvector.h") >Include("qvaluelist.h") >Include("qpixmap.h") >Include("qbitmap.h") >Include("qcursor.h") >Include("qstyle.h") >Include("qvariant.h") >Include("qobject.h") >Include("qobjectdefs.h") >Include("qpopupmenu.h") >Include("qpainter.h") >Include("qmetaobject.h") >Include("private/qrichtext_p.h") >Include("private/qucom_p.h") >Include("private/qcom_p.h") >Include("X11/Xlib.h") >QTextEdit=Class("QTextEdit","qtextedit.h") >exclude(QTextEdit.staticMetaObject) >exclude(QTextEdit.qObject) >exclude(QTextEdit.styleSheet) >exclude(QTextEdit.mimeSourceFactory) >exclude(QTextEdit.setGeometry) >exclude(QTextEdit.setMask) >exclude(QTextEdit.createPopupMenu) >exclude(QTextEdit.drawContents) >exclude(QTextEdit.zoomIn) >exclude(QTextEdit.zoomOut) >--- CUT HERE--- > >I get the following error: > >/afs/cern.ch/sw/lhcxx/specific/redhat73/gcc-3.2/Qt/3.0.5/include/qscrollview.h: In copy constructor `QTextEdit::QTextEdit(const QTextEdit&)': >/afs/cern.ch/sw/lhcxx/specific/redhat73/gcc-3.2/Qt/3.0.5/include/qscrollview.h:238: `QScrollView::QScrollView(const QScrollView&)' is private > >Any idea? Is this a known bug? > > Weird... the error seems to be in the Qt files... I unfortunately don't have the Qt headers with me, so I can't investigate this further without your help. Could you send to me the involved Qt headers (particullary qscrollview.h and qtextedit.h), the output xml generated by GCCXML (run pyste with --debug) and the generated code? I will take a look at it then. Also, add boost::noncopyable to the class_'s template parameters of QTextEdit, and see if it compiles... Regards, Nicodemus. From talsit at talsit.org Sun Apr 27 09:15:00 2003 From: talsit at talsit.org (tALSit de CoD) Date: Sun, 27 Apr 2003 17:15:00 +1000 Subject: [C++-sig] Ownership question. In-Reply-To: <3EAB8000.1000909@globalite.com.br> References: <5.2.0.9.2.20030427145130.00b0d200@talsit.org> <5.2.0.9.2.20030427145130.00b0d200@talsit.org> Message-ID: <5.2.0.9.2.20030427170646.00a7dcb8@talsit.org> Ok, I think i got ya, but I think that's not what I was saying. When I do this: >>> key = cAnimCurveKey () Python is in charge of the ownership of the object. So, in theory, the GC could mark it for collection at any given moment, right? So if I now add the key to a class that takes it's ownership, what happens? >>> animCurve.addKey (key) # animCurve is now in charge of deleting the key is key still managed by python? Will it be marked for collection by the GC? If so, how do i prevent it? At 04:00 27/04/2003 -0300, you wrote: >tALSit de CoD wrote: > >>I have a class method that takes ownership of the object passed into it, >>and I want to know, how do I let boost.python know about this and not to >>manage that object anymore? [SNIP SNIP] >>OOOOORRRRRR Is there a way to specify to boost.python that you don't want >>it to manage or track that object anymore? >> >>Thanks folks >>Cheers! > > >Unfortunately, I don't think you will get a "nice" way to acomplish this, >because of how garbage collection works in Python. Consider: > > >>> def foo(s): >... # use s >... del s # useless, but just to illustrate the point >... > >>> x = [1, 2, 3] > >>> foo(x) > >>> x >[1, 2, 3] > >So, there's simply no way for a Python function to delete a variable >passed as parameter... actually, you can't delete any variable and be sure >that it was actually release, because there could still be references to >it somewhere else. In python, there's no ownership (you can have >references with no ownership - weak references), just references to an >object, that will be disposed when no more references exist. > > >Regards, >Nicodemus. > >> >> >> tALSit de CoD | talsit.org >> >> >>_______________________________________________ >>C++-sig mailing list >>C++-sig at python.org >>http://mail.python.org/mailman/listinfo/c++-sig >> >>. > > > >_______________________________________________ >C++-sig mailing list >C++-sig at python.org >http://mail.python.org/mailman/listinfo/c++-sig tALSit de CoD | talsit.org From dave at boost-consulting.com Sun Apr 27 12:21:59 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 27 Apr 2003 06:21:59 -0400 Subject: [C++-sig] Ownership question. In-Reply-To: <3EAB8000.1000909@globalite.com.br> (nicodemus@globalite.com.br's message of "Sun, 27 Apr 2003 04:00:16 -0300") References: <5.2.0.9.2.20030427145130.00b0d200@talsit.org> <3EAB8000.1000909@globalite.com.br> Message-ID: Nicodemus writes: > tALSit de CoD wrote: > >> I have a class method that takes ownership of the object passed into >> it, and I want to know, how do I let boost.python know about this >> and not to manage that object anymore? > Unfortunately, I don't think you will get a "nice" way to acomplish > this, because of how garbage collection works in Python. Not so fast! See the FAQ: http://www.boost.org/libs/python/doc/v2/faq.html#ownership always-check-the-faq-first-ly y'rs, -- Dave Abrahams Boost Consulting www.boost-consulting.com From nicodemus at globalite.com.br Sun Apr 27 18:35:18 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 27 Apr 2003 13:35:18 -0300 Subject: [C++-sig] Ownership question. In-Reply-To: References: <5.2.0.9.2.20030427145130.00b0d200@talsit.org> <3EAB8000.1000909@globalite.com.br> Message-ID: <3EAC06C6.8010907@globalite.com.br> David Abrahams wrote: >Nicodemus writes: > > >>Unfortunately, I don't think you will get a "nice" way to acomplish >>this, because of how garbage collection works in Python. >> >> > >Not so fast! See the FAQ: >http://www.boost.org/libs/python/doc/v2/faq.html#ownership > >always-check-the-faq-first-ly y'rs, > Sorry, I didn't explain very well what I meant by "nice". 8) Suppose that A is a class with a public member "int value" and a function foo, which takes the ownership of a A* passed to it. After exporting them: >>> from test import * >>> a = A() >>> a >>> a.value 0 >>> foo(a) deleting a >>> a >>> a.value Traceback (most recent call last): File "", line 1, in ? TypeError: bad argument type for built-in operation >>> a.value = 10 Traceback (most recent call last): File "", line 1, in ? TypeError: bad argument type for built-in operation >>> So you see, the object after the call is no longer valid, which is against the normal Python semantics. The caller must know that "foo" is a C++ function and that it takes the ownership of the passed object, and the user can no longer use the object. I didn't want to imply that Boost.Python couldn't export this type of function: just that the result wouldn't be "pythonic", that's all. 8) Regards, Nicodemus. From dave at boost-consulting.com Sun Apr 27 19:44:33 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 27 Apr 2003 13:44:33 -0400 Subject: [C++-sig] Ownership question. In-Reply-To: <3EAC06C6.8010907@globalite.com.br> (nicodemus@globalite.com.br's message of "Sun, 27 Apr 2003 13:35:18 -0300") References: <5.2.0.9.2.20030427145130.00b0d200@talsit.org> <3EAB8000.1000909@globalite.com.br> <3EAC06C6.8010907@globalite.com.br> Message-ID: Nicodemus writes: > Sorry, I didn't explain very well what I meant by "nice". 8) > > Suppose that A is a class with a public member "int value" and a > function foo, which takes the ownership of a A* passed to it. After > exporting them: > > >>> from test import * > >>> a = A() > >>> a > > >>> a.value > 0 > >>> foo(a) > deleting a > >>> a > > >>> a.value > Traceback (most recent call last): > File "", line 1, in ? > TypeError: bad argument type for built-in operation > >>> a.value = 10 > Traceback (most recent call last): > File "", line 1, in ? > TypeError: bad argument type for built-in operation > >>> > > So you see, the object after the call is no longer valid, It's valid; it just doesn't contain the C++ "A" object anymore. nNaturally, you deleted it! Really "not nice" would be crashing as most naive wrapping systems do. > which is against the normal Python semantics. The caller must know > that "foo" is a C++ function and that it takes the ownership of the > passed object, and the user can no longer use the object. It depends on whether you believe exceptions are bad in Python ;-) > I didn't want to imply that Boost.Python couldn't export this type > of function: just that the result wouldn't be "pythonic", that's > all. 8) It's true; single-ownership semantics are completely un-pythonic. -- Dave Abrahams Boost Consulting www.boost-consulting.com From sagarwal at cs.ucsd.edu Sun Apr 27 20:40:36 2003 From: sagarwal at cs.ucsd.edu (Sameer Agarwal) Date: Sun, 27 Apr 2003 11:40:36 -0700 Subject: [C++-sig] pointers and pyste Message-ID: Hello Boosters, thank you for a wonderful library. I am a c++ newbie trying to write a ray tracer and making it scriptable in python using boost. I have had a fair amount of success but I have a question to which the answer was not entirely clear in the documentation or the faq. I have a c++ class which stores pointers to a set of c++ objects class B { void render() } class A { list blist; void add_b(B*) { blist.push_back(B*) } void render() { //iterate over list blist // and call the render method on each object. } } which I wrapped using pyste. I also wrapped the class B using pyste. now I initialized a copy of B in python and passed it to add_b to add it to blist. so far so good. The problem starts when I call the render method in A which in turn calls the render method on each of the classes stored in blist. since I was using pyste to wrap the class, the render method being called turned out to be the one associated with the wrapped object(a subclass of B from what I can gather) and not the actual class B. This causes problems since there was some additional funkiness with the way the wrapped method was handling some references. However putting an explicit exclude statement in the pyste files to exclude the render method for class B solved the problem. Is there a problem here ? is this the standard way of doing stuff ? it seems quite cumbersome to exclude methods like this. thanks. sameer From nicodemus at globalite.com.br Sun Apr 27 21:06:33 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 27 Apr 2003 16:06:33 -0300 Subject: [C++-sig] pointers and pyste In-Reply-To: References: Message-ID: <3EAC2A39.8070307@globalite.com.br> Hi Sameer, Sameer Agarwal wrote: > class B > { > void render() > } > class A > { > list blist; > void add_b(B*) > { > blist.push_back(B*) > } > > void render() > { > //iterate over list blist > // and call the render method on each object. > } > } > > > > The problem starts when I call the render method in A which in turn > calls the render method on each of the classes stored in blist. since > I was using pyste to wrap the class, > the render method being called turned out to be the one associated > with the wrapped object(a subclass of B from what I can gather) and > not the actual class B. Pyste will only generate a wrapper for a class that has virtual methods, which is not the case of your example. I tested it and it works just fine (I had to change it a little to make it compile): #include #include struct B { void render() { std::cout << "rendering a B" << std::endl; } }; struct A { std::list blist; void add_b(B* b) { blist.push_back(b); } void render() { std::list::iterator i; for (i = blist.begin(); i != blist.end(); ++i) { (*i)->render(); } } }; In Python: >>> from test import * >>> b1 = B() >>> b2 = B() >>> a = A() >>> a.add_b(b1) >>> a.add_b(b2) >>> a.render() rendering a B rendering a B >>> B::render() is called normally inside A::render(). I suppose your example is incomplete, and you meant that B::render to be virtual. Making this change, the code still works: if B::render isn't overriden in python, the default implementation is called, as you would expect. > This causes problems since there was some additional funkiness with > the way the wrapped method was handling some references. However > putting an explicit exclude statement in the pyste files to exclude > the render method for class B solved the problem. What "funkiness" does it do? Because this should really not a problem at all: the instance of B that A receives is not *really* a B, but a derived class (assuming B::render is virtual), but that should give the same behaviour. Suppose: struct C: B {}; If add_b receives a C instance, it will still work? Perhaps if you post a real example we can nail down the problem? 8) Regards, Nicodemus. From sagarwal at cs.ucsd.edu Sun Apr 27 21:49:10 2003 From: sagarwal at cs.ucsd.edu (Sameer Agarwal) Date: Sun, 27 Apr 2003 12:49:10 -0700 Subject: [C++-sig] pointers and pyste In-Reply-To: <3EAC2A39.8070307@globalite.com.br> Message-ID: <5044932F-78E9-11D7-BEFC-0003935AB3AC@cs.ucsd.edu> hi Nicodemus, sorry about forgetting to mention that render is indeed a virtual method for B which inherits from a base class C. The funkiness I am referring to has to do with the render method accepting a reference to another object D, and the new wrapped_render method does not respect the reference and instead creates a new copy of D, which causes trouble when I inspect D as it was never gets updated by the render. I can send you the code, but it is a bit messy and spread across multiple files and would make for a messy email. thanks, sameer From nicodemus at globalite.com.br Sun Apr 27 21:53:44 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 27 Apr 2003 16:53:44 -0300 Subject: [C++-sig] pointers and pyste In-Reply-To: <5044932F-78E9-11D7-BEFC-0003935AB3AC@cs.ucsd.edu> References: <5044932F-78E9-11D7-BEFC-0003935AB3AC@cs.ucsd.edu> Message-ID: <3EAC3548.8060009@globalite.com.br> Sameer Agarwal wrote: > hi Nicodemus, > sorry about forgetting to mention that render is indeed a virtual > method for B which inherits from a base class C. > The funkiness I am referring to has to do with the render method > accepting a reference to another object D, > and the new wrapped_render method does not respect the reference and > instead creates a new copy of D, which causes trouble when I inspect D > as it was never gets updated by the render. > > I can send you the code, but it is a bit messy and spread across > multiple files and would make for a messy email. Can't you post a simplified version of the code here, that reproduces the problem? That would help a lot. 8) Regards, Nicodemus. From sagarwal at cs.ucsd.edu Sun Apr 27 22:13:10 2003 From: sagarwal at cs.ucsd.edu (Sameer Agarwal) Date: Sun, 27 Apr 2003 13:13:10 -0700 Subject: [C++-sig] pointers and pyste In-Reply-To: <3EAC3548.8060009@globalite.com.br> Message-ID: okay, here goes. The class definitions are as follows class Object{ public: virtual int intersect (Ray & r)=0; Shader * mat; }; class Ray{ public: Vec3 origin; Vec3 direction; Object * hit_object; Ray(const Vec3 & o, const Vec3 & d ); Ray(const Ray & r); void trace(Color & c, Scene & scene); }; class Scene{ public: Scene(); Scene(int m, const Color & c); void builder(); void render(); void render(int xb, int xe, int yb, int ye); void add_object(Object & o); void add_light(Light & l); void add_camera(Camera & camera); void add_image(Image & image); void add_environment(Shader & env); std::list object_list; std::list light_list; }; void Scene::add_object(Object & o) { object_list.push_back(&o); }; class Sphere: public Object { public: Vec3 position; breal radius; Sphere(const Vec3 & p, const breal & rr, Shader & mat); int intersect (Ray & r); }; The trouble starts here. void Ray :: trace(Color &c , Scene &scn ) { hit=0; if (level < scn.max_level) { std::list::iterator o; o = scn.object_list.begin(); while(o!=scn.object_list.end()) { /******************************** //troubled code int retvalue = (*o)->intersect(*this); ***********************/ o++; }; }; if(!shadow) { if (hit) (hit_object->mat)->shade(*this ,c, scn); else scn.environment->shade(*this,c,scn); } } In the above function I called the virtual method intersect for each of the objects in the list object_list and pass it a reference to the class calling the method. when I use boost to wrap the sphere class, the ray which is passed to Sphere::intersect has a different address than the one which actually calls the routine. which I am guess is because somewhere along the way instead of a reference a copy of the object is being passed. The problem is fixed if I explicitly exclude Sphere::intersect from the wrapper. I hope this makes thing clearer. thanks, sameer From dave at boost-consulting.com Mon Apr 28 00:44:43 2003 From: dave at boost-consulting.com (David Abrahams) Date: Sun, 27 Apr 2003 18:44:43 -0400 Subject: [C++-sig] pointers and pyste In-Reply-To: (Sameer Agarwal's message of "Sun, 27 Apr 2003 13:13:10 -0700") References: Message-ID: Sameer Agarwal writes: > In the above function I called the virtual method intersect for each > of the objects in the list object_list and pass it a reference to the > class calling the method. > when I use boost to wrap the sphere class, the ray which is passed to > Sphere::intersect has a different address than the one which actually > calls the routine. > which I am guess is because somewhere along the way instead of a > reference a copy of the object is being passed. Yeah, what happens is that in: call_method(self, "name", x, y, z) which is what gets invoked in the Boost.Python override of any virtual member function called name, x, y, and z are copied, even if they're references (C++ actually gives us no way to tell whether they're references or not). In order to get pass-by-reference semantics you need: call_method( self, "name", boost::ref(x), boost::ref(y), boost::ref(z) ); Pass-by-reference is not the default because it's dangerous: someone could destroy the referent while you still have a Python object alive that's referencing it. If you have the luxury of modifying your interfaces, try passing around boost::shared_ptr instead of T& or T const&. -- Dave Abrahams Boost Consulting www.boost-consulting.com From sagarwal at cs.ucsd.edu Mon Apr 28 01:05:12 2003 From: sagarwal at cs.ucsd.edu (Sameer Agarwal) Date: Sun, 27 Apr 2003 16:05:12 -0700 Subject: [C++-sig] pointers and pyste In-Reply-To: Message-ID: Hello Dave, thank you for the explanation. I spent a very long 24 hours debugging my wrappers :). now atleast I know I am not insane. I think I should be able to use modify the interfaces to use shared_ptr. thanks once again, sameer On Sunday, April 27, 2003, at 03:44 PM, David Abrahams wrote: > Sameer Agarwal writes: > >> In the above function I called the virtual method intersect for each >> of the objects in the list object_list and pass it a reference to the >> class calling the method. >> when I use boost to wrap the sphere class, the ray which is passed to >> Sphere::intersect has a different address than the one which actually >> calls the routine. >> which I am guess is because somewhere along the way instead of a >> reference a copy of the object is being passed. > > > Yeah, what happens is that in: > > call_method(self, "name", x, y, z) > > which is what gets invoked in the Boost.Python override of any virtual > member function called name, x, y, and z are copied, even if they're > references (C++ actually gives us no way to tell whether they're > references or not). In order to get pass-by-reference semantics you > need: > > call_method( > self, "name", boost::ref(x), boost::ref(y), > boost::ref(z) > ); > > Pass-by-reference is not the default because it's dangerous: someone > could destroy the referent while you still have a Python object alive > that's referencing it. If you have the luxury of modifying your > interfaces, try passing around boost::shared_ptr instead of T& or T > const&. > > -- > Dave Abrahams > Boost Consulting > www.boost-consulting.com > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From giulio.eulisse at cern.ch Mon Apr 28 11:42:01 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 28 Apr 2003 11:42:01 +0200 Subject: [C++-sig] pyste and static const members. Message-ID: <1051522923.3696.172.camel@lxcms25> The following code: --- #include class Foo { public: static const std::string foo; }; --- Using Include("string") Foo=Class("Foo","foo.h"); as pyste file generates: [...] class_< Foo >("Foo", init< >()) .def(init< const Foo & >()) .def_readwrite("foo", &Foo::foo) ; [...] Which, when compiled, gives: foo.cpp: In function `void init_module_bar()': foo.cpp:14: no matching function for call to `boost::python::class_::def_readwrite(const char[4], const std::string*)' Why is that? Do I have to wrap all the static members into getter/setter methods? Ciao, Giulio PS: Nicodemus: I'm working on the additional qtextedit infos... From jacek.generowicz at cern.ch Mon Apr 28 14:27:28 2003 From: jacek.generowicz at cern.ch (Jacek Generowicz) Date: 28 Apr 2003 14:27:28 +0200 Subject: [C++-sig] Re: SWIG: overriding virtual functions in Python. References: Message-ID: Jacek Generowicz writes: > given a C++ class > > struct foo { > virtual void one() { > cout << "This is foo::one() calling two()" << endl; > two(); > } > virtual void two() { > cout << "This is foo::two()" << endl; > } > }; > > I would like to subclass it in Python and override "two()" thus: > > class bar(foo): > def two(self): > print "This is bar.two()" > > in such a way that calling bar.one() ... > > bar().one() > > gives the result > > This is foo::one() calling two() > This is bar.two() > > rather than > > This is foo::one() calling two() > This is foo.two() > > In Boost this is achieved by doing providing a wrapper class around > the original C++ implementation, and giving it a default > implementation of the virtual function, which calls back into Python. > > Is there a way of doing it in SWIG? Replying to myself for the benefit of anyone searching archives for a solution to this problem. The keyword is "directors": http://www.swig.org/Doc1.3/Python.html#n32 In brief, for the above example a) Change %module the_module_name to %module(directors="1") the_module_name b) Add %feature("director") foo; anywhere before foo is declared. From dave at boost-consulting.com Mon Apr 28 20:52:17 2003 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 28 Apr 2003 14:52:17 -0400 Subject: [C++-sig] Re: SWIG: overriding virtual functions in Python. In-Reply-To: (Jacek Generowicz's message of "28 Apr 2003 14:27:28 +0200") References: Message-ID: Jacek Generowicz writes: >> In Boost this is achieved by doing providing a wrapper class around >> the original C++ implementation, and giving it a default >> implementation of the virtual function, which calls back into Python. >> >> Is there a way of doing it in SWIG? SWIG has to do the same thing; the only way to override a C++ virtual function is, well, to override it. Pyste can hide that fact just as well as SWIG can, though ;-) -Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com From sagarwal at cs.ucsd.edu Mon Apr 28 20:59:41 2003 From: sagarwal at cs.ucsd.edu (Sameer Agarwal) Date: Mon, 28 Apr 2003 11:59:41 -0700 Subject: [C++-sig] pyste and masking interfaces Message-ID: <9186A6BB-79AB-11D7-96C7-0003935AB3AC@cs.ucsd.edu> hi, given my recent experiments with pyste, I was wondering if it would make sense to generalize the exclude functionality in pyste. Perhaps a userdefined callback can be defined which the wrapper generator calls before deciding to wrap a function. The callback gets as input the definition or some parsed form of it to make the decision. sameer From nicodemus at globalite.com.br Mon Apr 28 22:40:19 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 28 Apr 2003 17:40:19 -0300 Subject: [C++-sig] pyste and static const members. In-Reply-To: <1051522923.3696.172.camel@lxcms25> References: <1051522923.3696.172.camel@lxcms25> Message-ID: <3EAD91B3.2030904@globalite.com.br> Giulio Eulisse wrote: >The following code: > >Why is that? Do I have to wrap all the static members into getter/setter >methods? > > No, you don't have... 8) Your example works fine for me. Are you using the latest Boost.Python CVS? The support for static data members has been added recently. >Ciao, >Giulio >PS: Nicodemus: I'm working on the additional qtextedit infos... > > Great, thanks! Regards, Nicodemus. From nicodemus at globalite.com.br Mon Apr 28 22:47:38 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Mon, 28 Apr 2003 17:47:38 -0300 Subject: [C++-sig] pyste and masking interfaces In-Reply-To: <9186A6BB-79AB-11D7-96C7-0003935AB3AC@cs.ucsd.edu> References: <9186A6BB-79AB-11D7-96C7-0003935AB3AC@cs.ucsd.edu> Message-ID: <3EAD936A.7090008@globalite.com.br> Sameer Agarwal wrote: > hi, > given my recent experiments with pyste, I was wondering if it would > make sense > to generalize the exclude functionality in pyste. Perhaps a > userdefined callback can be defined which the wrapper generator calls > before deciding to wrap a function. The callback gets as input the > definition or some parsed form of it to make the decision. Certainly... how do you think such interface should work? Should it work globally, or just local to the pyste file? For instance, let's register a callback that excludes any function whose return type is not a fundamental type (int, char, floats...): def on_function_export(function): print function.name if isinstance(function.result, FundamentalType): exclude(function) RegisterFunctionHandler(on_function_export) Is something along this lines that you think would be useful? Any thoughts? Regards, Nicodemus. From sagarwal at cs.ucsd.edu Mon Apr 28 23:26:34 2003 From: sagarwal at cs.ucsd.edu (Sameer Agarwal) Date: Mon, 28 Apr 2003 14:26:34 -0700 Subject: [C++-sig] pyste and masking interfaces In-Reply-To: <3EAD936A.7090008@globalite.com.br> Message-ID: <162B610B-79C0-11D7-96C7-0003935AB3AC@cs.ucsd.edu> Hi Nicodemus, I would think it should local to each pyste file. well I would write one function in a file , and then import the .py file into each pyste file as needed. The thing that I am looking to do is to solve my previous problem, where I would like to exclude functions, which take as input a non-const reference. Also I would like access to the properties of the class that the function belongs to, like what are its parents, and what kind of method it is.. I am sure there can be more creative uses for this kind of thing. sameer > Certainly... how do you think such interface should work? Should it > work globally, or just local to the pyste file? > > For instance, let's register a callback that excludes any function > whose return type is not a fundamental type (int, char, floats...): > > def on_function_export(function): > print function.name > if isinstance(function.result, FundamentalType): > exclude(function) > > RegisterFunctionHandler(on_function_export) > > Is something along this lines that you think would be useful? Any > thoughts? > > Regards, > Nicodemus. > > > > > > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From dominique.devriese at student.kuleuven.ac.be Tue Apr 29 21:33:40 2003 From: dominique.devriese at student.kuleuven.ac.be (Dominique Devriese) Date: 29 Apr 2003 21:33:40 +0200 Subject: [C++-sig] converting objects to python.. Message-ID: <87k7ddksiz.fsf@student.kuleuven.ac.be> Hi, I have been looking at this for some time, and I can't seem to find it. Maybe someone here can help ? (I'm using Boost.python to export the api of an app that i want to embed python in.. ( http://edu.kde.org/kig in case someone is interested ) ) I'm trying to call a python function from C++ code with some arguments. The arguments are of type "const ObjectImp*", where ObjectImp is the abstract base class of a whole lot of other types. All of them are properly wrapped, and I have tested the wrapping in different situations, and it works. The problem is that I can't seem to find how to convert a "const ObjectImp*" to a PyObject. I tried: const ObjectImp* the_object_imp_pointer; object o( the_object_imp_pointer ); use( o.ptr() ); object o2( *the_object_imp_pointer ); use( o2.ptr() ); ( and a whole lot of other things that would only make me look stupid here, so i'll omit those ;) ) In both cases, the object constructor throws an error_already_set exception, and from the debugging in boost.python internals I've done, it appears that this happens because the lib doesn't have a converter registered for the types. I thought about trying to write a converter myself, but then I thought that this would be stupid, since I wouldn't know how to do this, unless i found out how boost.python PyObject's work, and it seemed more intelligent to just ask here first ;) At one point, I also thought that the problem would be that i should first downcast the pointers to their "real" type, and try to convert that, but then I thought that would not be the case, since you're using typeid() in the conversion stuff, and that only takes into account the "real" type, not the formal type, so downcasting is not necessary.. Anyway, I'm kinda stuck on this.. Could you give me some pointers on where to look ? thanks domi -- You have been selected for a secret mission. From dave at boost-consulting.com Wed Apr 30 02:21:50 2003 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 29 Apr 2003 20:21:50 -0400 Subject: [C++-sig] converting objects to python.. In-Reply-To: <87k7ddksiz.fsf@student.kuleuven.ac.be> (Dominique Devriese's message of "29 Apr 2003 21:33:40 +0200") References: <87k7ddksiz.fsf@student.kuleuven.ac.be> Message-ID: Dominique Devriese writes: > Hi, > > I have been looking at this for some time, and I can't seem to find > it. Maybe someone here can help ? > > (I'm using Boost.python to export the api of an app that i want to > embed python in.. ( http://edu.kde.org/kig in case someone is > interested ) ) > > I'm trying to call a python function from C++ code with some > arguments. The arguments are of type "const ObjectImp*", where > ObjectImp is the abstract base class of a whole lot of other types. > All of them are properly wrapped, and I have tested the wrapping in > different situations, and it works. The problem is that I can't seem > to find how to convert a "const ObjectImp*" to a PyObject. I tried: > > const ObjectImp* the_object_imp_pointer; > object o( the_object_imp_pointer ); > use( o.ptr() ); > object o2( *the_object_imp_pointer ); > use( o2.ptr() ); > > ( and a whole lot of other things that would only make me look stupid > here, so i'll omit those ;) ) > > In both cases, the object constructor throws an error_already_set > exception What's the Python exception behind it? > and from the debugging in boost.python internals I've done, it > appears that this happens because the lib doesn't have a converter > registered for the types. > > I thought about trying to write a converter myself, but then I thought > that this would be stupid, since I wouldn't know how to do this, > unless i found out how boost.python PyObject's work, and it seemed > more intelligent to just ask here first ;) > > At one point, I also thought that the problem would be that i should > first downcast the pointers to their "real" type, and try to convert > that, but then I thought that would not be the case, since you're > using typeid() in the conversion stuff, and that only takes into > account the "real" type, not the formal type, so downcasting is not > necessary.. > > Anyway, I'm kinda stuck on this.. Could you give me some pointers on > where to look ? http://www.boost.org/libs/python/doc/v2/ptr.html Consider: object o( ptr(the_object_imp_pointer) ); Equivalent to: object o( ref(*the_object_imp_pointer) ); But beware dangling reference in Python. object o( *the_object_imp_pointer ); is safer, but incurs a copy (and slicing) of your base class. Using boost::shared_ptr instead of raw pointers works best of all if it's an option. -- Dave Abrahams Boost Consulting www.boost-consulting.com From giulio.eulisse at cern.ch Wed Apr 30 09:33:08 2003 From: giulio.eulisse at cern.ch (Giulio Eulisse) Date: 30 Apr 2003 09:33:08 +0200 Subject: [C++-sig] pyste and static const members. In-Reply-To: <3EAD91B3.2030904@globalite.com.br> References: <1051522923.3696.172.camel@lxcms25> <3EAD91B3.2030904@globalite.com.br> Message-ID: <1051687989.8482.10.camel@lxcms25> > Your example works fine for me. > Are you using the latest Boost.Python CVS? The support for static data > members has been added recently. mmm...I run pyste out of CVS, but I don't think my supervisors would be happy about using the whole boost_python out of CVS... I think I will have to mark the problem as *fix later*...Is there, by chance, any timeframe for next boost/boost_python release? Ciao, Giulio From nicodemus at globalite.com.br Wed Apr 30 19:05:52 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Wed, 30 Apr 2003 14:05:52 -0300 Subject: [C++-sig] pyste and static const members. In-Reply-To: <1051687989.8482.10.camel@lxcms25> References: <1051522923.3696.172.camel@lxcms25> <3EAD91B3.2030904@globalite.com.br> <1051687989.8482.10.camel@lxcms25> Message-ID: <3EB00270.6030904@globalite.com.br> Giulio Eulisse wrote: >>Your example works fine for me. >>Are you using the latest Boost.Python CVS? The support for static data >>members has been added recently. >> >> > >mmm...I run pyste out of CVS, but I don't think my supervisors would be >happy about using the whole boost_python out of CVS... I think I will >have to mark the problem as *fix later*... > If you're willing to patch your copy and keep the patch after each update, take a look at the differences between revisions 1.15 and 1.16 of ClassExporter.py (method ExportVariables). Before this new support for static data members, Pyste supported *const* static data members by declaring them into the class scope, giving the same effect. Perhaps that's enough for your needs. Regards, Nicodemus. From dominique.devriese at student.kuleuven.ac.be Wed Apr 30 19:20:19 2003 From: dominique.devriese at student.kuleuven.ac.be (Dominique Devriese) Date: 30 Apr 2003 19:20:19 +0200 Subject: [C++-sig] converting objects to python.. In-Reply-To: References: <87k7ddksiz.fsf@student.kuleuven.ac.be> Message-ID: <873cjzlx64.fsf@student.kuleuven.ac.be> David Abrahams writes: David> Dominique Devriese David> writes: >> Hi, >> >> I have been looking at this for some time, and I can't seem to >> find it. Maybe someone here can help ? >> >> (I'm using Boost.python to export the api of an app that i want >> to embed python in.. ( http://edu.kde.org/kig in case someone is >> interested ) ) >> >> I'm trying to call a python function from C++ code with some >> arguments. The arguments are of type "const ObjectImp*", where >> ObjectImp is the abstract base class of a whole lot of other >> types. All of them are properly wrapped, and I have tested the >> wrapping in different situations, and it works. The problem is >> that I can't seem to find how to convert a "const ObjectImp*" to >> a PyObject. I tried: >> >> const ObjectImp* the_object_imp_pointer; object o( >> the_object_imp_pointer ); use( o.ptr() ); object o2( >> *the_object_imp_pointer ); use( o2.ptr() ); >> >> ( and a whole lot of other things that would only make me look >> stupid here, so i'll omit those ;) ) >> >> In both cases, the object constructor throws an error_already_set >> exception David> What's the Python exception behind it? No idea, any idea where i can find this ? >> and from the debugging in boost.python internals I've done, it >> appears that this happens because the lib doesn't have a >> converter registered for the types. >> >> I thought about trying to write a converter myself, but then I >> thought that this would be stupid, since I wouldn't know how to >> do this, unless i found out how boost.python PyObject's work, and >> it seemed more intelligent to just ask here first ;) >> >> At one point, I also thought that the problem would be that i >> should first downcast the pointers to their "real" type, and try >> to convert that, but then I thought that would not be the case, >> since you're using typeid() in the conversion stuff, and that >> only takes into account the "real" type, not the formal type, so >> downcasting is not necessary.. >> >> Anyway, I'm kinda stuck on this.. Could you give me some >> pointers on where to look ? David> http://www.boost.org/libs/python/doc/v2/ptr.html David> Consider: David> object o( ptr(the_object_imp_pointer) ); David> Equivalent to: David> object o( ref(*the_object_imp_pointer) ); David> But beware dangling reference in Python. David> object o( *the_object_imp_pointer ); David> is safer, but incurs a copy (and slicing) of your base class. David> Using boost::shared_ptr instead of raw pointers works best of David> all if it's an option. great, thanks for the information.. cheers domi -- Q: What do you call a principal female opera singer whose high C is lower than those of other principal female opera singers? A: A deep C diva. From Paul_Kunz at SLAC.Stanford.EDU Wed Apr 30 22:40:53 2003 From: Paul_Kunz at SLAC.Stanford.EDU (Paul F. Kunz) Date: Wed, 30 Apr 2003 13:40:53 -0700 Subject: [C++-sig] boost.python project files for vs.net Message-ID: <200304302040.h3UKerO29324@libra3.slac.stanford.edu> In case anybody is interested, enclosed are project files to build Boost.Python with Visual Studio .NET. I had trouble with bjam, so I use vs.net. It converted the project files for MSVC 6 to these. I fixed the path to Python in them. The boost_python.sln file... -- Microsoft Visual Studio Solution File, Format Version 7.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boost_python", "boost_python.vcproj", "{E858B6C2-7DB3-4AC0-B9DB-90377118B100}" EndProject Global GlobalSection(SolutionConfiguration) = preSolution ConfigName.0 = Debug ConfigName.1 = Release EndGlobalSection GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {E858B6C2-7DB3-4AC0-B9DB-90377118B100}.Debug.ActiveCfg = Debug|Win32 {E858B6C2-7DB3-4AC0-B9DB-90377118B100}.Debug.Build.0 = Debug|Win32 {E858B6C2-7DB3-4AC0-B9DB-90377118B100}.Release.ActiveCfg = Release|Win32 {E858B6C2-7DB3-4AC0-B9DB-90377118B100}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal --- The boost_python.vcproj file ... --- From nicodemus at globalite.com.br Sun Apr 27 00:15:15 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 26 Apr 2003 19:15:15 -0300 Subject: [C++-sig] Re: register_ptr_to_python docs and test In-Reply-To: References: <3EF8C9C9.3080502@globalite.com.br> <3EF90233.1040406@globalite.com.br> Message-ID: <3EAB04F3.20909@globalite.com.br> David Abrahams wrote: >That sounds great. I think we're almost there. Thanks for your work! > My pleasure! Here is a new version, with the latest changes. I think that it is now good enough to commit. Regards, Nicodemus. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: register_ptr.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: register_ptr_test.py URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: register_ptr_to_python.hpp URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: From nicodemus at globalite.com.br Sun Apr 27 00:40:16 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sat, 26 Apr 2003 19:40:16 -0300 Subject: [C++-sig] [newbie] Pyste overloaded member function problems In-Reply-To: <200306252335.RAA16836@ia.nsc.com> References: <200306252335.RAA16836@ia.nsc.com> Message-ID: <3EAB0AD0.40504@globalite.com.br> Hi Sengan, Sengan.Baring-Gould at nsc.com wrote: >Hi, > >I am using pyste and boost 1.30.0 to wrap a C++ class which has the following >overloaded member functions: > > I recommend that you use the latest CVS version, there has been *lots* of bug fixes and some features since boost 1.30.0 came out. >class Parser { > >... > >typedef unsigned char CFormatFlags; >const string& Get( string, string, const string&, const CFormatFlags in_flags = DEFAULT_FORMATTING ) const; >long Get( string, string, const long ) const; >int Get( string, string, const int ) const; >const string& Get( string, const string&, const CFormatFlags in_flags = DEFAULT_FORMATTING ) const; >long Get( string, const long ) const; >int Get( string, const int ) const; > >... > >}; > >In order to prevent Python from converting Get( string, string, const long ) >into const string& Get( string, const string&, CFormatFlags ) I have to hack >the generated file to remove all but the first 2 def() statements corresponding >to the first 2 Gets. >1/ Is there a more elegant method to solve this problem? >2/ Is there a way to tell pyste to exclude particular overloaded member > functions? >3/ Is there a way to specify a policy in pyste dependent on the overloaded > member function: I have > set_policy(CSettingsParser.Get, return_value_policy(copy_const_reference)) > but then I have to remove that for the long Get(string, string. long) case > from the generated file. > > Unfortunately, no. 8/ But I will implement in the next days support for meta-programming inside the pyste scripts, allowing you to do something like this: C = Class(...) for func in C.Get: if func._parameters[2].name == 'CFormatFlags': exclude(func) >Secondly, this class has member functions: > >class Parser { >... >typedef list CNameList; >CNameList List( void ) const; >CNameList List( const string section_name ) const; >... }; > > >In order to get a python list from this I wrote 2 wrapper functions. >However, I can't figure out how to get pyste to use the set_wrapper() functions to use the wrappers. So again I hacked the generated file. >4/ Is there some other way to do this without hacking the generated file? > > This problem is related to the last one too, ie, the inability to choose between functions with the same name. >I would like to congratulate the authors of pyste and boost python. Having >dipped my foot in the water by writing an extension module for >std::list/std::list, I can see this package really reduces the >amount of code one needs to write. > > Thanks a lot! 8) >Thanks, > >Sengan > > Regards, Nicodemus. From nicodemus at globalite.com.br Sun Apr 27 20:35:17 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 27 Apr 2003 15:35:17 -0300 Subject: [C++-sig] Re: register_ptr_to_python docs and test In-Reply-To: <3EFBFC95.1000202@cenix-bioscience.com> References: <3EF8C9C9.3080502@globalite.com.br> <3EF90233.1040406@globalite.com.br> <3EAB04F3.20909@globalite.com.br> <3EFBFC95.1000202@cenix-bioscience.com> Message-ID: <3EAC22E5.9080501@globalite.com.br> Hi Oliver, F. Oliver Gathmann wrote: > gcc 3.2.2 on Linux only stopped complaining after I inserted a > "typename" directive as shown: Thanks for the remainder! I just commited to CVS. Regards, Nicodemus. From nicodemus at globalite.com.br Sun Apr 27 20:42:34 2003 From: nicodemus at globalite.com.br (Nicodemus) Date: Sun, 27 Apr 2003 15:42:34 -0300 Subject: [C++-sig] Simply calling a routine ... In-Reply-To: <3EFC15EF.2070304@novagrid.com> References: <3EF9CAF4.80208@cenix-bioscience.com> <3EFAE527.3040301@cenix-bioscience.com> <3EFC15EF.2070304@novagrid.com> Message-ID: <3EAC249A.30605@globalite.com.br> christophe grimault wrote: > Hi all, > > I have a written several routines in C++ using blitz++. These > routines are called sucessively by the 'main' routine. I want to > rewrite the main in python in order to gain development speed and > flexibility. The routines use blitz++ matrix template library > but the interfaces to the routine are very common C++ calls with > basic C++ types (int, float*, short*, etc...) : > > int foo( short* a, float b, float* c, int N ){ > Array A(N); > A.data() = a; > > // Do some work > > > return ( ERROR_CODE ); > } > > Is it straightforward to declare these routines with pyste > (or the classic boost method). Does the use of blitz in these > routines (which belong to another file than the main, beginning > with include of blitz.hh) complicates the process. I'm a bit lost > because of the use of "templates in blitz++" versus "integration with > boost". What problems are you having exactly? And I don't know how you would pass the parameters to this function, except if you create the arrays in C++ too. If you don't care about reading the array values in Python, you can treat them as opaque pointers... check return_opaque_pointer: http://www.boost.org/libs/python/doc/v2/return_opaque_pointer.html > Also, as you can see in the example routine above, I started with > a creation of a blitz array 'A' from the array 'a'. Because I'm > afraid of the work to get back and forth from Numeric array in Python > to Blitz++ templated Array in C++ is a complicated and big amount > of work. Perhaps, but I don't believe it would be such a pain... you can create simple wrappers that would do the job nicely; If there is a lot of functions, then perhaps you could even implement to-python and from-python conversions for Numeric arrays, as demonstrated here (for C++ standard containers): http://www.boost.org/libs/python/doc/v2/faq.html#question2 > Thanks for any response on these to points, and for any suggestion or > criticism on my way of handling the problem. > Christophe Grimault Hope that helps! Regards, Nicodemus.