From tj_summers at naughtydog.com Wed Feb 1 00:10:37 2006 From: tj_summers at naughtydog.com (TJ Summers) Date: Tue, 31 Jan 2006 15:10:37 -0800 Subject: [C++-sig] Opportunities at Naughty Dog... Message-ID: <005901c626bb$8d1f0cc0$6401a8c0@DAMLT1> Hello Hamilton- My name is T.J. Summers and I am the recruiter at Naughty Dog in Santa Monica, CA. Naughty Dog is owned by Sony Computer Entertainment of America and is developer of the Jak and Daxter franchise. The reason for my email is that I want to ask if you might be interested in hearing about job opportunities at Naughty Dog. We are actively hiring talented programmer/engineers as we are currently ramping up on our new Playstation 3 game and engine development teams. I have listed the top priority positions at Naughty Dog. * Senior Tools Programmer for GAME team and ENGINE team * Senior Renderer Programmer for GAME team * Senior Game Programmers (either Senior Renderer Programmers, Assembler Programmers, or Generalists for ENGINE development) * Gameplay Programmers * Senior Audio Programmer Please let me know when we can schedule a time to discuss. Regards, T.J. Summers Naughty Dog 1601 Cloverfield Blvd. Suite 6000 North Santa Monica, CA 90404 www.naughtydog.com Phone: 310-633-9275 mailto:tj_summers at naughtydog.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndbecker2 at gmail.com Wed Feb 1 04:07:25 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Tue, 31 Jan 2006 22:07:25 -0500 Subject: [C++-sig] variable # args? Message-ID: How do I create a function in c++ that appears to python as a function taking a variable #args? What I'm doing now is like: F (object& o) { int size = extract (o.attr ("__len__")()); for (int i = 0; i < size; ++i) { const out_t& v = extract (o[i]); ... This works for passing a single object that is a sequence, e.g., tuple: F ((a,b,c)) But what I really want is F (a,b,c) From roman.yakovenko at gmail.com Wed Feb 1 06:09:09 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 1 Feb 2006 07:09:09 +0200 Subject: [C++-sig] pyplusplus tutorials & GUI wizard In-Reply-To: References: <7465b6170601232249u7ca7741ncf71a6973fc12c45@mail.gmail.com> <7465b6170601252149i3c597589t15d686f027567ab8@mail.gmail.com> <7465b6170601290507m3c2cc0edied458d60932dfa04@mail.gmail.com> <7465b6170601300808o7c99bd6cgf936f22fb40ed6b6@mail.gmail.com> <7465b6170601302132o26dbdaa6x6c6e412764ac2509@mail.gmail.com> Message-ID: <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> On 1/31/06, Matthias Baas wrote: > >> Anyway, I'll continue my test and move on to the more complex classes > >> that needed some manual intervention using Pyste.... > > The next class I've added to the module has two methods that require a > call policy. The methods just return a reference to its instance, so I > want to specify the 'return_self' policy. How do I do that? (I've had a > short glimpse at those examples you mentioned two mails ago, but didn't > really spot a place where a policy was assigned) You have 2 choices: 1. To create "callable" object that for a given declaration will return call policies. For example py_easybmp uses this technique. See: http://tinyurl.com/crjzf In this case you also need to switch from module_creator.create function to using class module_creator.creator_t. EasyBMP example will help you. 2. After you created extension module tree you can find relevant code creator and then set call policies. The relevant code for find functionality you can find in pygccxml/declarations/algorithm.py and pyplusplus/code_creators/algorithm.py 2.1 You also can iterate on all code creators: creators = code_creators.make_flatten( extmodule ) fmfunctions = filter( lambda creator: isinstance( creator, code_creators.function_t ) , creators ) for creator in fmfunctions: if not creator.call_policies: print 'missing call policies: ', declarations.full_name( creator.declaration ) print ' function will not be exported' creator.parent.remove_creator( creator ) As for me the first way is better then other. It does not degrade performance. Also 2.1 it useful to remove function with missing call policies, and thus to see result much faster. Small hint: If the SDK you are wrapping has code convention, than you can reuse it. For example if all classes has method "clone" that returns raw pointer to new object, then you can set call policies base on function name only. An other small hint: pygccxml has type_traits. The idea is similar as in boost.type_traits. You can analyze the return type of function, and only then to decide what call policies you will set. > Then there's another class that has a private destructor. This class > only has static methods and is not meant to be instantiated. So for the > wrappers I'd like to add the 'noncopyable' and 'no_init' specifiers. > Does pyplusplus allow that? pyplusplus does not allows this right now. The main reason for this is: pyplusplus checks whether class has private constructor (fixed yesterday) or does not have accessible copy constructor and generates right code. I forgot about public destructor. I will fix it. If you still need to control those properties just say it. > Now I also noticed another thing that'll get more serious the more > classes I wrap. Whenever I create the source code for the bindings > (using the multiple_files feature) *all* files are recreated, even when > the actual contents is the same than before. When I then compile the > module (using distutils) *every* file is recompiled which will take > quite some time once I've wrapped the entire SDK (which has about 300 > classes). Is there a way to tell pyplusplus to only generate a source > file when the contents will be different from a previous run? I will fix this. > - Matthias - > I will post to the list when fixes are ready. Thanks Roman Yakovenko From roman.yakovenko at gmail.com Wed Feb 1 09:14:46 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 1 Feb 2006 10:14:46 +0200 Subject: [C++-sig] pyplusplus tutorials & GUI wizard In-Reply-To: <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> References: <7465b6170601232249u7ca7741ncf71a6973fc12c45@mail.gmail.com> <7465b6170601252149i3c597589t15d686f027567ab8@mail.gmail.com> <7465b6170601290507m3c2cc0edied458d60932dfa04@mail.gmail.com> <7465b6170601300808o7c99bd6cgf936f22fb40ed6b6@mail.gmail.com> <7465b6170601302132o26dbdaa6x6c6e412764ac2509@mail.gmail.com> <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> Message-ID: <7465b6170602010014m546da17y7e5bd7653b7dd288@mail.gmail.com> On 2/1/06, Roman Yakovenko wrote: > > Then there's another class that has a private destructor. This class > > only has static methods and is not meant to be instantiated. So for the > > wrappers I'd like to add the 'noncopyable' and 'no_init' specifiers. > > Does pyplusplus allow that? > > pyplusplus does not allows this right now. The main reason for this is: > pyplusplus checks whether class has private constructor (fixed yesterday) > or does not have accessible copy constructor and generates right code. > > I forgot about public destructor. I will fix it. If you still need to > control those properties > just say it. Fixed. > > Now I also noticed another thing that'll get more serious the more > > classes I wrap. Whenever I create the source code for the bindings > > (using the multiple_files feature) *all* files are recreated, even when > > the actual contents is the same than before. When I then compile the > > module (using distutils) *every* file is recompiled which will take > > quite some time once I've wrapped the entire SDK (which has about 300 > > classes). Is there a way to tell pyplusplus to only generate a source > > file when the contents will be different from a previous run? > > I will fix this. Fixed. This bug was so silly, I don't know what I thought that moment. Thanks for reporting those bugs. You need to take CVS version. Roman Yakovenko. From baas at ira.uka.de Wed Feb 1 18:24:05 2006 From: baas at ira.uka.de (Matthias Baas) Date: Wed, 01 Feb 2006 18:24:05 +0100 Subject: [C++-sig] pyplusplus tutorials & GUI wizard In-Reply-To: <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> References: <7465b6170601232249u7ca7741ncf71a6973fc12c45@mail.gmail.com> <7465b6170601252149i3c597589t15d686f027567ab8@mail.gmail.com> <7465b6170601290507m3c2cc0edied458d60932dfa04@mail.gmail.com> <7465b6170601300808o7c99bd6cgf936f22fb40ed6b6@mail.gmail.com> <7465b6170601302132o26dbdaa6x6c6e412764ac2509@mail.gmail.com> <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> Message-ID: Roman Yakovenko wrote: [setting call policies] > You have 2 choices: > [...] As you recommended the first option I took the code from EasyBMP and modified it accordingly, so this is working now. > Small hint: If the SDK you are wrapping has code convention, than you > can reuse it. > [...] In the above case, this was not the case, but I'll keep it in mind. >> Then there's another class that has a private destructor. This class >> only has static methods and is not meant to be instantiated. So for the >> wrappers I'd like to add the 'noncopyable' and 'no_init' specifiers. >> Does pyplusplus allow that? > > pyplusplus does not allows this right now. The main reason for this is: > pyplusplus checks whether class has private constructor (fixed yesterday) > or does not have accessible copy constructor and generates right code. > > I forgot about public destructor. I will fix it. If you still need to > control those properties just say it. Thanks for fixing that. With the latest cvs, the noncopyable and no_init specifiers are added, but on Linux (using gcc) it still doesn't compile because of the *_wrapper class which is derived from the original class. I still get an error message that the destructor is private. I suppose in this case, such a *_wrapper class wouldn't be required anyway and the original class could be wrapped directly. Can I somehow suppress the creation of such wrapper classes? By the way, on Windows (using VC7.1) the code compiles without problems....?! >> Now I also noticed another thing that'll get more serious the more >> classes I wrap. Whenever I create the source code for the bindings >> (using the multiple_files feature) *all* files are recreated, even when >> the actual contents is the same than before. When I then compile the >> module (using distutils) *every* file is recompiled which will take >> quite some time once I've wrapped the entire SDK (which has about 300 >> classes). Is there a way to tell pyplusplus to only generate a source >> file when the contents will be different from a previous run? > > I will fix this. Basically, it works, but there is still a problem. Whenever I add a new class there's a new header file that gets included into *all* files automatically which wouldn't be necessary. So the files still change and get recompiled. I don't know how pyplusplus determines the files that it'll include in the output but I hope that there's a way to include only those header files that are really required. (Just out of curiosity, how do you determine whether a file has to be written or not, do you really compare the contents of the existing file with the data you're about to write?) By the way, after the cvs update I got a new warning from gcc. The compiler complains that the last line in the generated source files doesn't have a newline. Then there's a new thing that came up. Pyplusplus also adds protected methods to the generated wrappers which breaks compilation for me. How can I disable that feature? I thought I could just filter them out, but then I noticed something else that I don't understand. I already have my user defined filter function that filters out everything but my desired classes. The function basically looks like this: def filter(decl): return decl.name in [......] But now that I come to think about it, I don't understand why this works at all. I noticed that the filter function is also applied to class methods in which case the function returns False. But why are the methods then exposed? (I thought this would be a way to filter out the protected methods, but obviously this is not how it's supposed to work...) - Matthias - From vladimir at inktomi.com Wed Feb 1 05:37:38 2006 From: vladimir at inktomi.com (Vladimir Ofitserov) Date: Tue, 31 Jan 2006 20:37:38 -0800 Subject: [C++-sig] How to create instance using existing C++ object Message-ID: Let say I have a C++ function that gets instance of noncopyable object (CDoc for example) and I want to implement this function in python module, wrapping CDoc class using Boost.Python: void MyFunction( CDoc *pDoc ) { // want a wrapper that is just a pointer/reference/shared_ptr class_ cdoc( "CDoc", noinit ); cdoc.def(...); cdoc.def(...); // now how do I create instance of "cdoc" around pDoc // using cdoc::operator()? object odoc = cdoc( *pDoc ); // calling python module with new object instance call_method( pymodule, "myfunction", odoc ); } The main problem is that I could not find any documentation on how to create python wrapper around existing object. Only thing I've seen is Python Wiki FAQ article that has correct problem statement but *incorrect* answer: http://wiki.python.org/moin/boost.python/FAQ ------------------------------------------- Is it is possible to convert pointers to existing classes to PyObjects* and then be able to pass an existing instance of an object directly to and from python? It is. Example: In C++ I create a CWheel and I set its member m_diameter to 1233. In python I have a function that receives a CWheel and displays the diameter (Let's suppose that Python knows the CWheel from Boost.Python): def printCWheelDiam(awheel): print awheel.m_diameter The safest thing to do is to create the CWheel by invoking its class wrapper: // Declare the CWheel extension class object wheel_class = class_("CWheel") .def_readonly("m_diameter", &CWheel::m_diameter) .def("some_member_function", &CWheel::some_member_function) ... ; object wheel_obj = wheel_class(); // construct one Now you can pass wheel_obj back to python, and all reference counts are nicely managed. You don't need to "map" anything between C++ and Python; the library takes care of that for you. If you really want to pass pointers around, it's certainly possible to tell the library to build a Python object around the pointer, but then you need to make sure the lifetime of the C++ object being referenced by the pointer extends past the lifetime of all Python references to the object or your program will crash. -------------------------------------------------------------------------------------- This answer above is no way match to the question because there is *new* object created (wheel_obj) using default constructor and it no way an *existing* object as was asked in the question. The last paragraph says exactly what I want but it only mentions that "it's certainly possible to tell the library to build a Python object around pointer" but I must be really stupid because I just can figure out how :-) Thanks for help, -vladimir From dave at boost-consulting.com Wed Feb 1 22:40:50 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 01 Feb 2006 16:40:50 -0500 Subject: [C++-sig] How to create instance using existing C++ object References: Message-ID: Vladimir Ofitserov writes: > Let say I have a C++ function that gets instance of noncopyable object > (CDoc for example) and I want to implement this function in python > module, wrapping CDoc class using Boost.Python: > > void MyFunction( CDoc *pDoc ) { > > // want a wrapper that is just a pointer/reference/shared_ptr > class_ cdoc( "CDoc", noinit ); ^ !! What is that supposed to be? The library definitely does not expect a reference type here! > cdoc.def(...); > cdoc.def(...); > > // now how do I create instance of "cdoc" around pDoc > // using cdoc::operator()? > object odoc = cdoc( *pDoc ); > > // calling python module with new object instance > call_method( pymodule, "myfunction", odoc ); > } You've left out a *lot* of information! E.g., what is cdoc::operator()? But anyway... > The main problem is that I could not find any documentation on how to > create python wrapper around existing object. Only thing I've seen is > Python Wiki FAQ article that has correct problem statement but > *incorrect* answer: > > http://wiki.python.org/moin/boost.python/FAQ You might try this: namespace python = boost::python; python::object identity(python::object o) { return o; } python::object py_id(identity); python::object py_cdoc_instance = py_id(boost::ref(some_cpp_cdoc_instance)); // Warning: if some_cpp_cdoc_instance is destroyed before // py_cdoc_instance, crashses may ensue! -- Dave Abrahams Boost Consulting www.boost-consulting.com From dave at boost-consulting.com Wed Feb 1 22:44:25 2006 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 01 Feb 2006 16:44:25 -0500 Subject: [C++-sig] variable # args? References: Message-ID: Neal Becker writes: > How do I create a function in c++ that appears to python as a function > taking a variable #args? > > What I'm doing now is like: > > F (object& o) { > int size = extract (o.attr ("__len__")()); > > for (int i = 0; i < size; ++i) { > const out_t& v = extract (o[i]); > ... > > This works for passing a single object that is a sequence, e.g., tuple: > > F ((a,b,c)) > > But what I really want is > > F (a,b,c) Sounds like you're looking for: http://www.boost.org/libs/python/doc/v2/raw_function.html -- Dave Abrahams Boost Consulting www.boost-consulting.com From ndbecker2 at gmail.com Thu Feb 2 00:34:57 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 01 Feb 2006 18:34:57 -0500 Subject: [C++-sig] variable # args? References: Message-ID: David Abrahams wrote: > Neal Becker writes: > >> How do I create a function in c++ that appears to python as a function >> taking a variable #args? >> >> What I'm doing now is like: >> >> F (object& o) { >> int size = extract (o.attr ("__len__")()); >> >> for (int i = 0; i < size; ++i) { >> const out_t& v = extract (o[i]); >> ... >> >> This works for passing a single object that is a sequence, e.g., tuple: >> >> F ((a,b,c)) >> >> But what I really want is >> >> F (a,b,c) > > Sounds like you're looking for: > > http://www.boost.org/libs/python/doc/v2/raw_function.html > Excellent. Now, can this be used with make_constructor? e.g.: .def("__init__", make_constructor(raw_function (F))) Doesn't seem to work: /usr/include/nb/boost/python/make_constructor.hpp:230: error: no matching function for call to 'get_signature(boost::python::api::object&)' From roman.yakovenko at gmail.com Thu Feb 2 06:59:11 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 2 Feb 2006 07:59:11 +0200 Subject: [C++-sig] pyplusplus tutorials & GUI wizard In-Reply-To: References: <7465b6170601232249u7ca7741ncf71a6973fc12c45@mail.gmail.com> <7465b6170601290507m3c2cc0edied458d60932dfa04@mail.gmail.com> <7465b6170601300808o7c99bd6cgf936f22fb40ed6b6@mail.gmail.com> <7465b6170601302132o26dbdaa6x6c6e412764ac2509@mail.gmail.com> <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> Message-ID: <7465b6170602012159h5f78b334s9238f6f30f842371@mail.gmail.com> On 2/1/06, Matthias Baas wrote: > Thanks for fixing that. With the latest cvs, the noncopyable and no_init > specifiers are added, but on Linux (using gcc) it still doesn't compile > because of the *_wrapper class which is derived from the original class. > I still get an error message that the destructor is private. I suppose > in this case, such a *_wrapper class wouldn't be required anyway and the > original class could be wrapped directly. Can I somehow suppress the > creation of such wrapper classes? > By the way, on Windows (using VC7.1) the code compiles without > problems....?! I did not test my changes with GCC. I will test them. As a temporal solution you can remove the wrapper code creator. Try to use finalize method on class code creator. > >> Now I also noticed another thing that'll get more serious the more > >> classes I wrap. Whenever I create the source code for the bindings > >> (using the multiple_files feature) *all* files are recreated, even when > >> the actual contents is the same than before. When I then compile the > >> module (using distutils) *every* file is recompiled which will take > >> quite some time once I've wrapped the entire SDK (which has about 300 > >> classes). Is there a way to tell pyplusplus to only generate a source > >> file when the contents will be different from a previous run? > > > > I will fix this. > > Basically, it works, but there is still a problem. Whenever I add a new > class there's a new header file that gets included into *all* files > automatically which wouldn't be necessary. So the files still change and > get recompiled. I don't know how pyplusplus determines the files that > it'll include in the output but I hope that there's a way to include > only those header files that are really required. The problem is that I ( pyplusplus ) can not build set of required files. Consider next case: file a.h class A{}; file b.h #include "a.h" class B{}; You want to export A and B. pyplusplus will generate include to a.h and b.h. While writing those lines I think that I found solution, but requires modification of pygccxml. I am not going to implement this for next release, but still pyplusplus provide nice way to solve this situation. TnFOX has one header that include all other header files. Before generating code, we modify extension module. We remove all includes for TnFOX and replace them with include to main header. Here is relevant code: #extmodule defined somewhere includes = filter( lambda creator: isinstance( creator, code_creators.include_t ) , extmodule.creators ) includes = includes[2:] #all includes except boost\python.hpp and __array_1.pypp.hpp map( lambda creator: extmodule.remove_creator( creator ), includes ) extmodule.adopt_include( code_creators.include_t( header="fx.h" ) ) > (Just out of curiosity, how do you determine whether a file has to be > written or not, do you really compare the contents of the existing file > with the data you're about to write?) Yes, this is the only way, that I know, that does it reliably. Don't warry about performance. It takes only 90 - 100 second to create\generate Boost.Python bindings for TnFOX, 625 files. > By the way, after the cvs update I got a new warning from gcc. The > compiler complains that the last line in the generated source files > doesn't have a newline. Next time before I do check in I will check it first on Linux. Sorry for inconvinince. :-( > Then there's a new thing that came up. Pyplusplus also adds protected > methods to the generated wrappers which breaks compilation for me. How > can I disable that feature? Right now there is no way to disable it. Could you send me simple test case that breaks your compilation. I tested this behaviour and it works fine. Also if I fix this bug, do you still need to be able to disable this feature? > I thought I could just filter them out, but then I noticed something > else that I don't understand. I already have my user defined filter > function that filters out everything but my desired classes. The > function basically looks like this: > > def filter(decl): > return decl.name in [......] > > But now that I come to think about it, I don't understand why this works > at all. I noticed that the filter function is also applied to class > methods in which case the function returns False. But why are the > methods then exposed? (I thought this would be a way to filter out the > protected methods, but obviously this is not how it's supposed to work...) You found a bug. Thanks. I will fix it. > - Matthias - Thanks for bug reporting Roman Yakovenko From meine at kogs1.informatik.uni-hamburg.de Thu Feb 2 12:57:38 2006 From: meine at kogs1.informatik.uni-hamburg.de (Hans Meine) Date: Thu, 2 Feb 2006 12:57:38 +0100 Subject: [C++-sig] variable # args? In-Reply-To: References: Message-ID: <200602021257.38706.meine@kogs.informatik.uni-hamburg.de> On Thursday 02 February 2006 00:34, Neal Becker wrote: > David Abrahams wrote: > > Sounds like you're looking for: > > > > http://www.boost.org/libs/python/doc/v2/raw_function.html > > Excellent. > > Now, can this be used with make_constructor? e.g.: > .def("__init__", make_constructor(raw_function (F))) > > Doesn't seem to work: > /usr/include/nb/boost/python/make_constructor.hpp:230: > error: no matching function for call to > 'get_signature(boost::python::api::object&)' No, that does not work. (Both functions wrap a C++ function into a callable object, so they can't work together.) Have a look at my "Raw constructor (i.e. combination of make_constructor and raw_function)" thread (I say "my .. thread" because it was mostly me discussing with myself ;-p) in the archives, where I finally posted a solution. -- Ciao, / / /--/ / / ANS From ndbecker2 at gmail.com Thu Feb 2 13:25:15 2006 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 02 Feb 2006 07:25:15 -0500 Subject: [C++-sig] variable # args? References: <200602021257.38706.meine@kogs.informatik.uni-hamburg.de> Message-ID: Hans Meine wrote: > On Thursday 02 February 2006 00:34, Neal Becker wrote: >> David Abrahams wrote: >> > Sounds like you're looking for: >> > >> > http://www.boost.org/libs/python/doc/v2/raw_function.html >> >> Excellent. >> >> Now, can this be used with make_constructor? e.g.: >> .def("__init__", make_constructor(raw_function (F))) >> >> Doesn't seem to work: >> /usr/include/nb/boost/python/make_constructor.hpp:230: >> error: no matching function for call to >> 'get_signature(boost::python::api::object&)' > > No, that does not work. (Both functions wrap a C++ function into a > callable object, so they can't work together.) > > Have a look at my "Raw constructor (i.e. combination of make_constructor > and raw_function)" thread (I say "my .. thread" because it was mostly me > discussing with myself ;-p) in the archives, where I finally posted a > solution. > Hey thanks! Just what I needed. Can we please add this to boost::python? From dave at boost-consulting.com Thu Feb 2 15:59:52 2006 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 02 Feb 2006 09:59:52 -0500 Subject: [C++-sig] variable # args? References: <200602021257.38706.meine@kogs.informatik.uni-hamburg.de> Message-ID: Neal Becker writes: > Hans Meine wrote: > >> On Thursday 02 February 2006 00:34, Neal Becker wrote: >>> David Abrahams wrote: >>> > Sounds like you're looking for: >>> > >>> > http://www.boost.org/libs/python/doc/v2/raw_function.html >>> >>> Excellent. >>> >>> Now, can this be used with make_constructor? e.g.: >>> .def("__init__", make_constructor(raw_function (F))) >>> >>> Doesn't seem to work: >>> /usr/include/nb/boost/python/make_constructor.hpp:230: >>> error: no matching function for call to >>> 'get_signature(boost::python::api::object&)' >> >> No, that does not work. (Both functions wrap a C++ function into a >> callable object, so they can't work together.) >> >> Have a look at my "Raw constructor (i.e. combination of make_constructor >> and raw_function)" thread (I say "my .. thread" because it was mostly me >> discussing with myself ;-p) in the archives, where I finally posted a >> solution. >> > > Hey thanks! Just what I needed. Can we please add this to boost::python? Patches are welcome. -- Dave Abrahams Boost Consulting www.boost-consulting.com From baas at ira.uka.de Thu Feb 2 18:19:18 2006 From: baas at ira.uka.de (Matthias Baas) Date: Thu, 02 Feb 2006 18:19:18 +0100 Subject: [C++-sig] pyplusplus tutorials & GUI wizard In-Reply-To: <7465b6170602012159h5f78b334s9238f6f30f842371@mail.gmail.com> References: <7465b6170601232249u7ca7741ncf71a6973fc12c45@mail.gmail.com> <7465b6170601290507m3c2cc0edied458d60932dfa04@mail.gmail.com> <7465b6170601300808o7c99bd6cgf936f22fb40ed6b6@mail.gmail.com> <7465b6170601302132o26dbdaa6x6c6e412764ac2509@mail.gmail.com> <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> <7465b6170602012159h5f78b334s9238f6f30f842371@mail.gmail.com> Message-ID: Roman Yakovenko wrote: > On 2/1/06, Matthias Baas wrote: >> Thanks for fixing that. With the latest cvs, the noncopyable and no_init >> specifiers are added, but on Linux (using gcc) it still doesn't compile >> because of the *_wrapper class which is derived from the original class. >> [...] > > I did not test my changes with GCC. I will test them. As a temporal solution > you can remove the wrapper code creator. Try to use finalize method on > class code creator. Uhm, I didn't see any finalize() method anywhere...? By "class code creator" you probably don't mean the object I create with module_creator.creator_t(), right? Then how do I obtain the class code creator that corresponds to my particular class? >> Basically, it works, but there is still a problem. Whenever I add a new >> class there's a new header file that gets included into *all* files >> automatically which wouldn't be necessary. So the files still change and >> get recompiled. [...] > > The problem is that I ( pyplusplus ) can not build set of required files. > Consider next case: > file a.h > class A{}; > > file b.h > #include "a.h" > > class B{}; > > You want to export A and B. pyplusplus will generate include to a.h > and b.h. Why don't you just include the header that actually defines the corresponding class (i.e. "a.h" when wrapping A and "b.h" when wrapping B)? If a header depends on other stuff the appropriate #include statement has to be in that header anyway (in the above example, b.h does already include a.h). In my case, I have to add some headers manually because Boost.Python requires the full definition of a class whereas the original headers only contain forward declarations. But that's ok with me. >> (Just out of curiosity, how do you determine whether a file has to be >> written or not, do you really compare the contents of the existing file >> with the data you're about to write?) > > Yes, this is the only way, that I know, that does it reliably. > Don't warry about performance. It takes only 90 - 100 second to create\generate > Boost.Python bindings for TnFOX, 625 files. Do you generate the bindings on a local drive or on a network drive? Maybe performance could become an issue once the data has to be transferred over a network...? By the way, an alternative to comparing the entire file could be storing a checksum (such as CRC32, see zlib.crc32()) somewhere at the top of the file and comparing only that value. But so far, this is really a minor issue. If I get the above header thing sorted out, the current performance is good enough for me (and I am already on a network drive). >> By the way, after the cvs update I got a new warning from gcc. The >> compiler complains that the last line in the generated source files >> doesn't have a newline. > > Next time before I do check in I will check it first on Linux. Sorry > for inconvinince. :-( No problem, it's only a warning anyway (and actually, I don't understand why gcc insists on that newline...). >> Then there's a new thing that came up. Pyplusplus also adds protected >> methods to the generated wrappers which breaks compilation for me. How >> can I disable that feature? > > Right now there is no way to disable it. Could you send me simple test > case that breaks > your compilation. I tested this behaviour and it works fine. Also if I > fix this bug, do you > still need to be able to disable this feature? I don't think it's a bug in pyplusplus, it's just that those protected methods use a class whose full definition is not available. For example, there's a protected method 'void setPtr(MPtrBase*);' and a full definition of MPtrBase is not available, the header only contains a forward declaration. When compiling the bindings I then get the error: .../type_id.hpp:71: error: invalid use of undefined type `struct MPtrBase' ../MObject.h:94: error: forward declaration of `struct MPtrBase' >> def filter(decl): >> return decl.name in [......] >> >> But now that I come to think about it, I don't understand why this works >> at all. I noticed that the filter function is also applied to class >> methods in which case the function returns False. But why are the >> methods then exposed? (I thought this would be a way to filter out the >> protected methods, but obviously this is not how it's supposed to work...) > > You found a bug. Thanks. I will fix it. Does that mean my above filter won't work anymore (as it would produce 'empty' classes) and I will have to return True when called on the actual class methods? (and if so, how would the updated filter look like?) - Matthias - From roman.yakovenko at gmail.com Sun Feb 5 08:37:22 2006 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 5 Feb 2006 09:37:22 +0200 Subject: [C++-sig] pyplusplus tutorials & GUI wizard In-Reply-To: References: <7465b6170601232249u7ca7741ncf71a6973fc12c45@mail.gmail.com> <7465b6170601300808o7c99bd6cgf936f22fb40ed6b6@mail.gmail.com> <7465b6170601302132o26dbdaa6x6c6e412764ac2509@mail.gmail.com> <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> <7465b6170602012159h5f78b334s9238f6f30f842371@mail.gmail.com> Message-ID: <7465b6170602042337g6720a7f8q242b4dfd0c5b5b5a@mail.gmail.com> On 2/2/06, Matthias Baas wrote: > > I did not test my changes with GCC. I will test them. As a temporal solution > > you can remove the wrapper code creator. Try to use finalize method on > > class code creator. > > Uhm, I didn't see any finalize() method anywhere...? > By "class code creator" you probably don't mean the object I create with > module_creator.creator_t(), right? Then how do I obtain the class code > creator that corresponds to my particular class? Take a look on this UML diagram. It is incomplete but will give you some understanding of existent code creators: http://www.language-binding.net/pyplusplus/code_creators.png module_creator.creator_t() function returns instance of class module_t. This class contains module_body_t code creator( accessible via body property ). As you can see from the UML diagram they both derive from compound_t code creator. This means that they contain other code creators. You can get access to them via "creators" property. There are few functions that will help you to find particular code creator. You can find them in code_creators\algorithm.py module. Take a look on py_easybmp example. You can also take a look on unit test: http://tinyurl.com/ckux9 ( see creator_finder_tester_t tester ) > >> Basically, it works, but there is still a problem. Whenever I add a new > >> class there's a new header file that gets included into *all* files > >> automatically which wouldn't be necessary. So the files still change and > >> get recompiled. [...] > > > > The problem is that I ( pyplusplus ) can not build set of required files. > > Consider next case: > > file a.h > > class A{}; > > > > file b.h > > #include "a.h" > > > > class B{}; > > > > You want to export A and B. pyplusplus will generate include to a.h > > and b.h. > > Why don't you just include the header that actually defines the > corresponding class (i.e. "a.h" when wrapping A and "b.h" when wrapping > B)? This is exactly what I do. May be I did not explain my self well. > >> (Just out of curiosity, how do you determine whether a file has to be > >> written or not, do you really compare the contents of the existing file > >> with the data you're about to write?) > > > > Yes, this is the only way, that I know, that does it reliably. > > Don't warry about performance. It takes only 90 - 100 second to create\generate > > Boost.Python bindings for TnFOX, 625 files. > > Do you generate the bindings on a local drive or on a network drive? > Maybe performance could become an issue once the data has to be > transferred over a network...? > By the way, an alternative to comparing the entire file could be storing > a checksum (such as CRC32, see zlib.crc32()) somewhere at the top of the > file and comparing only that value. > But so far, this is really a minor issue. If I get the above header > thing sorted out, the current performance is good enough for me (and I > am already on a network drive). I test it on local drive only. Also on my laptop the drive speed is 5400. So the performance are really important. Right now I am quite satisfied with performance. I see from your posting that you too. If it will become an issue, I am sure we can find some way to solve it. > >> def filter(decl): > >> return decl.name in [......] > >> > >> But now that I come to think about it, I don't understand why this works > >> at all. I noticed that the filter function is also applied to class > >> methods in which case the function returns False. But why are the > >> methods then exposed? (I thought this would be a way to filter out the > >> protected methods, but obviously this is not how it's supposed to work...) > > > > You found a bug. Thanks. I will fix it. > > Does that mean my above filter won't work anymore (as it would produce > 'empty' classes) and I will have to return True when called on the > actual class methods? (and if so, how would the updated filter look like?) First of all you are right. Now small explanation how filtering works. pygccxml defines make_flatten function. This function takes declaration and returns list of all declarations found\located\defined in that declaration, including it self. Filter functions use this function to create list that contains all declarations and after this then call "match" function on every declaration. This approach has advantage ( fine control ) and disadvantage( a little bit complex "match" function ). Now how do you write filter function: def should_stay(decl): if isinstance( decl.parent, pygccxml.declarations.class_t ): return True #This will leave all declarations defined under classes if .... if you need even grater control on exported declarations you can use next filter: if isinstance( decl, pygccxml.declarations.member_calldef_t): if decl.access_type != pygccxml.declaration.ACCESS_TYPES.PUBLIC: return False Be sure to take a look on py_qtxml example: http://tinyurl.com/9uhv4 This examples reuse Qt XML class naming convention. It leaves only classes that their name start with 'QDom' or 'QXml'. Also it removes constructor, that as input takes a pointer to implementation details class instance. An other example is py_date_time: http://tinyurl.com/e44kh. This example defines pretty complex "should_stay_ function. This is also should help you. I hope this was helpful. Also I fixed bug you reported in previous post. Thanks for reporting them. As always fixes in CVS. > - Matthias - > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From baas at ira.uka.de Mon Feb 6 19:07:13 2006 From: baas at ira.uka.de (Matthias Baas) Date: Mon, 06 Feb 2006 19:07:13 +0100 Subject: [C++-sig] pyplusplus tutorials & GUI wizard In-Reply-To: <7465b6170602042337g6720a7f8q242b4dfd0c5b5b5a@mail.gmail.com> References: <7465b6170601232249u7ca7741ncf71a6973fc12c45@mail.gmail.com> <7465b6170601300808o7c99bd6cgf936f22fb40ed6b6@mail.gmail.com> <7465b6170601302132o26dbdaa6x6c6e412764ac2509@mail.gmail.com> <7465b6170601312109i484ff1d5pf0a6afd7821d6e92@mail.gmail.com> <7465b6170602012159h5f78b334s9238f6f30f842371@mail.gmail.com> <7465b6170602042337g6720a7f8q242b4dfd0c5b5b5a@mail.gmail.com> Message-ID: Roman Yakovenko wrote: >> Why don't you just include the header that actually defines the >> corresponding class (i.e. "a.h" when wrapping A and "b.h" when wrapping >> B)? > > This is exactly what I do. May be I did not explain my self well. Do you mean that should already work with the version in cvs? I cannot confirm that. Here, pyplusplus adds all headers that were parsed. >>>> def filter(decl): >>>> return decl.name in [......] >>>> >>>> But now that I come to think about it, I don't understand why this works >>>> at all. I noticed that the filter function is also applied to class >>>> methods in which case the function returns False. But why are the >>>> methods then exposed? (I thought this would be a way to filter out the >>>> protected methods, but obviously this is not how it's supposed to work...) >>> >>> You found a bug. Thanks. I will fix it. >>[...] ok, I'll wait until the bug is fixed before I go on with my filtering attempts... - Matthias - From benveal92 at hotmail.com Tue Feb 7 03:07:58 2006 From: benveal92 at hotmail.com (Ben Veal) Date: Tue, 07 Feb 2006 02:07:58 +0000 Subject: [C++-sig] linking with non-python libraries Message-ID: Hi, I am trying to build a python extension for a derived class whose base class I only have as a shared library object & declaration file. The base class contains many virtual functions of which I only need a few, and also involves some threading. It contains various functions for getting data from a remote server. I manage to build the extension OK (both manually and using pyplusplus), however when I try to import it, I get the following message: ImportError: /usr/lib/python2.3/MyClient.so: undefined symbol: _ZN8BaseClassC2ERKS_ I suppose it can't find the library containing the base class. I use the following lines in my Jamfile to link with the appropriate libraries: extension DerivedClass : sourcefile.cpp