From oanjao at yahoo.com Tue May 1 00:17:31 2007 From: oanjao at yahoo.com (Craig Finch) Date: Mon, 30 Apr 2007 15:17:31 -0700 (PDT) Subject: [C++-sig] Need strategic advice designing Boost/Python program In-Reply-To: <4636463B.8090709@sympatico.ca> Message-ID: <62078.32342.qm@web30315.mail.mud.yahoo.com> > This, together with your point further down that you want to add > python > methods that are only ever used inside python make it sound as if > a C++ base class derived from in python may be the best approach. I think I am beginning to see why this approach is good. I think this is a cleaner solution than using __init__.py to inject methods. By "cleaner," I mean that my intentions will be more obvious to someone who looks at my code for the first time. From the Tutorial, this is the only way I know to inject methods, so let me know if there's another way. > I don't understand what you mean by "I can't access the data members > of > the C++ class". Of course, you have to expose them to python via > accessors > (say, as 'properties'), but as soon as that is done you can easily > derive > and extend that base class from within python. I keep getting error messages like this one when I define a constructor in Python: Boost.Python.ArgumentError: Python argument types in python_constructor.value(python_constructor) did not match C++ signature: value(python_constructor {lvalue}) This error message is from a simple test case that I have created. BTW, I'm injecting the method from __init__.py. I'm probably doing something wrong--should I start a new discussion thread, since this is kind of a side topic? > I'm not sure I understand. extract<> is a C++ API, that has nothing > to > do with a Python interface. The only context in which you may need > extract<> > here is when talking to a Python object (such as an instance of the > derived > Python class) from within C++, which, as you stated earlier, you > won't. I guess that wasn't very clear. To elaborate: when a Python programmer uses my C++ class, he should not be concerned about C details like array length, memory allocation, etc. The Python user should be able to create lists, NumPy arrays, etc. The underlying C++ code should then check for type errors and convert them to C arrays for efficient processing. My plan was to use numeric::array objects in C++, which would provide the right Python behavior, and would require the use of to get the correct type from each element of the array. It looks like Ralf is giving me a lot to think about on the array subject, so I'm going to look at that before I say any more on this subject! > The same IS-A relationship that you would expect from a pure C++ > program > still holds in this hybrid setting. If you have exposed a C++ > function > (or method) expecting a parent reference (or pointer), a child > reference > (or pointer) will be accepted as well. Great! Things like this make me very impressed with Boost.python. -------------- Please reply to cfinch at ieee.org __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From seefeld at sympatico.ca Tue May 1 00:22:38 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 30 Apr 2007 18:22:38 -0400 Subject: [C++-sig] Need strategic advice designing Boost/Python program In-Reply-To: <62078.32342.qm@web30315.mail.mud.yahoo.com> References: <62078.32342.qm@web30315.mail.mud.yahoo.com> Message-ID: <46366C2E.3040303@sympatico.ca> Craig Finch wrote: > I keep getting error messages like this one when I define a constructor > in Python: > Boost.Python.ArgumentError: Python argument types in > python_constructor.value(python_constructor) > did not match C++ signature: > value(python_constructor {lvalue}) > This error message is from a simple test case that I have created. Since you don't show any specific code I have to guess: Are you calling the base class constructor in your derived class constructor ? In contrast to C++, Python doesn't do this automatically for you, so if you forget to initialize the base class you may see conflicts such as the above when passing a derived where a base is expected. > BTW, I'm injecting the method from __init__.py. I'm probably doing > something wrong--should I start a new discussion thread, since this is > kind of a side topic? If you have a specific question (with code samples etc.) that may make sense. It's up to you. I'm not sure what __init__.py is here. So I guess a complete test case would indeed help. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From seefeld at sympatico.ca Tue May 1 01:00:59 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 30 Apr 2007 19:00:59 -0400 Subject: [C++-sig] Need strategic advice designing Boost/Python program In-Reply-To: <148457.12444.qm@web31106.mail.mud.yahoo.com> References: <148457.12444.qm@web31106.mail.mud.yahoo.com> Message-ID: <4636752B.90007@sympatico.ca> Ralf W. Grosse-Kunstleve wrote: >> This, together with your point further down that you want to add python >> methods that are only ever used inside python make it sound as if >> a C++ base class derived from in python may be the best approach. > > FWIW: there is a very powerful alternative to this: injecting. > For example: > > class _histogram(boost.python.injector, ext.histogram): > > def show(self, f=None, prefix="", format_cutoffs="%.8g"): > if (f is None): f = sys.stdout > fmt = "%s" + format_cutoffs + " - " + format_cutoffs + ": %d" > for info in self.slot_infos(): > print >> f, fmt % (prefix, info.low_cutoff, info.high_cutoff, info.n) > > The boost.python.injector is a small utility class defined > in boost_adaptbx (adaptor toolbox), boost/python.py. > > The difference is that objects of ext.histogram will have the > .show() method, even if they are created in C++. > I.e. even if you only have a C++ constructor, you can have pure > Python methods. Sorry, can you elaborate on that a bit ? What is special in the code above ? It looks like a 'normal' definition of a derived python class ('_histogram') that derives from a (presumably) C++ class (ext.histogram). What does boost.python.injector do that wouldn't be available without it ? (I don't understand the 'only C++ constructor' part, in fact) Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... From rwgk at yahoo.com Tue May 1 02:16:50 2007 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 30 Apr 2007 17:16:50 -0700 (PDT) Subject: [C++-sig] Need strategic advice designing Boost/Python program Message-ID: <631819.11856.qm@web31111.mail.mud.yahoo.com> > Sorry, can you elaborate on that a bit ? What is special in the code > above ? It looks like a 'normal' definition of a derived python class > ('_histogram') that derives from a (presumably) C++ class (ext.histogram). If you just derive without the boost.python.injector, the C++ class ext.histogram doesn't know about the .show() method, only _histogram does. Maybe I should have shown the bare-bones approach first. Here it is again: def histogram_show(self, f=None, prefix="", format_cutoffs="%.8g"): # exact same code ext.histogram.show = histogram_show Why is this cool? If you have a C++ function returning a new histogram object, you want that to have the .show() method: C++: histogram make_histogram(); def("make_histogram", make_histogram); Python: h = make_histogram() h.show() It doesn't help if you have the plain inheritance _histogram, since h above is just an ext.histogram. To get the same result without injecting the .show() method, you'd have to def a Python wrapper function, something like: def make_histogram(): h = ext.make_histogram() return _histogram(h) And that for every C++ function returning a histogram object. Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boost-consulting.com Tue May 1 13:41:34 2007 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 01 May 2007 07:41:34 -0400 Subject: [C++-sig] [Boost.Python] inconsistent use of function pointer typedef References: Message-ID: <87hcqwkbyp.fsf@grogan.peloton> on Fri Apr 27 2007, Sebastian Ramacher wrote: > I just wanted to repost a patch I've submitted to the SourceForge > tracker some days ago. The patch fixes the inconsistent use of the > function pointer typedef 'convertible_function' at the declaration and > definition of 'boost::python::converter::registry::insert' and > 'boost::python::converter::registry::push_back'. This is just a warning fix, right? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com From oanjao at yahoo.com Wed May 2 00:42:38 2007 From: oanjao at yahoo.com (Craig Finch) Date: Tue, 1 May 2007 15:42:38 -0700 (PDT) Subject: [C++-sig] Problem injecting Python __init__ into wrapped C++ class Message-ID: <891935.77183.qm@web30301.mail.mud.yahoo.com> Injecting Python methods into wrapped Boost C++ classes sounds like an excellent idea. It is described in the Boost.python tutorial at http://www.boost.org/libs/python/doc/tutorial/doc/html/python/techniques.html#python.extending_wrapped_objects_in_python I have been able to get this to work for ordinary methods, but I would like to define an __init__ method in Python for a wrapped C++ class. I have created a test case, following the methods in the Tutorial, that demonstrates the runtime error that results when I try this. Because this involves creating a Python package with a directory structure that would be difficult to reproduce correctly in this message, I'm posting a link to a .tgz file that contains everything you need to build and run the example (using make and gcc) and see the error message. http://www.shocksolution.com/files/TestConstructors.tgz When I build and run the code, I get the following output: ---------------------------------------------------------- Python value is 18 C++ value is 18 Python value is Traceback (most recent call last): File "TestConstructors/TestConstructors.py", line 8, in ? print "Python value is", y.value() Boost.Python.ArgumentError: Python argument types in python_constructor.value(python_constructor) did not match C++ signature: value(python_constructor {lvalue}) I would appreciate it if someone could take a look at the code (it's really very small) and tell me what I'm doing wrong here. -------------- Please reply to cfinch at ieee.org __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From rwgk at yahoo.com Wed May 2 02:04:37 2007 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 1 May 2007 17:04:37 -0700 (PDT) Subject: [C++-sig] Problem injecting Python __init__ into wrapped C++ class Message-ID: <588216.9155.qm@web31111.mail.mud.yahoo.com> > I have been able to get this to work for ordinary methods, but I would > like to define an __init__ method in Python for a wrapped C++ class. I > have created a test case, following the methods in the Tutorial, that > demonstrates the runtime error that results when I try this. I'm doing it with a Python wrapper function for the constructor, e.g. sticking to my histogram example (although the following is completely made up): def histogram(a, b, c): if (c is None): return ext.histogram(a, b) return ext.histogram(a, b, c) The disadvantage is that help(histogram) only reports the function, not the entire class (in all our modules histogram is ext.histogram until overridden somehow). I don't really like this solution, but I'm having difficulties imagining something more slick. Ralf __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From mitch at niftyneato.com Wed May 2 07:15:34 2007 From: mitch at niftyneato.com (Mitch Jones) Date: Tue, 01 May 2007 22:15:34 -0700 Subject: [C++-sig] Problem exposing container iterator with boost::iterator_adaptor In-Reply-To: <7465b6170704271147m4c3a1crb5530c0713eece7c@mail.gmail.com> Message-ID: on 4/27/07 11:47 AM, Roman Yakovenko at roman.yakovenko at gmail.com scribbled: > Your code looks correct, can you create small example, which reproduce > the problem? Well, the sample turned out to be 150 or so lines, and in the end I figured out the problem as I was working with the sample. > Also what happens if you replace > .def("__iter__", range(&Container::begin, &Container::end) > with > .def("__iter__", range(&WidgetContainer::begin, &WidgetContainer::end) > ? This was a typo and should have read WidgetContainer all along. The problem boiled down to how my iterator adaptor was declared which looked something like class WidgetIterator : public iterator_fa?ade, single_pass_traversal_tag> What would happen is that dereference would get called and the current item would get passed back, but if you notice, the definition of the iterator doesn't define the reference type, it uses the default, which is absolutely not what you want in this case. In this case, dereference looks like shared_ptr & dereference() const { return current;} The shared_ptr never gets properly copied causing premature destruction which leads to the "pure virtual method called" error. So, in answer to my question "Is the iterator_adaptor a red herring and the real issue in Widget and its descendants and I've missed something obvious?" The answer was no and yes. -- Mitch Jones mitch at niftyneato.com From jonas at MIT.EDU Wed May 2 14:25:58 2007 From: jonas at MIT.EDU (Eric Jonas) Date: Wed, 02 May 2007 08:25:58 -0400 Subject: [C++-sig] more examples of automatic type conversion Message-ID: <1178108758.13074.4.camel@convolution.mit.edu> Hello! I'm using boost::python to try and interface numpy (that is, the newest numpy, not numeric or numarray) ndarray objects to my code which depends on boost::multi_array. I've written functions that take a pyobject* and return a multiarray and vice versa. Now I'm at the point of interfacing my c++ classes (which take multi_array references in their constructors). Rather than adulterating their interfaces by adding additional constructors with PyObject* arguments, is there some way of telling boost::python to use my conversion functions automatically? Thanks, ...Eric Jonas From seefeld at sympatico.ca Wed May 2 14:33:21 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 02 May 2007 08:33:21 -0400 Subject: [C++-sig] boost::python::eval Message-ID: <46388511.40702@sympatico.ca> David, when looking at the Embedding Python tutorial, I realized that the functionality provided by exec() and exec_file() isn't quite complete, with respect to the C API's offering: Py_eval_input isn't covered. The attached patch attempts to fix that, i.e. a new eval() function is defined that returns the result of the evaluated expression passed as argument. I'd like to check this into HEAD, as well as the 1_34 branch, as soon as the release is out (assuming that this is indeed to become the new trunk), so it can make it into 1.35. OK ? Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin... -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: patch URL: From dave at boost-consulting.com Wed May 2 15:02:48 2007 From: dave at boost-consulting.com (David Abrahams) Date: Wed, 02 May 2007 09:02:48 -0400 Subject: [C++-sig] boost::python::eval In-Reply-To: <46388511.40702@sympatico.ca> (Stefan Seefeld's message of "Wed\, 02 May 2007 08\:33\:21 -0400") References: <46388511.40702@sympatico.ca> Message-ID: <87y7k7e5tz.fsf@grogan.peloton> on Wed May 02 2007, Stefan Seefeld wrote: > David, > > when looking at the Embedding Python tutorial, I realized that the > functionality provided by exec() and exec_file() isn't quite complete, > with respect to the C API's offering: Py_eval_input isn't covered. > > The attached patch attempts to fix that, i.e. a new eval() function > is defined that returns the result of the evaluated expression passed > as argument. > > I'd like to check this into HEAD, as well as the 1_34 branch, as soon > as the release is out (assuming that this is indeed to become the new > trunk), so it can make it into 1.35. > > OK ? Sure. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com From roman.yakovenko at gmail.com Wed May 2 15:32:21 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 2 May 2007 16:32:21 +0300 Subject: [C++-sig] more examples of automatic type conversion In-Reply-To: <1178108758.13074.4.camel@convolution.mit.edu> References: <1178108758.13074.4.camel@convolution.mit.edu> Message-ID: <7465b6170705020632g29b04f5eoce3608934f8265c7@mail.gmail.com> On 5/2/07, Eric Jonas wrote: > Hello! I'm using boost::python to try and interface numpy (that is, the > newest numpy, not numeric or numarray) ndarray objects to my code which > depends on boost::multi_array. I've written functions that take a > pyobject* and return a multiarray and vice versa. Now I'm at the point > of interfacing my c++ classes (which take multi_array references in > their constructors). Rather than adulterating their interfaces by adding > additional constructors with PyObject* arguments, is there some way of > telling boost::python to use my conversion functions automatically? http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html Let me know if this helped you. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From tim at klingt.org Wed May 2 15:41:07 2007 From: tim at klingt.org (Tim Blechmann) Date: Wed, 02 May 2007 15:41:07 +0200 Subject: [C++-sig] boost::python threading problem Message-ID: <1178113267.7782.15.camel@localhost> hi all, trying to hunt a deadlock, i've figured out, that during the execution of wrapped c++ functions, python global interpreter lock is not released. in my specific case it lead to this behaviour: thread A (python) calls a wrapped c++ function, that locks mutex M thread B (c++) locks mutex M before calling a python function. from my understanding, this shouldn't be a problem, if the gil would be released for the time of the c++ function call... while this can be done from within the wrapped c++ function (via Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS), i would be in favor of a solution, where i wouldn't have to change the c++ code ... is this a known issue? are there any plans to change this behavior? thanks, tim -- tim at klingt.org ICQ: 96771783 http://tim.klingt.org There's no such entity as "most people". These are generalities. All generalities are meaningless. You've got to pin it down to a specific person doing a specific thing at a specific time and space. William S. Burroughs -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part URL: From ndbecker2 at gmail.com Wed May 2 19:06:05 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 02 May 2007 13:06:05 -0400 Subject: [C++-sig] more examples of automatic type conversion References: <1178108758.13074.4.camel@convolution.mit.edu> Message-ID: Eric Jonas wrote: > Hello! I'm using boost::python to try and interface numpy (that is, the > newest numpy, not numeric or numarray) ndarray objects to my code which > depends on boost::multi_array. I've written functions that take a > pyobject* and return a multiarray and vice versa. Now I'm at the point > of interfacing my c++ classes (which take multi_array references in > their constructors). Rather than adulterating their interfaces by adding > additional constructors with PyObject* arguments, is there some way of > telling boost::python to use my conversion functions automatically? > > Thanks, > ...Eric Jonas I'm very interested in interfacing various c++ array containers to numpy. Do you have any small examples? From jonas at MIT.EDU Wed May 2 19:31:44 2007 From: jonas at MIT.EDU (Eric Jonas) Date: Wed, 02 May 2007 13:31:44 -0400 Subject: [C++-sig] more examples of automatic type conversion In-Reply-To: References: <1178108758.13074.4.camel@convolution.mit.edu> Message-ID: <1178127105.13074.18.camel@convolution.mit.edu> > I'm very interested in interfacing various c++ array containers to numpy. > Do you have any small examples? > I think we all are, and the existing numpy/numeric interface is getting a bit crufty, and the new numpy type module is somewhat complex :) one thing I'm struggling with is my poor understanding of python's internal memory management and the like. I'll hopefully have the automatic type conversion working in a day or two, and I'll be sure to post my results to the list. I'm not trying to do anything fancy like the numeric/numarray stuff currently in boost; I just want functions that take in const boost::multi_array & to handle the conversion for me. I want to mostly use my python as a scripting interface on top of some number-crunching C++ monte-carlo code. Interesting questions include: What sort of containers do we use? Boost::array? Boost::multiarray? The ublas containers? all of them? Just std::vector< std::vector (...) How do we handle the static typing problems? I also can't promise that I've written anything other than an app that leaks memory like a submarine with a screen door. C++'s notion of "ownership" is so simple compared to python. ...Eric From p.jaroszynski at gmail.com Wed May 2 22:56:51 2007 From: p.jaroszynski at gmail.com (Piotr Jaroszynski) Date: Wed, 2 May 2007 22:56:51 +0200 Subject: [C++-sig] Policies again Message-ID: <200705022256.52150.p.jaroszynski@gmail.com> Hello, I am still not the best at polcies... Let me show you my current problem: #include namespace bp = boost::python; struct Blah; struct Foo { Blah * b; Foo(Blah * blah) : b(blah) { } }; struct Blah { Foo * f; Blah() : f(new Foo(this)) { } }; BOOST_PYTHON_MODULE(policies) { bp::class_ f("Foo", bp::no_init); bp::class_ b("Blah"); b.add_property("f", bp::make_getter(&Blah::f, policy??)); } Which policy should I use in such case? -- Best Regards, Piotr Jaroszynski From ndbecker2 at gmail.com Thu May 3 01:51:31 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 02 May 2007 19:51:31 -0400 Subject: [C++-sig] more examples of automatic type conversion References: <1178108758.13074.4.camel@convolution.mit.edu> <1178127105.13074.18.camel@convolution.mit.edu> Message-ID: Eric Jonas wrote: >> I'm very interested in interfacing various c++ array containers to numpy. >> Do you have any small examples? >> > > I think we all are, and the existing numpy/numeric interface is getting > a bit crufty, and the new numpy type module is somewhat complex :) one > thing I'm struggling with is my poor understanding of python's internal > memory management and the like. I'll hopefully have the automatic type > conversion working in a day or two, and I'll be sure to post my results > to the list. I'm not trying to do anything fancy like the > numeric/numarray stuff currently in boost; I just want functions that > take in const boost::multi_array & to handle the conversion for > me. I want to mostly use my python as a scripting interface on top of > some number-crunching C++ monte-carlo code. > > Interesting questions include: What sort of containers do we use? > Boost::array? Boost::multiarray? The ublas containers? all of them? Just > std::vector< std::vector (...) How do we handle the static typing > problems? > I've used: ublas::{vector,matrix} boost::multi_array blitz::array Recently, I've been playing with blitz/python and I am starting to really like it. OTOH, it doesn't seem to be a very active project and my questions have gone largely unanswered. OTOH, the code is far easier to comprehend (for me, at least) than the first 2 above, so I can pretty much answer my own questions. I like that blitz::array handles more than just 1/2 dimensions, and I am starting to _really_ like that it does ref counting. That means I can do: u = array1_int ((1,2,3,4)) u2 = u[::2] and now u2 is a proxy for u. This behavior is (I believe) like numpy. Or: u = array1_complex ((1,2,3,4)) u2 = real (u) u2[:] = 7 Again, this will write to the real part of u. And, I haven't needed to even think about ownership. From ndbecker2 at gmail.com Thu May 3 01:56:23 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 02 May 2007 19:56:23 -0400 Subject: [C++-sig] more examples of automatic type conversion References: <1178108758.13074.4.camel@convolution.mit.edu> <1178127105.13074.18.camel@convolution.mit.edu> Message-ID: Eric Jonas wrote: >> I'm very interested in interfacing various c++ array containers to numpy. >> Do you have any small examples? >> > > I think we all are, and the existing numpy/numeric interface is getting > a bit crufty, and the new numpy type module is somewhat complex :) one > thing I'm struggling with is my poor understanding of python's internal > memory management and the like. I'll hopefully have the automatic type > conversion working in a day or two, and I'll be sure to post my results > to the list. I'm not trying to do anything fancy like the > numeric/numarray stuff currently in boost; I just want functions that > take in const boost::multi_array & to handle the conversion for > me. I want to mostly use my python as a scripting interface on top of > some number-crunching C++ monte-carlo code. > > Interesting questions include: What sort of containers do we use? > Boost::array? Boost::multiarray? The ublas containers? all of them? Just > std::vector< std::vector (...) How do we handle the static typing > problems? > Also, I am quite interested in writing generic algorithms that will work with any of the above. I have mentioned this on boost-devel. Some people suggested looking at gil. I don't really think that is what I want, though. Seems rather specific to image processing and image formats. I'm still interested in a generalization of boost::range to multi-dimensions for this purpose. From fullung at gmail.com Thu May 3 10:33:51 2007 From: fullung at gmail.com (Albert Strasheim) Date: Thu, 3 May 2007 10:33:51 +0200 Subject: [C++-sig] more examples of automatic type conversion In-Reply-To: <7465b6170705020632g29b04f5eoce3608934f8265c7@mail.gmail.com> References: <1178108758.13074.4.camel@convolution.mit.edu> <7465b6170705020632g29b04f5eoce3608934f8265c7@mail.gmail.com> Message-ID: <20070503083351.GA5134@dogbert.sdsl.sun.ac.za> On Wed, 02 May 2007, Roman Yakovenko wrote: > On 5/2/07, Eric Jonas wrote: > > Hello! I'm using boost::python to try and interface numpy (that is, the > > newest numpy, not numeric or numarray) ndarray objects to my code which > > depends on boost::multi_array. I've written functions that take a > > pyobject* and return a multiarray and vice versa. Now I'm at the point > > of interfacing my c++ classes (which take multi_array references in > > their constructors). Rather than adulterating their interfaces by adding > > additional constructors with PyObject* arguments, is there some way of > > telling boost::python to use my conversion functions automatically? > > http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html > > Let me know if this helped you. As luck would have it, I also started playing with this idea yesterday and I found the above-mentioned page to help me along. I'm mostly interested in wrapping an interface written in terms of uBLAS vectors, matrices and vector-of-vectors. One issue I've run into with uBLAS is that there doesn't seem to be an array adaptor (the A in matrix) that can be used to wrap existing memory without copying at some point. Writing an array adaptor like this shouldn't be too hard though. Another issue is that you have to be very careful with the vector/matrix type you use, since converting a NumPy array to matrix > and passing that to a function that expects matrix doesn't work (strange crashes, probably due to the slight difference in size between the objects, due to the different array adaptors being used). Anyway, I've more or less got pass-by-value and return-by-value working using Roman's example, but I can't quite figure out how to make Boost.Python convert pointer and reference arguments or return values into PyObject*'s using the same scheme. Should this just work if I have my automatic conversion set up correctly, or is there additional magic that needs to be added? Again, it would be *very* useful if copying could be avoided here. Any hints would be appreciated. Cheers, Albert From roman.yakovenko at gmail.com Thu May 3 13:08:41 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 3 May 2007 14:08:41 +0300 Subject: [C++-sig] more examples of automatic type conversion In-Reply-To: <20070503083351.GA5134@dogbert.sdsl.sun.ac.za> References: <1178108758.13074.4.camel@convolution.mit.edu> <7465b6170705020632g29b04f5eoce3608934f8265c7@mail.gmail.com> <20070503083351.GA5134@dogbert.sdsl.sun.ac.za> Message-ID: <7465b6170705030408geea84b4ib2c4e52e4b957a07@mail.gmail.com> On 5/3/07, Albert Strasheim wrote: > > On Wed, 02 May 2007, Roman Yakovenko wrote: > > > On 5/2/07, Eric Jonas wrote: > > > Hello! I'm using boost::python to try and interface numpy (that is, > the > > > newest numpy, not numeric or numarray) ndarray objects to my code > which > > > depends on boost::multi_array. I've written functions that take a > > > pyobject* and return a multiarray and vice versa. Now I'm at the point > > > of interfacing my c++ classes (which take multi_array references in > > > their constructors). Rather than adulterating their interfaces by > adding > > > additional constructors with PyObject* arguments, is there some way of > > > telling boost::python to use my conversion functions automatically? > > > > > http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html > > > > Let me know if this helped you. > > As luck would have it, I also started playing with this idea yesterday > and I found the above-mentioned page to help me along. I'm mostly > interested in wrapping an interface written in terms of uBLAS vectors, > matrices and vector-of-vectors. :-), good One issue I've run into with uBLAS is that there doesn't seem to be an > array adaptor (the A in matrix) that can be used to wrap > existing memory without copying at some point. Writing an array adaptor > like this shouldn't be too hard though. You don't have, use indexing suite v2: http://language-binding.net/pyplusplus/documentation/containers.html And example of usage: http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#return-range > Another issue is that you have to be very careful with the > vector/matrix type you use, since converting a NumPy array to > matrix > and passing that to a > function that expects matrix doesn't work (strange crashes, probably > due to the slight difference in size between the objects, due to the > different array adaptors being used). > > Anyway, I've more or less got pass-by-value and return-by-value working > using Roman's example, but I can't quite figure out how to make > Boost.Python convert pointer and reference arguments or return values > into PyObject*'s using the same scheme. Should this just work if I have > my automatic conversion set up correctly, or is there additional magic > that needs to be added? Again, it would be *very* useful if copying > could be avoided here. Post small example, may be I will be able to help -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.reid at mail.cryst.bbk.ac.uk Thu May 3 13:30:45 2007 From: j.reid at mail.cryst.bbk.ac.uk (John Reid) Date: Thu, 03 May 2007 12:30:45 +0100 Subject: [C++-sig] more examples of automatic type conversion In-Reply-To: References: <1178108758.13074.4.camel@convolution.mit.edu> Message-ID: Neal Becker wrote: > I'm very interested in interfacing various c++ array containers to numpy. > Do you have any small examples? I have what works for me although it is not extensively tested. It is not fancy as it copies data on conversion to/from python but I don't need any more than that. I've just implemented conversion for boost::multi_array but other arrays should be straightforward. Also it is a shameless hack of Roman's tuple example. No doubt it could be improved considerably but I hope it is useful. Here is an example of using it to export a property of a simple struct: struct numpy_test { typedef boost::multi_array< double, 2 > double_array; double_array a; void print_shape() const { std::cout << a.shape()[ 0 ] << "," << a.shape()[ 1 ] << "\n"; } void print_first() const { std::cout << a[ 0 ][ 0 ] << "\n"; } }; void export_model() { numpy_multi_array_converter< numpy_test::double_array >::register_to_and_from_python(); class_< numpy_test >( "numpy_test" ) .def( "print_shape", &numpy_test::print_shape ) .def( "print_first", &numpy_test::print_first ) .add_property( "array", make_getter( &numpy_test::a, return_value_policy< return_by_value >() ), numpy_multi_array_converter< numpy_test::double_array >::set_member_with_resize< numpy_test, &numpy_test::a > ) ; } and here is the code to do the conversion: namespace detail { template< typename T > struct get_dtype { static const char * name() { throw std::logic_error( "get_dtype not specialised for this type" ); } }; #define DECLARE_DTYPE_FOR( type, dtype ) template< > struct get_dtype< type > { static const char * name() { return dtype; } }; DECLARE_DTYPE_FOR( double, "float64" ) DECLARE_DTYPE_FOR( float, "float32" ) DECLARE_DTYPE_FOR( int, "int32" ) DECLARE_DTYPE_FOR( unsigned, "uint32" ) DECLARE_DTYPE_FOR( long, "int64" ) DECLARE_DTYPE_FOR( unsigned long, "uint64" ) } // namespace impl template< typename MultiArrayType > struct numpy_multi_array_converter { typedef MultiArrayType multi_array_t; typedef std::vector< std::size_t > shape_t; static void register_to_and_from_python() { register_from_python(); register_to_python(); } static void register_to_python() { boost::python::to_python_converter< multi_array_t, numpy_multi_array_converter< multi_array_t > >(); } static void register_from_python() { boost::python::converter::registry::push_back( &numpy_multi_array_converter< multi_array_t >::convertible, &numpy_multi_array_converter< multi_array_t >::construct, boost::python::type_id< multi_array_t >() ); } static void * convertible( PyObject * obj ) { using namespace boost::python; try { shape_t shape; get_shape( object( handle<>( borrowed( obj ) ) ), shape ); if( multi_array_t::dimensionality != shape.size() ) return 0; } catch( ... ) { return 0; } return obj; } template< typename C, multi_array_t C::* pm > static void set_member_with_resize( C & c, const multi_array_t & a ) { std::vector< unsigned > extents; for( unsigned dim = 0; a.num_dimensions() != dim; ++dim ) extents.push_back( a.shape()[ dim ] ); (c.*pm).resize( extents ); (c.*pm) = a; } static void construct( PyObject* obj, boost::python::converter::rvalue_from_python_stage1_data* data ) { using namespace boost::python; //get the storage typedef converter::rvalue_from_python_storage< multi_array_t > storage_t; storage_t * the_storage = reinterpret_cast< storage_t * >( data ); void * memory_chunk = the_storage->storage.bytes; //new placement object py_obj( handle<>( borrowed( obj ) ) ); shape_t shape; get_shape( py_obj, shape ); multi_array_t * a = new (memory_chunk) multi_array_t( shape ); //extract each element from numpy array and put in c array index i( a->num_dimensions(), 0 ); do { using boost::python::list; using boost::python::tuple; list numpy_index; for( unsigned dim = 0; a->num_dimensions() != dim; ++dim ) { numpy_index.append( i[ dim ] ); } ( *a )( i ) = extract< multi_array_t::element >( py_obj[ tuple( numpy_index ) ] ); } while( increment_index( i, *a ) ); data->convertible = memory_chunk; } static PyObject * convert( const multi_array_t & c_array ) { using namespace boost::python; object numpy = object( handle<>( ::PyImport_Import( object( "numpy" ).ptr() ) ) ); if( ! numpy ) throw std::logic_error( "Could not import numpy" ); object array_function = numpy.attr( "empty" ); if( ! array_function ) throw std::logic_error( "Could not find array function" ); //create a numpy array to put it in boost::python::list extents; for( unsigned dim = 0; c_array.num_dimensions() != dim; ++dim ) extents.append( c_array.shape()[ dim ] ); object result( array_function( extents, numpy.attr( "dtype" )( detail::get_dtype< multi_array_t::element >::name() ) ) ); //copy the elements index i( c_array.num_dimensions(), 0 ); do { boost::python::list numpy_index; for( unsigned dim = 0; c_array.num_dimensions() != dim; ++dim ) { numpy_index.append( i[dim] ); } result[ tuple( numpy_index ) ] = c_array( i ); } while( increment_index( i, c_array ) ); return incref( result.ptr() ); } protected: static void get_shape( boost::python::object & obj, shape_t & shape ) { using namespace boost::python; shape.clear(); object py_shape = obj.attr( "shape" ); const std::size_t N = len( py_shape ); for( std::size_t i = 0; N != i; ++i ) shape.push_back( extract< std::size_t >( py_shape[ i ] ) ); } typedef std::vector< typename multi_array_t::index > index; /**< To iterate over entries in num_dimensions independent fashion. */ /**< Iterates over entries in num_dimensions independent fashion. */ static bool increment_index( index & i, const multi_array_t & c_array ) { for( unsigned dim = 0; i.size() != dim; ++dim ) { ++i[dim]; if( i[dim] != c_array.shape()[dim] ) return true; else i[dim] = 0; } return false; } }; From ndbecker2 at gmail.com Thu May 3 14:43:13 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 03 May 2007 08:43:13 -0400 Subject: [C++-sig] more examples of automatic type conversion References: <1178108758.13074.4.camel@convolution.mit.edu> <1178127105.13074.18.camel@convolution.mit.edu> Message-ID: I've placed some basic test code for blitz++ here: https://nbecker.dyndns.org/blitz.hpp Next I will add all the arithmetic operators. That won't take long, since I've already done this for ublas, and stlsoft::fixed_array. From p.jaroszynski at gmail.com Thu May 3 16:30:07 2007 From: p.jaroszynski at gmail.com (Piotr Jaroszynski) Date: Thu, 3 May 2007 16:30:07 +0200 Subject: [C++-sig] Policies again In-Reply-To: <200705022256.52150.p.jaroszynski@gmail.com> References: <200705022256.52150.p.jaroszynski@gmail.com> Message-ID: <200705031630.08286.p.jaroszynski@gmail.com> On Wednesday 02 of May 2007 22:56:51 Piotr Jaroszynski wrote: > Let me show you my current problem: To be even more precise: #include namespace bp = boost::python; struct Blah; struct Foo { Blah * b; Foo(Blah * blah) : b(blah) { } }; struct Blah_f { Foo * f; Blah_f(Blah * blah) : f(new Foo(blah)) { } }; struct Blah : Blah_f { Blah() : Blah_f(this) { } }; BOOST_PYTHON_MODULE(policies) { bp::register_ptr_to_python(); bp::class_ f("Foo", bp::no_init); bp::class_ b("Blah"); b.add_property("f", bp::make_getter(&Blah::f, bp::return_internal_reference<>())); } You will probably ask where is the big difference... So when using the return_internal_reference policy, which is probably wrong anyway, I get: Traceback (most recent call last): File "./test.py", line 5, in ? print Blah().f Boost.Python.ArgumentError: Python argument types in None.None(Blah) did not match C++ signature: None(Blah_f {lvalue}) I think I should use one of the with_custodian_and_ward variations, but I couldn't make any of them to even compile. -- Best Regards, Piotr Jaroszynski From jwiegley at gmail.com Fri May 4 15:39:13 2007 From: jwiegley at gmail.com (John Wiegley) Date: Fri, 4 May 2007 07:39:13 -0600 Subject: [C++-sig] Making boost::optional passable to/from Python Message-ID: <5452682E-E1E0-4DAE-BFA1-DDC3B8C9F09A@gmail.com> The following code will make it possible to use boost::optional very easily with Boost.Python. For every time you expect to be used optionally, you must call the following during module initialization: python_optional(); You can now accept and return boost::optional(). In both directions, None will reflect an uninitialized value, while data of the correct type represents an initialized value. Needless to say, valid conversions must already exist for some_type_t, otherwise an error is generated claiming that the optional type cannot be converted. John Wiegley template struct object_from_python { object_from_python() { boost::python::converter::registry::push_back (&TfromPy::convertible, &TfromPy::construct, boost::python::type_id()); } }; template struct register_python_conversion { register_python_conversion() { boost::python::to_python_converter(); object_from_python(); } }; template struct python_optional : public boost::noncopyable { struct optional_to_python { static PyObject * convert(const boost::optional& value) { return (value ? boost::python::to_python_value()(*value) : boost::python::detail::none()); } }; struct optional_from_python { static void * convertible(PyObject * source) { using namespace boost::python::converter; if (source == Py_None) return source; const registration& converters(registered::converters); if (implicit_rvalue_convertible_from_python(source, converters)) { rvalue_from_python_stage1_data data = rvalue_from_python_stage1(source, converters); return rvalue_from_python_stage2(source, data, converters); } return NULL; } static void construct(PyObject * source, boost::python::converter::rvalue_from_python_stage1_data * data) { using namespace boost::python::converter; void * const storage = ((rvalue_from_python_storage *) data)->storage.bytes; if (data->convertible == source) // == None new (storage) boost::optional(); // A Boost uninitialized value else new (storage) boost::optional(*static_cast(data->convertible)); data->convertible = storage; } }; explicit python_optional() { register_python_conversion, optional_to_python, optional_from_python>(); } }; From gbrunick at andrew.cmu.edu Fri May 4 18:02:46 2007 From: gbrunick at andrew.cmu.edu (Gerard Brunick) Date: Fri, 04 May 2007 12:02:46 -0400 Subject: [C++-sig] Passing wrapped objects between extensions via python. Message-ID: <463B5926.2030302@andrew.cmu.edu> I'd like to be able to add new C++ code "on the fly." I have the "main" extension module: ************************* #include #include #include void do_function(boost::function func, double arg) { std::cout << "Doing function: " << func(arg) << std::endl; } BOOST_PYTHON_MODULE(main) { boost::python::class_ >("double_double"); boost::python::def("do_function", do_function); } *************************** Later I decide to add functionality (during a session in which the python is running and the main extension module has been loaded) so I compile a new extension module: *************************** #include #include double triple(double d) { return d * 3; } BOOST_PYTHON_MODULE(helper) { boost::python::scope().attr("triple") = boost::function(triple); } **************************** This all seems to work fine. In fact I have ********* >>> import main, helper >>> main.do_function(helper.triple, 3) Doing function: 9 ********** but **************** >>> import helper, main Traceback (most recent call last): File "", line 1, in TypeError: No to_python (by-value) converter found for C++ type: class boost::function > ***************** which I take to be a good thing, because it means that helper actually finds the to_python converter in main. The thing is, I'm a little uneasy about all of this because I feel that I should have to do something to make the helper.pyd link again the main.pyd. Is it really this easy, or am I doing something that is unsafe? Thanks, Gerard From roman.yakovenko at gmail.com Fri May 4 21:23:30 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 4 May 2007 22:23:30 +0300 Subject: [C++-sig] Policies again In-Reply-To: <200705031630.08286.p.jaroszynski@gmail.com> References: <200705022256.52150.p.jaroszynski@gmail.com> <200705031630.08286.p.jaroszynski@gmail.com> Message-ID: <7465b6170705041223g624c4c2dp16d0905df21d5ac6@mail.gmail.com> On 5/3/07, Piotr Jaroszynski wrote: > On Wednesday 02 of May 2007 22:56:51 Piotr Jaroszynski wrote: > > Let me show you my current problem: > To be even more precise: > > #include > namespace bp = boost::python; > > struct Blah; > > struct Foo { > Blah * b; > Foo(Blah * blah) : b(blah) { } > }; > > struct Blah_f { > Foo * f; > Blah_f(Blah * blah) : f(new Foo(blah)) { } > }; > > struct Blah : Blah_f { > Blah() : Blah_f(this) { } > }; > > BOOST_PYTHON_MODULE(policies) > { > bp::register_ptr_to_python(); > bp::class_ f("Foo", bp::no_init); > bp::class_ b("Blah"); > b.add_property("f", bp::make_getter(&Blah::f, > bp::return_internal_reference<>())); > } > > You will probably ask where is the big difference... So when using the > return_internal_reference policy, which is probably wrong anyway, I get: > Traceback (most recent call last): > File "./test.py", line 5, in ? > print Blah().f > Boost.Python.ArgumentError: Python argument types in > None.None(Blah) > did not match C++ signature: > None(Blah_f {lvalue}) > > I think I should use one of the with_custodian_and_ward variations, but I > couldn't make any of them to even compile. No, return_internal_reference should be fine. I don't remember why, but Py++ generates a wrapper class for you use-case and adds accessor function. Take a look on member variables tester. I attached the generated code. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- A non-text attachment was scrubbed... Name: member_variables.cpp Type: text/x-c++src Size: 20869 bytes Desc: not available URL: From p.jaroszynski at gmail.com Sat May 5 12:30:30 2007 From: p.jaroszynski at gmail.com (Piotr Jaroszynski) Date: Sat, 5 May 2007 12:30:30 +0200 Subject: [C++-sig] Policies again In-Reply-To: <7465b6170705041223g624c4c2dp16d0905df21d5ac6@mail.gmail.com> References: <200705022256.52150.p.jaroszynski@gmail.com> <200705031630.08286.p.jaroszynski@gmail.com> <7465b6170705041223g624c4c2dp16d0905df21d5ac6@mail.gmail.com> Message-ID: <200705051230.31231.p.jaroszynski@gmail.com> On Friday 04 of May 2007 21:23:30 Roman Yakovenko wrote: > No, return_internal_reference should be fine. I don't remember why, > but Py++ generates a wrapper class for you use-case and adds accessor > function. Take a look on member variables tester. I attached the > generated code. Thanks a lot! Making accessors functions did the trick. I wonder whether it can be considered a bug in the make_getter as using: > ? ? b.add_property("f", bp::make_getter(&Blah::f, > ? ? ? ? ?bp::return_internal_reference<>())); results in: > Traceback (most recent call last): > ? File "./test.py", line 5, in ? > ? ? print Blah().f > Boost.Python.ArgumentError: Python argument types in > ? ? None.None(Blah) > did not match C++ signature: > ? ? None(Blah_f {lvalue}) -- Best Regards, Piotr Jaroszynski From s.ramacher at gmx.at Sat May 5 15:03:26 2007 From: s.ramacher at gmx.at (Sebastian Ramacher) Date: Sat, 05 May 2007 15:03:26 +0200 Subject: [C++-sig] [Boost.Python] inconsistent use of function pointer typedef In-Reply-To: <87hcqwkbyp.fsf@grogan.peloton> References: <87hcqwkbyp.fsf@grogan.peloton> Message-ID: David Abrahams wrote: > > This is just a warning fix, right? > Actually not. At least I haven't seen a warning here (msvc-8.0). I just stumbled accross it while using boost::function for convertible_function and got some unresolved symbol errors. From tgbrooks at gmail.com Sat May 5 20:46:21 2007 From: tgbrooks at gmail.com (Tom Brooks) Date: Sat, 5 May 2007 14:46:21 -0400 Subject: [C++-sig] Passing inherited classes back to C++ Message-ID: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> I currently have these C++ classes: class Renderable { public: Renderable(); virtual ~Renderable(); virtual void Draw() = 0; }; class Quad : public Renderable { public: Quad(float x, float y, float h, float w); ~Quad(); void Draw(); }; And I need to expose them to Python. Then, I need to be able to make one in Python, and pass it back to a C++ function as a Renderable*. I made this wrapper class for Renderable: struct RenderableWrap : Renderable, wrapper { public: void Draw() { this->get_override("Draw")(); } }; And I have this Boost.Python code for the Python side: class_("Renderable") .def("Draw",pure_virtual(&Renderable::Draw)) ; class_ >("Quad",init()) .def("Draw",&Quad::Draw) ; But when I pass in a Quad() to my C++ function, I get an error that it can't convert from a Quad to a Renderable*. I have next to no clue how the base class should have been done, since the tutorial and anything else I can find online don't go over what to do for the base class (when there are virtual functions, at least). For example, I don't know if I inherit from Renderable, or RenderableWrap (or both?). I don't know whether the base class needs a wrapper itself (and would it if it had a virtual function?). I'd appreciate any help! -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Sat May 5 20:55:42 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 5 May 2007 21:55:42 +0300 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> Message-ID: <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> On 5/5/07, Tom Brooks wrote: > I currently have these C++ classes: > > class Renderable > { > public: > Renderable(); > virtual ~Renderable(); > virtual void Draw() = 0; > }; > > class Quad : public Renderable > { > public: > Quad(float x, float y, float h, float w); > ~Quad(); > void Draw(); > }; > > And I need to expose them to Python. Then, I need to be able to make one in > Python, and pass it back to a C++ function as a Renderable*. > > I made this wrapper class for Renderable: > > struct RenderableWrap : Renderable, wrapper > { > public: > void Draw() > { > this->get_override("Draw")(); > } > }; > > And I have this Boost.Python code for the Python side: > > class_ boost::noncopyable>("Renderable") > .def("Draw",pure_virtual(&Renderable::Draw)) > ; > > class_ >("Quad",init float>()) > .def("Draw",&Quad::Draw) > ; > > But when I pass in a Quad() to my C++ function, I get an error that it can't > convert from a Quad to a Renderable*. I have next to no clue how the base > class should have been done, since the tutorial and anything else I can find > online don't go over what to do for the base class (when there are virtual > functions, at least). For example, I don't know if I inherit from > Renderable, or RenderableWrap (or both?). I don't know whether the base > class needs a wrapper itself (and would it if it had a virtual function?). > > I'd appreciate any help! Next code was generated by Py++ GUI (http://language-binding.net/pyplusplus/documentation/tutorials/pyplusplus_gui.html) #include "boost/python.hpp" #include "1.h" namespace bp = boost::python; struct Renderable_wrapper : Renderable, bp::wrapper< Renderable > { Renderable_wrapper( ) : Renderable( ) , bp::wrapper< Renderable >(){ // null constructor } virtual void Draw( ){ bp::override func_Draw = this->get_override( "Draw" ); func_Draw( ); } }; struct Quad_wrapper : Quad, bp::wrapper< Quad > { Quad_wrapper(Quad const & arg ) : Quad( arg ) , bp::wrapper< Quad >(){ // copy constructor } Quad_wrapper(float x, float y, float h, float w ) : Quad( x, y, h, w ) , bp::wrapper< Quad >(){ // constructor } virtual void Draw( ) { if( bp::override func_Draw = this->get_override( "Draw" ) ) func_Draw( ); else this->Quad::Draw( ); } void default_Draw( ) { Quad::Draw( ); } }; BOOST_PYTHON_MODULE(pyplusplus){ bp::class_< Renderable_wrapper, boost::noncopyable >( "Renderable" ) .def( bp::init< >() ) .def( "Draw" , bp::pure_virtual( &::Renderable::Draw ) ); bp::class_< Quad_wrapper, bp::bases< Renderable > >( "Quad", bp::init< float, float, float, float >(( bp::arg("x"), bp::arg("y"), bp::arg("h"), bp::arg("w") )) ) .def( "Draw" , &::Quad::Draw , &Quad_wrapper::default_Draw ); } -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From tgbrooks at gmail.com Sat May 5 22:15:40 2007 From: tgbrooks at gmail.com (Tom Brooks) Date: Sat, 5 May 2007 16:15:40 -0400 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> Message-ID: <112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com> Thank you for the fast reply. I would have tried Py++ myself, but I'm unable to install it. I get an error that the .NET framework SDK must be installed in order to build Python extensions when I try to install GCC_XML. I tried to download and install the .NET SDK, but I'm sure if I've really got all of it. I didn't select much for the installation process. Though it is off-topic, any help with this would be nice too. I use Visual Studios C++ express on Windows XP. I have Python 2.4 and the Windows Platform SDK. As for the code, I haven't looked at it in a lot of detail yet, but a simple copy-and-paste gives me a run-time error that I'm calling a pure-virtual function when I call Draw() from the passed in Renderable*. Any more thoughts? On 5/5/07, Roman Yakovenko wrote: > > On 5/5/07, Tom Brooks wrote: > > I currently have these C++ classes: > > > > class Renderable > > { > > public: > > Renderable(); > > virtual ~Renderable(); > > virtual void Draw() = 0; > > }; > > > > class Quad : public Renderable > > { > > public: > > Quad(float x, float y, float h, float w); > > ~Quad(); > > void Draw(); > > }; > > > > And I need to expose them to Python. Then, I need to be able to make one > in > > Python, and pass it back to a C++ function as a Renderable*. > > > > I made this wrapper class for Renderable: > > > > struct RenderableWrap : Renderable, wrapper > > { > > public: > > void Draw() > > { > > this->get_override("Draw")(); > > } > > }; > > > > And I have this Boost.Python code for the Python side: > > > > class_ > boost::noncopyable>("Renderable") > > .def("Draw",pure_virtual(&Renderable::Draw)) > > ; > > > > class_ >("Quad",init float, > > Quad derives from Renderable, not RenderableWrap > > > float>()) > > .def("Draw",&Quad::Draw) > > ; > > > > But when I pass in a Quad() to my C++ function, I get an error that it > can't > > convert from a Quad to a Renderable*. I have next to no clue how the > base > > class should have been done, since the tutorial and anything else I can > find > > online don't go over what to do for the base class (when there are > virtual > > functions, at least). For example, I don't know if I inherit from > > Renderable, or RenderableWrap (or both?). I don't know whether the base > > class needs a wrapper itself (and would it if it had a virtual > function?). > > > > I'd appreciate any help! > > Next code was generated by Py++ GUI > ( > http://language-binding.net/pyplusplus/documentation/tutorials/pyplusplus_gui.html > ) > > #include "boost/python.hpp" > > #include "1.h" > > namespace bp = boost::python; > > struct Renderable_wrapper : Renderable, bp::wrapper< Renderable > { > > Renderable_wrapper( ) > : Renderable( ) > , bp::wrapper< Renderable >(){ > // null constructor > > } > > virtual void Draw( ){ > bp::override func_Draw = this->get_override( "Draw" ); > func_Draw( ); > } > > }; > > struct Quad_wrapper : Quad, bp::wrapper< Quad > { > > Quad_wrapper(Quad const & arg ) > : Quad( arg ) > , bp::wrapper< Quad >(){ > // copy constructor > > } > > Quad_wrapper(float x, float y, float h, float w ) > : Quad( x, y, h, w ) > , bp::wrapper< Quad >(){ > // constructor > > } > > virtual void Draw( ) { > if( bp::override func_Draw = this->get_override( "Draw" ) ) > func_Draw( ); > else > this->Quad::Draw( ); > } > > > void default_Draw( ) { > Quad::Draw( ); > } > > }; > > BOOST_PYTHON_MODULE(pyplusplus){ > bp::class_< Renderable_wrapper, boost::noncopyable >( "Renderable" ) > .def( bp::init< >() ) > .def( > "Draw" > , bp::pure_virtual( &::Renderable::Draw ) ); > > bp::class_< Quad_wrapper, bp::bases< Renderable > >( "Quad", > bp::init< float, float, float, float >(( bp::arg("x"), bp::arg("y"), > bp::arg("h"), bp::arg("w") )) ) > .def( > "Draw" > , &::Quad::Draw > , &Quad_wrapper::default_Draw ); > } > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Sun May 6 07:12:47 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 6 May 2007 08:12:47 +0300 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> <112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com> Message-ID: <7465b6170705052212p7ac075q4ea2c042577002a0@mail.gmail.com> On 5/5/07, Tom Brooks wrote: > Thank you for the fast reply. I would have tried Py++ myself, but I'm unable > to install it. I get an error that the .NET framework SDK must be installed > in order to build Python extensions when I try to install GCC_XML. I tried > to download and install the .NET SDK, but I'm sure if I've really got all of > it. I didn't select much for the installation process. Though it is > off-topic, any help with this would be nice too. I use Visual Studios C++ > express on Windows XP. I have Python 2.4 and the Windows Platform SDK. > > As for the code, I haven't looked at it in a lot of detail yet, but a simple > copy-and-paste gives me a run-time error that I'm calling a pure-virtual > function when I call Draw() from the passed in Renderable*. Any more > thoughts? Please provide a complete example -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From tgbrooks at gmail.com Sun May 6 11:12:43 2007 From: tgbrooks at gmail.com (Tom Brooks) Date: Sun, 6 May 2007 05:12:43 -0400 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <7465b6170705052212p7ac075q4ea2c042577002a0@mail.gmail.com> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> <112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com> <7465b6170705052212p7ac075q4ea2c042577002a0@mail.gmail.com> Message-ID: <112c5ffc0705060212q519a6593x665d3a2293de8a29@mail.gmail.com> I run this python code: quad = Renderer.Quad(250, 250, 64,64) c = Renderer.Color() Renderer.AddRenderable(quad) #Removing this line makes it not crash AddRenderable does: renderables.push_back(renderable); And later that frame, this is done: for(std::list::iterator itr = renderables.begin(); itr != renderables.end(); itr++) { Renderable* renderable = *itr; renderable->Draw(); //It crashes here! With error "R6025: pure virtual function call". } I use your Py++ code (only thing changed is it's namespace, which is now Renderer), along with: def("AddRenderable",&AddRenderable); in the Renderer namespace. My C++ code runs just fine if I don't use anything from Python. There, I think that's complete. On 5/6/07, Roman Yakovenko wrote: > > On 5/5/07, Tom Brooks wrote: > > Thank you for the fast reply. I would have tried Py++ myself, but I'm > unable > > to install it. I get an error that the .NET framework SDK must be > installed > > in order to build Python extensions when I try to install GCC_XML. I > tried > > to download and install the .NET SDK, but I'm sure if I've really got > all of > > it. I didn't select much for the installation process. Though it is > > off-topic, any help with this would be nice too. I use Visual Studios > C++ > > express on Windows XP. I have Python 2.4 and the Windows Platform SDK. > > > > As for the code, I haven't looked at it in a lot of detail yet, but a > simple > > copy-and-paste gives me a run-time error that I'm calling a pure-virtual > > function when I call Draw() from the passed in Renderable*. Any more > > thoughts? > > Please provide a complete example > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Sun May 6 11:22:09 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 6 May 2007 12:22:09 +0300 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <112c5ffc0705060212q519a6593x665d3a2293de8a29@mail.gmail.com> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> <112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com> <7465b6170705052212p7ac075q4ea2c042577002a0@mail.gmail.com> <112c5ffc0705060212q519a6593x665d3a2293de8a29@mail.gmail.com> Message-ID: <7465b6170705060222x67a4b5dvd0e525c3c0deb9f1@mail.gmail.com> On 5/6/07, Tom Brooks wrote: > I run this python code: > > quad = Renderer.Quad(250, 250, 64,64) > c = Renderer.Color() > Renderer.AddRenderable(quad) #Removing this line makes it not crash > > AddRenderable does: > renderables.push_back(renderable); > > And later that frame, this is done: > for(std::list::iterator itr = > renderables.begin(); itr != renderables.end(); itr++) > { > Renderable* renderable = *itr; > renderable->Draw(); //It crashes here! With error "R6025: pure > virtual function call". > } > > I use your Py++ code (only thing changed is it's namespace, which is now > Renderer), along with: > > def("AddRenderable",&AddRenderable); > > in the Renderer namespace. > > My C++ code runs just fine if I don't use anything from Python. > > There, I think that's complete. This is not a complete example, but it allows to make a guess - memory management. To prove this, try to hold a reference to "quad" variable somewhere in Python and run the code. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From tgbrooks at gmail.com Sun May 6 11:37:34 2007 From: tgbrooks at gmail.com (Tom Brooks) Date: Sun, 6 May 2007 05:37:34 -0400 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <7465b6170705060222x67a4b5dvd0e525c3c0deb9f1@mail.gmail.com> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> <112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com> <7465b6170705052212p7ac075q4ea2c042577002a0@mail.gmail.com> <112c5ffc0705060212q519a6593x665d3a2293de8a29@mail.gmail.com> <7465b6170705060222x67a4b5dvd0e525c3c0deb9f1@mail.gmail.com> Message-ID: <112c5ffc0705060237l430a861emd259215a5cee0a62@mail.gmail.com> Wow, that was a great guess! I kept a reference to the quad in Python, and it all went fine. The FAQ has a part about just this situation, so I think I'm all set now. Thanks a bunch for the help! BTW, for future reference, what else would you have wanted to see? On 5/6/07, Roman Yakovenko wrote: > > On 5/6/07, Tom Brooks wrote: > > I run this python code: > > > > quad = Renderer.Quad(250, 250, 64,64) > > c = Renderer.Color() > > Renderer.AddRenderable(quad) #Removing this line makes it not crash > > > > AddRenderable does: > > renderables.push_back(renderable); > > > > And later that frame, this is done: > > for(std::list::iterator itr = > > renderables.begin(); itr != renderables.end(); itr++) > > { > > Renderable* renderable = *itr; > > renderable->Draw(); //It crashes here! With error "R6025: pure > > virtual function call". > > } > > > > I use your Py++ code (only thing changed is it's namespace, which is now > > Renderer), along with: > > > > def("AddRenderable",&AddRenderable); > > > > in the Renderer namespace. > > > > My C++ code runs just fine if I don't use anything from Python. > > > > There, I think that's complete. > > This is not a complete example, but it allows to make a guess - memory > management. > To prove this, try to hold a reference to "quad" variable somewhere in > Python and run the code. > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ngoodspeed at solidworks.com Sun May 6 19:03:37 2007 From: ngoodspeed at solidworks.com (Nat Goodspeed) Date: Sun, 6 May 2007 13:03:37 -0400 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <112c5ffc0705060237l430a861emd259215a5cee0a62@mail.gmail.com> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com><7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com><112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com><7465b6170705052212p7ac075q4ea2c042577002a0@mail.gmail.com><112c5ffc0705060212q519a6593x665d3a2293de8a29@mail.gmail.com><7465b6170705060222x67a4b5dvd0e525c3c0deb9f1@mail.gmail.com> <112c5ffc0705060237l430a861emd259215a5cee0a62@mail.gmail.com> Message-ID: <94F7A8DD4408D8499C6812FE42E2D4B7011FCC7A@corp-mail4.solidworks.swk> ________________________________________ From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On Behalf Of Tom Brooks Sent: Sunday, May 06, 2007 5:38 AM To: Development of Python/C++ integration Subject: Re: [C++-sig] Passing inherited classes back to C++ BTW, for future reference, what else would you have wanted to see? [Nat] Roman, forgive me for putting words in your mouth. Tom, I think he's requesting that you attach complete, minimal source files to your mail message that he could save to some work directory, build and execute to see (and possibly debug) the behavior you describe. Providing snippets of the crucial code in your mail message is helpful, and sometimes it's enough. But other times someone wants to help, can't guess the problem from your description and doesn't have time to write the boilerplate code into which to paste your snippets. In such cases, attaching complete (minimal) source files encourages them to test your program anyway. For other kinds of questions, e.g. compilation errors, sometimes the failing code snippet is fine by itself and the problem has to do with missing (or badly-ordered) #include statements. Unless both parties see the whole source file, you can get replies of the form "It works for me" even while you're saying, "But it's still broken for me." From roman.yakovenko at gmail.com Sun May 6 20:09:50 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 6 May 2007 21:09:50 +0300 Subject: [C++-sig] Passing inherited classes back to C++ In-Reply-To: <94F7A8DD4408D8499C6812FE42E2D4B7011FCC7A@corp-mail4.solidworks.swk> References: <112c5ffc0705051146h5c980458pf411338a3413f3be@mail.gmail.com> <7465b6170705051155s3c3b2b4r692875e03c610779@mail.gmail.com> <112c5ffc0705051315h48b41513sa8e7952c7abcdbb9@mail.gmail.com> <7465b6170705052212p7ac075q4ea2c042577002a0@mail.gmail.com> <112c5ffc0705060212q519a6593x665d3a2293de8a29@mail.gmail.com> <7465b6170705060222x67a4b5dvd0e525c3c0deb9f1@mail.gmail.com> <112c5ffc0705060237l430a861emd259215a5cee0a62@mail.gmail.com> <94F7A8DD4408D8499C6812FE42E2D4B7011FCC7A@corp-mail4.solidworks.swk> Message-ID: <7465b6170705061109ja36fec3m7717c1d92a6f72b9@mail.gmail.com> On 5/6/07, Nat Goodspeed wrote: > ________________________________________ > From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On > Behalf Of Tom Brooks > Sent: Sunday, May 06, 2007 5:38 AM > To: Development of Python/C++ integration > Subject: Re: [C++-sig] Passing inherited classes back to C++ > > BTW, for future reference, what else would you have wanted to see? > > [Nat] Roman, forgive me for putting words in your mouth. > > Tom, I think he's requesting that you attach complete, minimal source > files to your mail message that he could save to some work directory, > build and execute to see (and possibly debug) the behavior you describe. No, I don't like to help people, brrr :-). The purpose of small and complete example to force people to help them self. In most cases we deal with complex libraries and dependencies - extracting the exact use-case that fails, it is a half way to solution. Also I agree with you it is much easier to see the problem when you see small and complete source code( C++ and Python ). -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From fullung at gmail.com Sun May 6 20:44:55 2007 From: fullung at gmail.com (Albert Strasheim) Date: Sun, 6 May 2007 20:44:55 +0200 Subject: [C++-sig] more examples of automatic type conversion In-Reply-To: <7465b6170705030408geea84b4ib2c4e52e4b957a07@mail.gmail.com> References: <1178108758.13074.4.camel@convolution.mit.edu> <7465b6170705020632g29b04f5eoce3608934f8265c7@mail.gmail.com> <20070503083351.GA5134@dogbert.sdsl.sun.ac.za> <7465b6170705030408geea84b4ib2c4e52e4b957a07@mail.gmail.com> Message-ID: <20070506184455.GA15374@dogbert.sdsl.sun.ac.za> Hello all On Thu, 03 May 2007, Roman Yakovenko wrote: > On 5/3/07, Albert Strasheim wrote: > >Anyway, I've more or less got pass-by-value and return-by-value working > >using Roman's example, but I can't quite figure out how to make > >Boost.Python convert pointer and reference arguments or return values > >into PyObject*'s using the same scheme. Should this just work if I have > >my automatic conversion set up correctly, or is there additional magic > >that needs to be added? Again, it would be *very* useful if copying > >could be avoided here. > > > Post small example, may be I will be able to help To recap, the idea is to wrap classes with member functions that take uBLAS vectors or matrices by value, (const) reference and (const) pointer. However, on the Python side one always wants to pass in a NumPy array which should be converted on the fly. Using an appropriate array adaptor, one should be able to construct a uBLAS matrix that reused the NumPy array's underlying data buffer without copying (except in special cases which I won't go into now). Similarly, for (const) pointer or (const) reference returns, one wants to wrap a new NumPy array around the return value so that the Python side always sees a NumPy array. Again, copying should be avoided. For the return_internal_reference case, it would be nice if the object "owning" the matrix being returned could be kept alive until all NumPy arrays that refer to the data are deleted. In the manage_new_object case, the array_adaptor in the array being returned can be told to give up the ownership of the data and then uBLAS matrix can be deallocated immediately (effectively only destroying a few bits and pieces). I expect some complications here if you have a NumPy array taking over ownership of a data buffer allocated in C++ code, so I guess one would have to look at an array_adaptor that allocates the matrix's storage as a NumPy array which can be "extracted" when returning to Python. Here's some code that shows what I'm trying to using tuples instead of NumPy arrays and array_t instead of uBLAS matrices. #include #include namespace py = boost::python; struct array_t { int rows; int cols; void* data; array_t(int rows_, int cols_) : rows(rows_), cols(cols_), data(0){} array_t() : rows(0), cols(0), data(0){} }; struct array_converter { static void register_to_and_from_python() { register_from_python(); register_to_python(); } static void register_to_python() { py::to_python_converter(); } static void register_from_python() { py::converter::registry::push_back( &array_converter::convertible, &array_converter::construct, py::type_id()); } static void* convertible(PyObject* obj) { return PyTuple_Check(obj) != 0 ? obj : 0; } static void construct(PyObject* obj, py::converter::rvalue_from_python_stage1_data* data) { // get the storage typedef py::converter::rvalue_from_python_storage storage_t; storage_t* the_storage = reinterpret_cast(data); void* memory_chunk = the_storage->storage.bytes; // placement new int rows = PyInt_AsLong(PyTuple_GET_ITEM(obj, 0)); int cols = PyInt_AsLong(PyTuple_GET_ITEM(obj, 1)); // XXX get data pointer here array_t* a = new (memory_chunk) array_t(rows, cols); data->convertible = memory_chunk; } static PyObject* convert(const array_t& a) { return py::incref(py::make_tuple(a.rows, a.cols).ptr()); } }; struct array_test { array_test() : data_(3, 4){} array_t value_return() const { return data_; } array_t const* const_pointer_return() const { return &data_; } array_t* pointer_return() { return &data_; } array_t const& const_ref_return() const { return data_; } array_t& ref_return() { return data_; } void value_arg(array_t a) { print(a); } void pointer_arg(array_t* a) { print(*a); } void const_pointer_arg(array_t const* a){} void ref_arg(array_t& a){} void const_ref_arg(array_t const& a){} private: void print(array_t const& a) { std::cout << "(" << a.rows << ", " << a.cols << ")" << std::endl; } array_t data_; }; BOOST_PYTHON_MODULE(pyublas) { array_converter::register_to_and_from_python(); py::class_("array_test") .def("value_return", &array_test::value_return) .def("const_pointer_return", &array_test::const_pointer_return, py::return_internal_reference<>()) #if 0 .def("pointer_return", &array_test::pointer_return) .def("const_ref_return", &array_test::const_ref_return) .def("ref_return", &array_test::ref_return) #endif .def("value_arg", &array_test::value_arg) .def("pointer_arg", &array_test::pointer_arg) #if 0 .def("const_pointer_arg", &array_test::const_pointer_arg) .def("ref_arg", &array_test::ref_arg) .def("const_ref_arg", &array_test::const_ref_arg) #endif ; } And the Python code import pyublas print pyublas print dir(pyublas) at = pyublas.array_test() print at print at.value_return() # XXX this doesn't work yet print at.const_pointer_return() a = (10, 20) at.value_arg(a) # XXX this doesn't work yet at.pointer_arg(a) The call to const_pointer_return raises the following error: Traceback (most recent call last): File "test_pyublas.py", line 24, in ? print at.const_pointer_return() TypeError: No Python class registered for C++ class struct array_t The call to pointer_arg raises the following error: Traceback (most recent call last): File "test_pyublas.py", line 28, in ? at.pointer_arg(a) Boost.Python.ArgumentError: Python argument types in array_test.pointer_arg(array_test, tuple) did not match C++ signature: pointer_arg(struct array_test {lvalue}, struct array_t *) In both cases, I would like conversions to happen from the PyObjects to the expected C++ data structures. Is it possible to convince Boost.Python to do this? Thanks for any feedback. Cheers, Albert From fullung at gmail.com Mon May 7 12:10:35 2007 From: fullung at gmail.com (Albert Strasheim) Date: Mon, 7 May 2007 12:10:35 +0200 Subject: [C++-sig] more examples of automatic type conversion In-Reply-To: <20070506184455.GA15374@dogbert.sdsl.sun.ac.za> References: <1178108758.13074.4.camel@convolution.mit.edu> <7465b6170705020632g29b04f5eoce3608934f8265c7@mail.gmail.com> <20070503083351.GA5134@dogbert.sdsl.sun.ac.za> <7465b6170705030408geea84b4ib2c4e52e4b957a07@mail.gmail.com> <20070506184455.GA15374@dogbert.sdsl.sun.ac.za> Message-ID: <20070507101035.GA22718@dogbert.sdsl.sun.ac.za> Hello all On Sun, 06 May 2007, Albert Strasheim wrote: > Hello all > > On Thu, 03 May 2007, Roman Yakovenko wrote: > > > On 5/3/07, Albert Strasheim wrote: > > > >Anyway, I've more or less got pass-by-value and return-by-value working > > >using Roman's example, but I can't quite figure out how to make > > >Boost.Python convert pointer and reference arguments or return values > > >into PyObject*'s using the same scheme. Should this just work if I have > > >my automatic conversion set up correctly, or is there additional magic > > >that needs to be added? Again, it would be *very* useful if copying > > >could be avoided here. > > > > > > Post small example, may be I will be able to help > Looks like SWIG typemaps do exactly what I want in this case. Cheers, Albert From dave at boost-consulting.com Mon May 7 21:24:22 2007 From: dave at boost-consulting.com (David Abrahams) Date: Mon, 07 May 2007 15:24:22 -0400 Subject: [C++-sig] [Boost.Python] inconsistent use of function pointer typedef References: <87hcqwkbyp.fsf@grogan.peloton> Message-ID: <878xc0sahl.fsf@grogan.peloton> on Sat May 05 2007, Sebastian Ramacher wrote: > David Abrahams wrote: >> >> This is just a warning fix, right? >> > > Actually not. At least I haven't seen a warning here (msvc-8.0). > I just stumbled accross it while using boost::function for > convertible_function and got some unresolved symbol errors. I'm sorry, I don't understand. Is this a bugfix, or a stylistic improvement, or something else? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com From roman.yakovenko at gmail.com Tue May 8 06:19:47 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 8 May 2007 07:19:47 +0300 Subject: [C++-sig] [ANN]Py++ 0.9.0 In-Reply-To: <7465b6170705072119x410cb33cq50f88eb1baba11c6@mail.gmail.com> References: <7465b6170705072112q639a50acwcda287e7b4ffb103@mail.gmail.com> <7465b6170705072119x410cb33cq50f88eb1baba11c6@mail.gmail.com> Message-ID: <7465b6170705072119u429f9e82h153b309f3912241e@mail.gmail.com> Hello! I'm pleased to announce the 0.9.0 release of Py++. What is Py++? ============= Py++ is an object-oriented framework for creating a code generator for Boost.Python library. Where is Py++? ============== Site: http://language-binding.net/pyplusplus/pyplusplus.html Download: http://language-binding.net/pyplusplus/download.html What's new? =========== Features -------- * Added exposing of copy constructor, ``operator=`` and ``operator<<``. * ``operator=`` is exposed under "assign" name * ``operator<<`` is exposed under "__str__" name * Added new call policies: * as_tuple * custom_call_policies * return_range * Added an initial support for multi-module development. Now you can mark your declarations as ``already_exposed`` and `Py++`_ will do the rest. * `input_c_buffer`_ - new functions transformation, which allows to pass a Python sequence to C++ function, instead of pair of arguments: pointer to buffer and size. * Added ability to control generated "include" directives. Now you can ask Py++ to include a header file, when it generates code for some declaration. * Code generation improvements: system header files (Boost.Python or Py++ defined) will be included from the generated files only in case the generated code depends on them. * Performance: Py++ runs 1.5 - 2 times faster. * Py++ will generate documentation for automatically constructed properties. * Added iteration functionality to Boost.Python Indexing Suite V2 ``std::map`` and ``std::multimap`` containers. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From bruce.who.hk at gmail.com Tue May 8 14:20:54 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Tue, 8 May 2007 20:20:54 +0800 Subject: [C++-sig] Why this does not work- overriding C++ virtual functions in python script? Message-ID: Hi, all I have managed to get a python wrapper for my Cpp modules, but there is something wrong. This is my cpp files: // cmod.h file #ifndef __CMOD_H #define __CMOD_H class EventHandler { public: virtual void OnEvent(){} virtual ~EventHandler(){} }; void func(void); void setEventHandler(EventHandler* pEH); #endif // cmod.cpp file #include "cmod.h" static EventHandler* s_pEH; void func(void) { if(s_pEH != NULL) { printf("call OnEvent"); s_pEH->OnEvent(); } } void setEventHandler(EventHandler* pEH) { s_pEH = pEH; } // cmod.i file %module cmod %include "cmod.h" %inline %{ #include "cmod.h" %} and I compile all these files with Visual Studio 2005: swig -c++ -python cmod.i cl -c cmod_wrap.cxx -ID:\program\Python25\include\ cl -c cmod.cpp link /subsystem:windows /LIBPATH:D:\program\Python25\libs\ cmod_wrap.obj cmod.obj /dll /OUT:_cmod.pyd and then we can get cmod.py and _cmod.pyd. I write a python script: # testcmod.py file import cmod class EventHandler(cmod.EventHandler): def OnEvent(self): print 'called' eh = EventHandler() cmod.setEventHandler(eh) cmod.func() Once this script runs, it is supposed to print 'called' but it does not! I guess that if we cannot override C++ virtual functions in python script? Hope someone can help me. Any help would be appreciated! Bruce From nitro at dr-code.org Tue May 8 14:52:48 2007 From: nitro at dr-code.org (Nitro) Date: Tue, 08 May 2007 14:52:48 +0200 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtual functions in python script? In-Reply-To: References: Message-ID: Am 08.05.2007, 14:20 Uhr, schrieb Bruce Who : > Hi, all > > I have managed to get a python wrapper for my Cpp modules, but there > is something wrong. > > This is my cpp files: > > // cmod.h file > #ifndef __CMOD_H > #define __CMOD_H > > class EventHandler > { > public: > virtual void OnEvent(){} > virtual ~EventHandler(){} > }; > > void func(void); > > void setEventHandler(EventHandler* pEH); > > #endif > > // cmod.cpp file > #include "cmod.h" > > static EventHandler* s_pEH; > > void func(void) > { > if(s_pEH != NULL) > { > printf("call OnEvent"); > s_pEH->OnEvent(); > } > } > > void setEventHandler(EventHandler* pEH) > { > s_pEH = pEH; > } > > // cmod.i file > %module cmod > %include "cmod.h" > > > %inline %{ > #include "cmod.h" > > %} > > > and I compile all these files with Visual Studio 2005: > > swig -c++ -python cmod.i > cl -c cmod_wrap.cxx -ID:\program\Python25\include\ > cl -c cmod.cpp > link /subsystem:windows /LIBPATH:D:\program\Python25\libs\ > cmod_wrap.obj cmod.obj /dll /OUT:_cmod.pyd > > and then we can get cmod.py and _cmod.pyd. I write a python script: > > # testcmod.py file > import cmod > > class EventHandler(cmod.EventHandler): > def OnEvent(self): > print 'called' > > eh = EventHandler() > cmod.setEventHandler(eh) > cmod.func() > > > Once this script runs, it is supposed to print 'called' but it does > not! I guess that if we cannot override C++ virtual functions in > python script? Hope someone can help me. Any help would be > appreciated! Read the "directors" part of the manual. -Matthias From fullung at gmail.com Tue May 8 23:45:43 2007 From: fullung at gmail.com (Albert Strasheim) Date: Tue, 8 May 2007 23:45:43 +0200 Subject: [C++-sig] Automatic type conversion again Message-ID: <20070508214542.GA1577@dogbert.sdsl.sun.ac.za> Hello all Referring to Roman's excellent guide here: http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html Is there any way to allow conversion of PyObject* when passing to functions that expect references or pointers? In Roman's code he explicitly checks that doing this throws a TypeError: http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/test.py.html e.g. self.failUnlessRaises( TypeError, tuples.test_triplet_ref_110, (1,1,0) ) I can do this with SWIG typemaps, but SWIG doesn't seem to have a built-in equivalent for return_internal_reference or with_custodian_and_ward_postcall, so I'd like to stick to using Boost.Python if at all possible. Any advice would be appreciated. Thanks. Cheers, Albert From bruce.who.hk at gmail.com Wed May 9 03:13:18 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Wed, 9 May 2007 09:13:18 +0800 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtual functions in python script? In-Reply-To: References: Message-ID: Hi, Nitro Thanks for your clue. I've added "directors" to my .i file: %module(directors="1") cmod %feature("director"); but it seems that Visual Studio2005 doesnot support this, and it fails to compile: f:\swigproj\cmod_wrap.cxx(2733) : error C2039: 'unexpected_handler' : is not a member of 'std' f:\swigproj\cmod_wrap.cxx(2734) : error C2039: 'unexpected_handler' : is not a member of 'std' I look at the source code and find that it has something to do with directors. Is there any workaround? On 5/8/07, Nitro wrote: > Am 08.05.2007, 14:20 Uhr, schrieb Bruce Who : > >> > > Read the "directors" part of the manual. > > -Matthias > From s.somani at fincad.com Wed May 9 03:37:19 2007 From: s.somani at fincad.com (Sohail Somani) Date: Tue, 8 May 2007 18:37:19 -0700 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtualfunctions in python script? In-Reply-To: References: Message-ID: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> You probably need to #include or in the generated code. > -----Original Message----- > From: swig-user-bounces at lists.sourceforge.net > [mailto:swig-user-bounces at lists.sourceforge.net] On Behalf Of > Bruce Who > Sent: Tuesday, May 08, 2007 6:13 PM > To: Nitro > Cc: swig-user; c++-sig of python > Subject: Re: [Swig-user] Why this does not work- overriding > C++ virtualfunctions in python script? > > Hi, Nitro > > Thanks for your clue. I've added "directors" to my .i file: > > %module(directors="1") cmod > %feature("director"); > > but it seems that Visual Studio2005 doesnot support this, and it fails > to compile: > > f:\swigproj\cmod_wrap.cxx(2733) : error C2039: 'unexpected_handler' : > is not a member of 'std' > f:\swigproj\cmod_wrap.cxx(2734) : error C2039: 'unexpected_handler' : > is not a member of 'std' > > I look at the source code and find that it has something to do with > directors. Is there any workaround? > > On 5/8/07, Nitro wrote: > > Am 08.05.2007, 14:20 Uhr, schrieb Bruce Who > : > > > >> > > > > Read the "directors" part of the manual. > > > > -Matthias > > > > -------------------------------------------------------------- > ----------- > This SF.net email is sponsored by DB2 Express > Download DB2 Express C - the FREE version of DB2 express and take > control of your XML. No limits. Just data. Click to get it now. > http://sourceforge.net/powerbar/db2/ > _______________________________________________ > Swig-user mailing list > Swig-user at lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/swig-user > From bruce.who.hk at gmail.com Wed May 9 04:13:39 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Wed, 9 May 2007 10:13:39 +0800 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtualfunctions in python script? In-Reply-To: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> References: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> Message-ID: I add #include in the generated .cxx file and removed std namespace before exceptions and it compiles. I donnot know why. But my code still doesnot work! My OnEvent() event is still not called. Does that mean director doesnot work for me? On 5/9/07, Sohail Somani wrote: > You probably need to #include or in the > generated code. > > > -----Original Message----- > > From: swig-user-bounces at lists.sourceforge.net > > [mailto:swig-user-bounces at lists.sourceforge.net] On Behalf Of > > Bruce Who > > Sent: Tuesday, May 08, 2007 6:13 PM > > To: Nitro > > Cc: swig-user; c++-sig of python > > Subject: Re: [Swig-user] Why this does not work- overriding > > C++ virtualfunctions in python script? > > > > Hi, Nitro > > > > Thanks for your clue. I've added "directors" to my .i file: > > > > %module(directors="1") cmod > > %feature("director"); > > > > but it seems that Visual Studio2005 doesnot support this, and it fails > > to compile: > > > > f:\swigproj\cmod_wrap.cxx(2733) : error C2039: 'unexpected_handler' : > > is not a member of 'std' > > f:\swigproj\cmod_wrap.cxx(2734) : error C2039: 'unexpected_handler' : > > is not a member of 'std' > > > > I look at the source code and find that it has something to do with > > directors. Is there any workaround? > > > > On 5/8/07, Nitro wrote: > > > Am 08.05.2007, 14:20 Uhr, schrieb Bruce Who > > : > > > > > >> > > > > > > Read the "directors" part of the manual. > > > > > > -Matthias > > > > > > > -------------------------------------------------------------- > > ----------- > > This SF.net email is sponsored by DB2 Express > > Download DB2 Express C - the FREE version of DB2 express and take > > control of your XML. No limits. Just data. Click to get it now. > > http://sourceforge.net/powerbar/db2/ > > _______________________________________________ > > Swig-user mailing list > > Swig-user at lists.sourceforge.net > > https://lists.sourceforge.net/lists/listinfo/swig-user > > > Bruce From roman.yakovenko at gmail.com Wed May 9 05:51:04 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 9 May 2007 06:51:04 +0300 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtualfunctions in python script? In-Reply-To: References: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> Message-ID: <7465b6170705082051k6f55ff0chd79bd2729b5c4d54@mail.gmail.com> I have nothing again SWIG, but can you move this discussion to its mailing list? It has nothing to do with Boost.Python. Thanks On 5/9/07, Bruce Who wrote: > I add #include in the generated .cxx file and removed std > namespace before exceptions and it compiles. I donnot know why. But my > code still doesnot work! My OnEvent() event is still not called. Does > that mean director doesnot work for me? > > On 5/9/07, Sohail Somani wrote: > > You probably need to #include or in the > > generated code. > > > > > -----Original Message----- > > > From: swig-user-bounces at lists.sourceforge.net > > > [mailto:swig-user-bounces at lists.sourceforge.net] On Behalf Of > > > Bruce Who > > > Sent: Tuesday, May 08, 2007 6:13 PM > > > To: Nitro > > > Cc: swig-user; c++-sig of python > > > Subject: Re: [Swig-user] Why this does not work- overriding > > > C++ virtualfunctions in python script? > > > > > > Hi, Nitro > > > > > > Thanks for your clue. I've added "directors" to my .i file: > > > > > > %module(directors="1") cmod > > > %feature("director"); > > > > > > but it seems that Visual Studio2005 doesnot support this, and it fails > > > to compile: > > > > > > f:\swigproj\cmod_wrap.cxx(2733) : error C2039: 'unexpected_handler' : > > > is not a member of 'std' > > > f:\swigproj\cmod_wrap.cxx(2734) : error C2039: 'unexpected_handler' : > > > is not a member of 'std' > > > > > > I look at the source code and find that it has something to do with > > > directors. Is there any workaround? > > > > > > On 5/8/07, Nitro wrote: > > > > Am 08.05.2007, 14:20 Uhr, schrieb Bruce Who > > > : > > > > > > > >> > > > > > > > > Read the "directors" part of the manual. > > > > > > > > -Matthias > > > > > > > > > > -------------------------------------------------------------- > > > ----------- > > > This SF.net email is sponsored by DB2 Express > > > Download DB2 Express C - the FREE version of DB2 express and take > > > control of your XML. No limits. Just data. Click to get it now. > > > http://sourceforge.net/powerbar/db2/ > > > _______________________________________________ > > > Swig-user mailing list > > > Swig-user at lists.sourceforge.net > > > https://lists.sourceforge.net/lists/listinfo/swig-user > > > > > > > Bruce > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Wed May 9 06:48:52 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 9 May 2007 07:48:52 +0300 Subject: [C++-sig] Automatic type conversion again In-Reply-To: <20070508214542.GA1577@dogbert.sdsl.sun.ac.za> References: <20070508214542.GA1577@dogbert.sdsl.sun.ac.za> Message-ID: <7465b6170705082148t386f92bgacfe5731c4bcae65@mail.gmail.com> On 5/9/07, Albert Strasheim wrote: > Hello all > > Referring to Roman's excellent guide here: > > http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/automatic_conversion.html > > Is there any way to allow conversion of PyObject* when passing to > functions that expect references or pointers? In Roman's code he > explicitly checks that doing this throws a TypeError: > > http://www.language-binding.net/pyplusplus/troubleshooting_guide/automatic_conversion/test.py.html > > e.g. > > self.failUnlessRaises( TypeError, tuples.test_triplet_ref_110, (1,1,0) ) > > I can do this with SWIG typemaps, but SWIG doesn't seem to have a > built-in equivalent for return_internal_reference or > with_custodian_and_ward_postcall, so I'd like to stick to using > Boost.Python if at all possible. Memory management is pretty good reason to stick with Boost.Python. The short answer - you cannot, the long answer - I believe it is possible to find acceptable solution to the problem ( may be not ). I could be wrong! You cannot, because an automatic conversion creates temporal object, so the changes you do to it in the function cannot be propagated to Python. There are few possible work around. The first on is to use decorators. Every relevant exported function should have a decorator, which will normalize argument types. Explanation: Lets say your function takes YourArray*, while user gave you an instance of ItsArray type as argument. You can create new function that will create new YourArray instance from ItsArray. You can define it as: boost::python::object Its2YourArrayConverter( boost::python::object ); Also you create new YourArray instance, it doesn't necessary means that you copy array content. You can use call policies to bind between objects ( return and argument ) life time. Thus you don't use "automatic conversion". Using Python magic you can apply this decorator on every relevant function. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From neworderofjamie at gmail.com Wed May 9 13:23:36 2007 From: neworderofjamie at gmail.com (James Knight) Date: Wed, 9 May 2007 12:23:36 +0100 Subject: [C++-sig] Wrapping std::map using Boost::Python Message-ID: <9fadca7e0705090423h4fdf20fcs84eee57bb090ca64@mail.gmail.com> Hi, I'm trying to wrap std::map using boost::python so my embedded python code can access maps. I have the following wrapper class: //Map - takes e.g std::map as MapType template struct MapItem { //Typedefine the key and value types for ease typedef typename MapType::key_type KeyType; typedef typename MapType::mapped_type ValueType; static ValueType& Get(MapType & x,KeyType const& i) { if( x.find(i) != x.end() ) return x[i]; //Some kind of error! } static void Set(MapType & x,KeyType const& i,ValueType const& v) { x[i]=v; // use map autocreation feature } static void Del(MapType & x,KeyType const& i) { if( x.find(i) != x.end() ) x.erase(i); } } And the following Boost::Python class definition to wrap a particular map: [source lang="cpp"] boost::python::class_ >("SubGridMap") .def("__len__",&std::map::size) .def("clear",&std::map::clear) .def("__getitem__",&MapItem >::Get,boost::python::return_value_policy()) .def("__setitem__",&MapItem >::Set,boost::python::with_custodian_and_ward<1,2>()) // to let container keep value .def("__delitem__",&MapItem >::Del) ; I really need iterator support and following the Python Wiki entry on STL containers, have written a function like this to convert the std::map to a std::list of tuples as boost::python::iterator doesn't seem to be compatible with std::map (which seems a bit icky but makes sense): static std::list > Items(MapType const& x) { std::list > t; typename MapType::const_iterator it; for(it=x.begin(); it!=x.end(); ++it) t.push_back(boost::make_tuple(it->first,it->second)); return t; } But the wiki entry irritatingly stops short of telling you how the hell you wrap it into an __iter__ and the attachement to the wiki entry seems to be empty...Has anyone done this or have any ideas? Cheers Jamie -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Wed May 9 14:32:53 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 09 May 2007 08:32:53 -0400 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtualfunctions in python script? In-Reply-To: <7465b6170705082051k6f55ff0chd79bd2729b5c4d54@mail.gmail.com> References: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> <7465b6170705082051k6f55ff0chd79bd2729b5c4d54@mail.gmail.com> Message-ID: <4641BF75.3020608@sympatico.ca> Roman Yakovenko wrote: > I have nothing again SWIG, but can you move this discussion to its mailing list? > It has nothing to do with Boost.Python. [While I agree with your point, I'd also like to mention that the topic of this mailing list claims to be "Development of Python/C++ integration", and thus it is worth pointing out that boost.python is not the only authoritative binding.] FWIW, Stefan -- ...ich hab' noch einen Koffer in Berlin... From wsf at fultondesigns.co.uk Wed May 9 21:58:46 2007 From: wsf at fultondesigns.co.uk (William S Fulton) Date: Wed, 09 May 2007 20:58:46 +0100 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtualfunctions in python script? In-Reply-To: References: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> Message-ID: <464227F6.4070701@fultondesigns.co.uk> Take one of the director examples as they work then modify to suite. That way you will probably spot what you are doing wrong too. William Bruce Who wrote: > I add #include in the generated .cxx file and removed std > namespace before exceptions and it compiles. I donnot know why. But my > code still doesnot work! My OnEvent() event is still not called. Does > that mean director doesnot work for me? > From bruce.who.hk at gmail.com Thu May 10 04:17:36 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Thu, 10 May 2007 10:17:36 +0800 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtualfunctions in python script? In-Reply-To: <464227F6.4070701@fultondesigns.co.uk> References: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> <464227F6.4070701@fultondesigns.co.uk> Message-ID: Hi, Thanks for all of you. It finally works. I have tried swig/testswig/python/extend, and the unexpected_handler issue still exists. I solve this as what I said in my previous post. The script swig/testswig/python/extend/runme.py runs with errors: Runtime Error! Program: D:\program\Python25\python.exe abnormal program termination and I find that this error is caused by this call ``e.getName()''. I think swig is not very friendly to win32 users. However, the only difference between my .i file and the example.i is that the order of #include and %include, this is my original .i file: %module(directors="1") cmod %include "cmod.h" %feature("director"); %inline %{ #include "cmod.h" %} so I change it to: %module(directors="1") cmod %inline %{ #include "cmod.h" %} %feature("director"); %include "cmod.h" then compile all files and run my script and everything goes fine! Bruce From roman.yakovenko at gmail.com Thu May 10 06:31:51 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 10 May 2007 07:31:51 +0300 Subject: [C++-sig] Wrapping std::map using Boost::Python In-Reply-To: <9fadca7e0705090423h4fdf20fcs84eee57bb090ca64@mail.gmail.com> References: <9fadca7e0705090423h4fdf20fcs84eee57bb090ca64@mail.gmail.com> Message-ID: <7465b6170705092131l55fbd97dw633e8ca6d41f029@mail.gmail.com> On 5/9/07, James Knight wrote: > > Hi, > > I'm trying to wrap std::map using boost::python so my embedded python code > can access maps. I have the following wrapper class: Boost.Python exposes std::map: http://boost.cvs.sourceforge.net/*checkout*/boost/boost/libs/python/doc/v2/indexing.html#map_indexing_suite_class http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/map_indexing_suite.cpp?view=markup&sortdir=down May be you can use them? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From bruce.who.hk at gmail.com Thu May 10 10:54:04 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Thu, 10 May 2007 16:54:04 +0800 Subject: [C++-sig] [Swig-user] Why this does not work- overriding C++ virtualfunctions in python script? In-Reply-To: References: <1C1EBEF8DBACDC439D038EA051674EC78A4B60@xbox.financialcad.com> <464227F6.4070701@fultondesigns.co.uk> Message-ID: Hi, all I guess the Runtime Error is due to the compiler. I compiles it with VC++6.0 and the error occurs while with VC++8.0 everything is OK. On 5/10/07, Bruce Who wrote: > Hi, > > Thanks for all of you. It finally works. > > I have tried swig/testswig/python/extend, and the unexpected_handler > issue still exists. I solve this as what I said in my previous post. > The script swig/testswig/python/extend/runme.py runs with errors: > > Runtime Error! > Program: D:\program\Python25\python.exe > abnormal program termination > > and I find that this error is caused by this call ``e.getName()''. I > think swig is not very friendly to win32 users. > > However, the only difference between my .i file and the example.i is > that the order of #include and %include, this is my original .i file: > > > %module(directors="1") cmod > %include "cmod.h" > > %feature("director"); > > %inline %{ > #include "cmod.h" > %} > > > so I change it to: > > %module(directors="1") cmod > > %inline %{ > #include "cmod.h" > %} > > %feature("director"); > > %include "cmod.h" > > > then compile all files and run my script and everything goes fine! Bruce From bruce.who.hk at gmail.com Thu May 10 17:57:16 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Thu, 10 May 2007 23:57:16 +0800 Subject: [C++-sig] A callback function with arguments causes error Message-ID: Hi, all I have some callback functions in my .cpp files and I want to wrap them into python scripts with swig. So I have tried this example first: swigwin-1.3.31/Examples/python/callback. This example compiles and runs well. But this callback function takes no arguments, so I changed it a little: // example.h class Callback { public: virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } // XXX this is the original statement // virtual void run() { std::cout << "Callback::run()" << std::endl; } virtual void run(int* pn) { std::cout << "Callback::run()" << (*pn) << std::endl; } }; class Caller { private: Callback *_callback; public: Caller(): _callback(0) {} ~Caller() { delCallback(); } void delCallback() { delete _callback; _callback = 0; } void setCallback(Callback *cb) { delCallback(); _callback = cb; } // XXX void call() { if (_callback) _callback->run(); } void call() { if (_callback) { int i = 90; // XXX _callback->run(i); _callback->run(&i); } } }; As you see, I just add a int* argument to this callback. It compiles but it cause python.exe to crash while running. Could anybody tell me how to solve this? Any help would be appreciated! Bruce From luca.sbardella at gmail.com Thu May 10 18:32:34 2007 From: luca.sbardella at gmail.com (Luca Sbardella) Date: Thu, 10 May 2007 18:32:34 +0200 Subject: [C++-sig] inheritance problem when using constructor Message-ID: <8315652a0705100932y6c9a611bg8f4ba29a59250ea5@mail.gmail.com> Hi all, I have a problem regarding inheritance/polymorphism which I cannot get to the bottom of it. In C++ I have a pure virtual class, lets called it an interface, called "its" and an implementation of it called "ts". I exposed the two to python using the "wrapper.hpp" module. struct ts_wrapper : its, wrapper { int get_numdates() const {....} } typedef boost::shared_ptr ITS; register_ptr_to_python(); class_("itimeserie", "Time serie interface") .def("get_numdates", pure_virtual(&its::get_numdates)); class_>("timeserie", "An implementation of itimeserie", init()); def("ts_create",×erieFactory::Create,"Get a time serie"); timeserieFactory returns a smart pointer to the interface "its", ITS. Now, in Python, when I create an instance of "timeserie" using the "ts_create" everything works fine, i.e. I can call the method "get_numdates" without any problem. However when I create an instance of "timeserie" using the constructor, the object is constructed correctly but when I call "get_numdates" this is what python think about it Boost.Python.ArgumentError: Python argument types in itimeserie.get_numdates(timeserie) did not match C++ signature: get_numdates(class ts_wrapper {lvalue}) get_numdates(class its {lvalue}) somehow when I use the constructor, the instance is not recognized as derived from the interface. Luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From p.jaroszynski at gmail.com Thu May 10 19:02:19 2007 From: p.jaroszynski at gmail.com (Piotr Jaroszynski) Date: Thu, 10 May 2007 19:02:19 +0200 Subject: [C++-sig] inheritance problem when using constructor In-Reply-To: <8315652a0705100932y6c9a611bg8f4ba29a59250ea5@mail.gmail.com> References: <8315652a0705100932y6c9a611bg8f4ba29a59250ea5@mail.gmail.com> Message-ID: <200705101902.19867.p.jaroszynski@gmail.com> On Thursday 10 of May 2007 18:32:34 Luca Sbardella wrote: > class_>("timeserie", "An implementation of > itimeserie", init()); ts is not derived from ts_wrapper but from its, is it? So I think you should use bases. -- Best Regards, Piotr Jaroszynski From luca.sbardella at gmail.com Thu May 10 19:38:35 2007 From: luca.sbardella at gmail.com (Luca Sbardella) Date: Thu, 10 May 2007 19:38:35 +0200 Subject: [C++-sig] inheritance problem when using constructor In-Reply-To: <200705101902.19867.p.jaroszynski@gmail.com> References: <8315652a0705100932y6c9a611bg8f4ba29a59250ea5@mail.gmail.com> <200705101902.19867.p.jaroszynski@gmail.com> Message-ID: <8315652a0705101038j3da6f0fdlc342e371be115237@mail.gmail.com> obviously. thanks On 10/05/07, Piotr Jaroszynski wrote: > > On Thursday 10 of May 2007 18:32:34 Luca Sbardella wrote: > > class_>("timeserie", "An implementation of > > itimeserie", init()); > > ts is not derived from ts_wrapper but from its, is it? So I think you > should > use bases. > > -- > Best Regards, > Piotr Jaroszynski > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pk at cs.tut.fi Thu May 10 22:27:35 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Thu, 10 May 2007 23:27:35 +0300 Subject: [C++-sig] Doing dlopen() from within a Python extension Message-ID: <46438037.7010306@cs.tut.fi> I am wrapping a library using Boost.Python, and the library does a "dlopen(path,RTLD_LOCAL | RTLD_NOW)" to load some plugin code. The dlopen() fails and returns NULL. There seems to have been a lot of discussion around the issue, but I am yet to find a definite answer of how to make the dlopen() work. Any pointers? My system is Ubuntu 6.10, and I am building the Python extension using distutils. Python version is 2.4. -- Pertti From pk at cs.tut.fi Thu May 10 23:08:20 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Fri, 11 May 2007 00:08:20 +0300 Subject: [C++-sig] Doing dlopen() from within a Python extension In-Reply-To: <46438037.7010306@cs.tut.fi> References: <46438037.7010306@cs.tut.fi> Message-ID: <464389C4.6010103@cs.tut.fi> Pertti Kellom?ki wrote: > There seems to have been a lot of discussion around > the issue, but I am yet to find a definite answer of > how to make the dlopen() work. It seems that setting the RTLD_GLOBAL flag with sys.setldopenflags() before loading my extensions resolves the issue. -- Pertti From ajay.murthy at philips.com Fri May 11 06:33:51 2007 From: ajay.murthy at philips.com (Ajay Murthy) Date: Fri, 11 May 2007 10:03:51 +0530 Subject: [C++-sig] Very New to Boost Python Message-ID: Hi All, I am very new to Boost.Python and I am facing the following problem. Here is my C++ class declaration: class Matrix { public: Matrix(int rows, int cols); Matrix(const Matrix& m); inline int GetCols() { return numCols;} inline int GetRows() { return numRows;} int** Get_Buffer(); void SetStride(int x, int y); Matrix& operator*(const Matrix& m); Vector& operator[](int index); Matrix& operator=(const Matrix& m); private: void SetSize(int rows, int cols); int numCols, numRows; Vector* matrix; int ystride; }; And the corresponding Boost.Python wrapper is BOOST_PYTHON_MODULE(DataTypes) { class_("Matrix", init()) .def("GetCols", &Matrix::GetCols) .def("GetRows", &Matrix::GetRows) .def("SetStride", &Matrix::SetStride) //.def("Get_Buffer", &Matrix::Get_Buffer) //.def(self * self) //.def(__getitem__(self, int) //.def(__setitem__(self, int, int) ; } As you might have already observed, I have commented out few lines in the wrapper. If i uncomment it, bjam doesnt work. >From the initial analysis it seems to be a problem with the methods which accepts/returns arguments other than the primitive types. I may be wrong here. Anyways, could anyone please explain me what the problem could be and the solution for the same. Also, it would help if you could point me to some good documentation. The documentation in the boost.python page is very helpful for basic understanding but not after that. thanks in advance, Ajay -------------- next part -------------- An HTML attachment was scrubbed... URL: From meine at informatik.uni-hamburg.de Fri May 11 12:09:12 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Fri, 11 May 2007 12:09:12 +0200 Subject: [C++-sig] Telling boost::build V2 how to find pyconfig.h? Message-ID: <200705111209.12723.meine@informatik.uni-hamburg.de> Hi! For several hours now I have been struggling with boost::build V2, trying to compile the 1.34.0 beta version. Please, can anyone tell me how to tell the build system that in addition to the regular python include path (which is found correctly), a platform-specific include path that contains only pyconfig.h is needed? Looking at boost_1_34_0/tools/build/v2/tools/python.jam, I am not getting any smarter. I do not even understand how the include path is set and why it is correct (I see the "rule" compute-default-paths, but my python installation is not in $prefix at all, so that cannot apply for me). I expect distutils.sysconfig to be used, but I did not find that code yet. With older boost versions, I simply set PYTHON_PYCONFIG="`python -c "import distutils.sysconfig; print distutils.sysconfig.get_config_h_filename()"`" and copied $PYTHON_PYCONFIG into $BUILDDIR/bin/boost/libs/python/build I would be content if I found a comparable working hack to build 1.34.0 in our system environment, but the only location where I could copy pyconfig.h was the boost's source root directory, which is included through -I"." If you tell me how to add an additional -I commandline argument to gcc, that would be fine, too. Otherwise, the preferred solution would be to ask $(interpreter-cmd) for the location of pyconfig.h (see above) and compare the directory with the python includes directory, so it works for all users automatically. -- Ciao, / / /--/ / / ANS From roman.yakovenko at gmail.com Fri May 11 21:14:20 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 11 May 2007 21:14:20 +0200 Subject: [C++-sig] Very New to Boost Python In-Reply-To: References: Message-ID: <7465b6170705111214n1367d7a3jfab593ccd6d85deb@mail.gmail.com> On 5/11/07, Ajay Murthy wrote: > > Hi All, > > I am very new to Boost.Python and I am facing the following problem. > > Here is my C++ class declaration: > > class Matrix > { > public: > Matrix(int rows, int cols); > Matrix(const Matrix& m); > inline int GetCols() { return numCols;} > inline int GetRows() { return numRows;} > int** Get_Buffer(); > void SetStride(int x, int y); > Matrix& operator*(const Matrix& m); > Vector& operator[](int index); > Matrix& operator=(const Matrix& m); > private: > void SetSize(int rows, int cols); > int numCols, numRows; > Vector* matrix; > int ystride; > > }; > > And the corresponding Boost.Python wrapper is > > BOOST_PYTHON_MODULE(DataTypes) > { > class_("Matrix", init()) > .def("GetCols", &Matrix::GetCols) > .def("GetRows", &Matrix::GetRows) > .def("SetStride", &Matrix::SetStride) > //.def("Get_Buffer", &Matrix::Get_Buffer) > //.def(self * self) > //.def(__getitem__(self, int) > //.def(__setitem__(self, int, int) > ; > } > You have to expose class Vector too and may be to define call policies. > > As you might have already observed, I have commented out few lines in the wrapper. If i uncomment it, bjam doesnt work. > From the initial analysis it seems to be a problem with the methods which accepts/returns arguments other than the primitive types. I may be wrong here. > > Anyways, could anyone please explain me what the problem could be and the solution for the same. You cannot export Get_Buffer, cause Python doesn't expose its user to low-level details such as int**, so does Boost.Python. The are few possible solution, one of them is to use custom return policies. I needed to expose the functionality similar to yours, so I create such call policy: http://www.language-binding.net/pyplusplus/documentation/functions/call_policies.html#return-range > Also, it would help if you could point me to some good documentation. The documentation in the boost.python page is very helpful for basic understanding but not after that. http://www.language-binding.net/pyplusplus/links.html#help-resources -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From bruce.who.hk at gmail.com Mon May 14 11:25:51 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Mon, 14 May 2007 17:25:51 +0800 Subject: [C++-sig] A callback function with arguments causes error In-Reply-To: References: Message-ID: Hi, all Has nobody tried a callback function with arguments? I just want to implement an event-handling by doing this, but I donnot know how to make it work. On 5/10/07, Bruce Who wrote: > Hi, all > > I have some callback functions in my .cpp files and I want to wrap > them into python scripts with swig. So I have tried this example > first: swigwin-1.3.31/Examples/python/callback. This example compiles > and runs well. But this callback function takes no arguments, so I > changed it a little: > > // example.h > class Callback { > public: > virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } > // XXX this is the original statement > // virtual void run() { std::cout << "Callback::run()" << std::endl; } > virtual void run(int* pn) { std::cout << "Callback::run()" << (*pn) > << std::endl; } > }; > > > class Caller { > private: > Callback *_callback; > public: > Caller(): _callback(0) {} > ~Caller() { delCallback(); } > void delCallback() { delete _callback; _callback = 0; } > void setCallback(Callback *cb) { delCallback(); _callback = cb; } > // XXX void call() { if (_callback) _callback->run(); } > void call() > { > if (_callback) > { > int i = 90; > // XXX _callback->run(i); > _callback->run(&i); > } > } > }; > > > As you see, I just add a int* argument to this callback. It compiles > but it cause python.exe to crash while running. Could anybody tell me > how to solve this? Any help would be appreciated! Bruce From meine at informatik.uni-hamburg.de Mon May 14 11:52:16 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Mon, 14 May 2007 11:52:16 +0200 Subject: [C++-sig] Better introspection/apidoc extraction support? Message-ID: <200705141152.16771.meine@informatik.uni-hamburg.de> Hi! The epydoc developers would like to support boost::python function introspection. In boost 1.34.0, there is support for C++ signatures appended to the docstrings, but it would be better AFAICS if boost::python would additionally provide means for extracting the argument names and default values via ("half-private") attributes, similar to CPython. I would imagine that this is not even hard to do for someone with sufficient insight, is such a thing planned? (Or are there good reasons why that is not yet supported?) IMHO it would greatly help API documentation systems. (Especially since signatures in docstrings are discouraged according to PEP 257, as I just learned.) -- Ciao, / / /--/ / / ANS From lucy.devlin at hotmail.co.uk Mon May 14 14:14:43 2007 From: lucy.devlin at hotmail.co.uk (Lucy Devlin) Date: Mon, 14 May 2007 12:14:43 +0000 Subject: [C++-sig] Deleting the C++ part of a Boost.Python exposed Python object from C++ Message-ID: Hi Everyone,Apologies for the verbose subject/title :-pI am very new to Boost.Python so I am still finding my feet...I've spent a couple of days looking at a problem that I just can't figure out how to solve. What look like similar problems and solutions don't appear to suit my needs, so if someone can point me in the right direction I would be very grateful.I'm working on interfacing with a C++ application for which the source code should not be affected (if possible) and the following situation seems like a reasonable pattern of behaviour, but I can't see how to wrap it with Boost.Python. Look at the following C++ code snippet...ProcessX* process = new ProcessX;ProcessManager* manager = ...; // Get the process managermanager->addProcess(process);if (!manager->isValid()){ // Prompt for user input and modify the process // Note that process is still accessible at this point process->doSomething();}// The manager has ownership of process which // will be deleted by the manager after execution manager->executeProcesses();Now, I was hoping to find a way to wrap the C++ classes involved (ProcessX and ProcessManager) such that a python ProcessX instance wraps a C++ ProcessX instance and knows when the C++ instance is deleted. Such as...ProcessX process = myapi.ProcessX()ProcessManager manager = ...# Get the process managermanager.addProcess(process);if not manager.isValid(): # User input, etc process.doSomething() # process instance is still validmanager.executeProcesses()try: process.doSomething() # The wrapped C++ object was deletedexcept DeleteCPPException: print "Exception raised" # And rightly so!I don't really need the Python process instance to endure after the deletion of its C++ counterpart but I need to transfer ownership to the process manager and maintain temporary access to the Python instance in order to doSomething.Any suggestions? Reading material? Good advice?I apologise if this has come up a few times before! I would expect it to have but didn't find anything in the archives.Many thanks in advance,L _________________________________________________________________ Try Live.com: where your online world comes together - with news, sports, weather, and much more. http://www.live.com/getstarted -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucy.devlin at hotmail.co.uk Mon May 14 16:51:51 2007 From: lucy.devlin at hotmail.co.uk (Lucy Devlin) Date: Mon, 14 May 2007 14:51:51 +0000 Subject: [C++-sig] Auto-Linking to Boost.Python Message-ID: Hi Everyone,I've noticed that the auto-linking in VC7.1 is trying to link me against boost_python-vc71-mt-gd-1_34.lib rather than boost_python-vc71-mt-gyd-1_34.lib (note the extra 'y') even though I have BOOST_DEBUG_PYTHON defined in my project. Is this right or am I doing something wrong? I built the actual boost_python-vc71-mt-gyd-1_34.lib (and DLL) without any problems, it's just linking to this library that's going wrong for me.Obviously I am using Boost 1.34 ;-)Regards and many thanks,L _________________________________________________________________ Try Live.com - your fast, personalized homepage with all the things you care about in one place. http://www.live.com/getstarted -------------- next part -------------- An HTML attachment was scrubbed... URL: From rwgk at yahoo.com Mon May 14 17:59:00 2007 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Mon, 14 May 2007 08:59:00 -0700 (PDT) Subject: [C++-sig] Better introspection/apidoc extraction support? Message-ID: <375753.33058.qm@web31104.mail.mud.yahoo.com> I did the implementation of the "docstring_options" feature. I'm not aware of plans to work on this, but I'm interested to at least learn what could be done to better support epydoc. If it is not too time-consuming I'd be willing to work on it a bit. > The epydoc developers would like to support boost::python function > introspection. In boost 1.34.0, there is support for C++ signatures appended > to the docstrings, but it would be better AFAICS if boost::python would > additionally provide means for extracting the argument names and default > values via ("half-private") attributes, similar to CPython. How exactly does this work? Are there web pages about this? Thanks! Ralf ____________________________________________________________________________________Be a better Heartthrob. Get better relationship answers from someone who knows. Yahoo! Answers - Check it out. http://answers.yahoo.com/dir/?link=list&sid=396545433 -------------- next part -------------- An HTML attachment was scrubbed... URL: From monty at inaugust.com Mon May 14 20:27:07 2007 From: monty at inaugust.com (Monty Taylor) Date: Mon, 14 May 2007 11:27:07 -0700 Subject: [C++-sig] [Swig-user] A callback function with arguments causes error In-Reply-To: References: Message-ID: <4648A9FB.3000804@inaugust.com> Hi Bruce, I'm using a callback with arguments from Python using directors. I've got this: class BaseCallback { public: virtual ~BaseCallback() {}; virtual void callback(int res, NdbTransaction * trans); }; Then from python: class PythonCallback(ndbapi.BaseCallback): def __init__(self, recAttr): self.recAttr=recAttr def __call__(self, *args, **kw): self.callback(*args,**kw) def callback(self, ret, myTrans): x=self.recAttr.get_value() Works like a charm. Are you sure everything is working right with memory ownership and that int *? I'd try it with just a normal int first to see if that's the problem, then go in and figure out how to get Python to allocate and pass the int* in such a way that it still exists when you access it in the callback... but I could be way off base there. Monty Bruce Who wrote: > Hi, all > > Has nobody tried a callback function with arguments? I just want to > implement an event-handling by doing this, but I donnot know how to > make it work. > > On 5/10/07, Bruce Who wrote: >> Hi, all >> >> I have some callback functions in my .cpp files and I want to wrap >> them into python scripts with swig. So I have tried this example >> first: swigwin-1.3.31/Examples/python/callback. This example compiles >> and runs well. But this callback function takes no arguments, so I >> changed it a little: >> >> // example.h >> class Callback { >> public: >> virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } >> // XXX this is the original statement >> // virtual void run() { std::cout << "Callback::run()" << std::endl; } >> virtual void run(int* pn) { std::cout << "Callback::run()" << (*pn) >> << std::endl; } >> }; >> >> >> class Caller { >> private: >> Callback *_callback; >> public: >> Caller(): _callback(0) {} >> ~Caller() { delCallback(); } >> void delCallback() { delete _callback; _callback = 0; } >> void setCallback(Callback *cb) { delCallback(); _callback = cb; } >> // XXX void call() { if (_callback) _callback->run(); } >> void call() >> { >> if (_callback) >> { >> int i = 90; >> // XXX _callback->run(i); >> _callback->run(&i); >> } >> } >> }; >> >> >> As you see, I just add a int* argument to this callback. It compiles >> but it cause python.exe to crash while running. Could anybody tell me >> how to solve this? Any help would be appreciated! > > > Bruce > > ------------------------------------------------------------------------- > This SF.net email is sponsored by DB2 Express > Download DB2 Express C - the FREE version of DB2 express and take > control of your XML. No limits. Just data. Click to get it now. > http://sourceforge.net/powerbar/db2/ > _______________________________________________ > Swig-user mailing list > Swig-user at lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/swig-user From bruce.who.hk at gmail.com Tue May 15 02:25:30 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Tue, 15 May 2007 08:25:30 +0800 Subject: [C++-sig] [Swig-user] A callback function with arguments causes error In-Reply-To: <4648A9FB.3000804@inaugust.com> References: <4648A9FB.3000804@inaugust.com> Message-ID: Hi, Monty, Thanks for your code, but I still cannot figure out why it doesnot work. This is all of my code, it is just the callback example of swig with a little modification, but it just doesnot work: // ================== example.h #include #include class Callback { public: virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } // virtual void run() { std::cout << "Callback::run()" << std::endl; } virtual void run(int* pn) { std::cout << "Callback::run()" << (*pn) << std::endl; } }; class Caller { private: Callback *_callback; public: Caller(): _callback(0) {} ~Caller() { delCallback(); } void delCallback() { delete _callback; _callback = 0; } void setCallback(Callback *cb) { delCallback(); _callback = cb; } // void call() { if (_callback) _callback->run(); } void call() { if (_callback) { int i = 90; _callback->run(&i); } } }; // ================== example.cxx #include "example.h" // ================== example.i %module(directors="1") example %{ #include "example.h" %} %include "std_string.i" %feature("director") Callback; %include "example.h" @rem ================== build.bat @rem I compile my code with this bat file set FILENAME=example call "D:\program\Microsoft Visual Studio 8\VC\bin\vcvars32" swig -c++ -python %FILENAME%.i cl -c %FILENAME%_wrap.cxx -ID:\program\Python25\include\ link /subsystem:windows /LIBPATH:D:\program\Python25\libs\ %FILENAME%_wrap.obj /dll /OUT:_%FILENAME%.pyd #=================================================== # file: runme.py # you can test the wrapper with this script import example class PyCallback(example.Callback): def __init__(self): example.Callback.__init__(self) def run(self, i): print "PyCallback.run()", i # Create an Caller instance caller = example.Caller() # Add a simple C++ callback (caller owns the callback, so # we disown it first by clearing the .thisown flag). print "Adding and calling a normal C++ callback" print "----------------------------------------" callback = example.Callback() callback.thisown = 0 caller.setCallback(callback) caller.call() caller.delCallback(); print print "Adding and calling a Python callback" print "------------------------------------" # Add a Python callback (caller owns the callback, so we # disown it first by calling __disown__). caller.setCallback(PyCallback().__disown__()) caller.call() caller.delCallback() print print "Adding and calling another Python callback" print "------------------------------------------" # Lets do the same but use the weak reference this time. callback = PyCallback().__disown__() caller.setCallback(callback) caller.call() caller.delCallback() # All done. print print "python exit" After compiling all code, I run it: E:\test>runme.py Adding and calling a normal C++ callback ---------------------------------------- Callback::run()90 Callback::~Callback() Adding and calling a Python callback ------------------------------------ PyCallback.run() and then a windows message box pops up saying that there is something wrong with python.exe. On 5/15/07, Monty Taylor wrote: > Hi Bruce, > > I'm using a callback with arguments from Python using directors. > > I've got this: > > class BaseCallback { > public: > virtual ~BaseCallback() {}; > virtual void callback(int res, NdbTransaction * trans); > > }; > > > Then from python: > > class PythonCallback(ndbapi.BaseCallback): > > def __init__(self, recAttr): > self.recAttr=recAttr > > def __call__(self, *args, **kw): > self.callback(*args,**kw) > > def callback(self, ret, myTrans): > x=self.recAttr.get_value() > > Works like a charm. Are you sure everything is working right with memory > ownership and that int *? I'd try it with just a normal int first to see > if that's the problem, then go in and figure out how to get Python to > allocate and pass the int* in such a way that it still exists when you > access it in the callback... but I could be way off base there. > > Monty From j.reid at mail.cryst.bbk.ac.uk Tue May 15 12:49:41 2007 From: j.reid at mail.cryst.bbk.ac.uk (John Reid) Date: Tue, 15 May 2007 11:49:41 +0100 Subject: [C++-sig] Better introspection/apidoc extraction support? In-Reply-To: <375753.33058.qm@web31104.mail.mud.yahoo.com> References: <375753.33058.qm@web31104.mail.mud.yahoo.com> Message-ID: Would there be any chance of improving the formatting of mismatched arguments in python to C++ function call errors at the same time as this work? I'm not sure how related it is though. See http://tinyurl.com/2wa9pe I think it would be a major improvement in useability. Best, John. Ralf W. Grosse-Kunstleve wrote: > I did the implementation of the "docstring_options" feature. I'm not > aware of plans to work on this, but I'm interested to at least learn > what could be done to better support epydoc. If it is not too > time-consuming I'd be willing to work on it a bit. > > > The epydoc developers would like to support boost::python function > > introspection. In boost 1.34.0, there is support for C++ signatures > appended > > to the docstrings, but it would be better AFAICS if boost::python would > > additionally provide means for extracting the argument na mes and > default > > values via ("half-private") attributes, similar to CPython. > > How exactly does this work? Are there web pages about this? > > Thanks! > > Ralf > > > ------------------------------------------------------------------------ > Moody friends. Drama queens. Your life? Nope! - their life, your story. > Play Sims Stories at Yahoo! Games. > > > > ------------------------------------------------------------------------ > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From meine at informatik.uni-hamburg.de Tue May 15 13:37:24 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Tue, 15 May 2007 13:37:24 +0200 Subject: [C++-sig] Better introspection/apidoc extraction support? In-Reply-To: <375753.33058.qm@web31104.mail.mud.yahoo.com> References: <375753.33058.qm@web31104.mail.mud.yahoo.com> Message-ID: <200705151337.25198.meine@informatik.uni-hamburg.de> Hi! Am Montag, 14. Mai 2007 17:59:00 schrieb Ralf W. Grosse-Kunstleve: > I did the implementation of the "docstring_options" feature. I'm not aware > of plans to work on this, but I'm interested to at least learn what could > be done to better support epydoc. If it is not too time-consuming I'd be > willing to work on it a bit. Great! > > The epydoc developers would like to support boost::python function > > introspection. In boost 1.34.0, there is support for C++ signatures > > appended to the docstrings, but it would be better AFAICS if > > boost::python would additionally provide means for extracting the > > argument names and default values via ("half-private") attributes, > > similar to CPython. > > How exactly does this work? Are there web pages about this? Not that I know of. AFAICS, there is no public API for that (that's why I wrote "half-private"), but if you look at a functions func_code.co_XXX and func_defaults properties, you see that there is a lot of internal information available in CPython. Then, there is the inspect module (implemented in python), which uses the above internal stuff to offer a more convenient API. E.g. inspect.getargspec() uses func_code.co_varnames[:func_code.co_argcount] to query the argument names, func_code.co_flags to determine whether the function has *args or **kwargs parameters (4/8 bitflags), ... I would think that basically *any* API within boost::python functions would be OK, since there is no official way beyond inspect. (Of course, it would be best if the inspect module would become compatible with boost::python some day, so apidoc projects do not have to duplicate code..) -- Ciao, / / /--/ / / ANS From Mark.English at rbccm.com Tue May 15 14:12:07 2007 From: Mark.English at rbccm.com (English, Mark) Date: Tue, 15 May 2007 13:12:07 +0100 Subject: [C++-sig] Better introspection/apidoc extraction support? Message-ID: > Not that I know of. AFAICS, there is no public API for that (that's why I > wrote "half-private"), but if you look at a functions func_code.co_XXX and > func_defaults properties, you see that there is a lot of internal information > available in CPython. > Then, there is the inspect module (implemented in python), which uses the > above internal stuff to offer a more convenient API. E.g. > inspect.getargspec() uses func_code.co_varnames[:func_code.co_argcount] to > query the argument names, func_code.co_flags to determine whether the > function has *args or **kwargs parameters (4/8 bitflags), ... > I would think that basically *any* API within boost::python functions would be > OK, since there is no official way beyond inspect. (Of course, it would be > best if the inspect module would become compatible with boost::python some > day, so apidoc projects do not have to duplicate code..) (Apologies for the ridiculous trailer) For an introspection example, there was a signature.py drifting around which I'm having trouble tracking down, written I believe by Neel Krishnaswami. There's a copy here: http://funformkit.sourceforge.net/FunFormKit/Signature.py Speaking of signatures, have you looked at the draft Pep 362 ? http://www.python.org/dev/peps/pep-0362/ There's a reference implementation: http://svn.python.org/view/sandbox/trunk/pep362/ Hope that helps, Mark ________________________________________ This E-Mail (including any attachments) may contain privileged or confidential information. It is intended only for the addressee(s) indicated above. The sender does not waive any of its rights, privileges or other protections respecting this information. Any distribution, copying or other use of this E-Mail or the information it contains, by other than an intended recipient, is not sanctioned and is prohibited. If you received this E-Mail in error, please delete it and advise the sender (by return E-Mail or otherwise) immediately. This E-Mail (including any attachments) has been scanned for viruses. It is believed to be free of any virus or other defect that might affect any computer system into which it is received and opened. However, it is the responsibility of the recipient to ensure that it is virus free. The sender accepts no responsibility for any loss or damage arising in any way from its use. E-Mail received by or sent from RBC Capital Markets is subject to review by Supervisory personnel. Such communications are retained and may be produced to regulatory authorities or others with legal rights to the information. IRS CIRCULAR 230 NOTICE: TO COMPLY WITH U.S. TREASURY REGULATIONS, WE ADVISE YOU THAT ANY U.S. FEDERAL TAX ADVISE INCLUDED IN THIS COMMUNICATION IS NOT INTENDED OR WRITTEN TO BE USED, AND CANNOT BE USED, TO AVOID ANY U.S. FEDERAL TAX PENALTIES OR TO PROMOTE, MARKET, OR RECOMMEND TO ANOTHER PARTY ANY TRANSACTION OR MATTER. From meine at informatik.uni-hamburg.de Tue May 15 15:01:41 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Tue, 15 May 2007 15:01:41 +0200 Subject: [C++-sig] Better introspection/apidoc extraction support? In-Reply-To: References: Message-ID: <200705151501.42122.meine@informatik.uni-hamburg.de> Hi! Am Dienstag, 15. Mai 2007 14:12:07 schrieb English, Mark: > For an introspection example, there was a signature.py drifting around > which I'm having trouble tracking down, written I believe by Neel > Krishnaswami. There's a copy here: > http://funformkit.sourceforge.net/FunFormKit/Signature.py That looks like a predecessor / alternative to the std. 'inspect' module. (And does not yet work with boost::python or course.) > Speaking of signatures, have you looked at the draft Pep 362 ? > http://www.python.org/dev/peps/pep-0362/ That PEP is very interesting indeed. Since it describes a complete API, it looks like a perfect implementation goal for BPL. (Eager/lazy creation does not really matter here, as long as BPL functions get a proper __signature__ attribute.) Ralf, what do you think? -- Ciao, / / /--/ / / ANS From bruce.who.hk at gmail.com Tue May 15 16:49:24 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Tue, 15 May 2007 22:49:24 +0800 Subject: [C++-sig] [Swig-user] A callback function with arguments causes error In-Reply-To: References: <4648A9FB.3000804@inaugust.com> Message-ID: hi, Nitro Thanks for your hint, and I tried a similar method, I add __asm {int 3} before the call, but the unassembld code are really hard to read and I donnot think I can figure it out even it's translated into C++ source code. I just wonder if this kind of usage is not supported by swig or maybe I miss something very basic, since I just made a little modification to the swig example. On 5/15/07, Nitro wrote: > Am 15.05.2007, 02:25 Uhr, schrieb Bruce Who : > > > > Why don't you compile a debug version and invoke the debugger when it > crashes (or before it crashes)? My favourite trick for debugging an > extension module is like this: > > test.py: > > import myModule > doSomeNonCrashingPythonThingsHere() > myModule.InvokeDebugger() # Debugger gets involved here > this_line_will_make_it_crash() > > > myModule.i: > > .... > > %inline > %{ > void InvokeDebugger() > { > int* x = 0; > y = *x; > } > %} > > > When it crashes on the invoke debugger line, windows gives me that error > box where I can choose "Debug". When I do this I end up in the y = *x > line, then set the "next instruction" to the end of the InvokeDebugger > function, set all breakpoints I want to set (for example in the > myModuke_wrap.cpp) and hit F5 to contiue debugging. The debugger will then > either break on the next breakpoint or break when it crashes. > This should give you enough pointers to see what you are doing wrong. > > -Matthias > > P.S.: I think this only works in debug mode and probably only on msvc. In > release mode the InvokeDebugger function is sometimes either not executed > or it doesn't care whether it dereferences a 0 pointer. > Bruce From bruce.who.hk at gmail.com Wed May 16 05:10:27 2007 From: bruce.who.hk at gmail.com (Bruce Who) Date: Wed, 16 May 2007 11:10:27 +0800 Subject: [C++-sig] Any win32 project using swig? Message-ID: Hi,all I'm trying to use swig to wrap a C++ library to python, but there's so many problems that I cannot solve. I am now looking for a existing project which uses swig for python binding, is a open-source win32 project and not too complex. If there is such a project I think I can learn something by looking through its source code. Could anybody recommend one or more (the more the better) for me? Thanks in advance. Bruce From jlenz2 at math.uiuc.edu Wed May 16 20:39:42 2007 From: jlenz2 at math.uiuc.edu (John Lenz) Date: Wed, 16 May 2007 13:39:42 -0500 Subject: [C++-sig] [Swig-user] Any win32 project using swig? In-Reply-To: References: Message-ID: <464B4FEE.7010902@math.uiuc.edu> On 05/15/2007 10:10 PM, Bruce Who wrote: > Hi,all > > I'm trying to use swig to wrap a C++ library to python, but there's so > many problems that I cannot solve. I am now looking for a existing > project which uses swig for python binding, is a open-source win32 > project and not too complex. If there is such a project I think I can > learn something by looking through its source code. Could anybody > recommend one or more (the more the better) for me? Thanks in advance. > > Bruce Subversion is the first one that comes to mind. cross platform and python bindings (as well as several other languages). http://subversion.tigris.org/ From dave at boost-consulting.com Fri May 18 01:09:09 2007 From: dave at boost-consulting.com (David Abrahams) Date: Thu, 17 May 2007 17:09:09 -0600 Subject: [C++-sig] Auto-Linking to Boost.Python References: Message-ID: <871whf9hey.fsf@grogan.peloton> on Mon May 14 2007, Lucy Devlin wrote: > Hi Everyone, > > I've noticed that the auto-linking in VC7.1 is trying to link me > against boost_python-vc71-mt-gd-1_34.lib rather than > boost_python-vc71-mt-gyd-1_34.lib (note the extra 'y') even though I > have BOOST_DEBUG_PYTHON defined in my project. Is this right or am I > doing something wrong? I built the actual > boost_python-vc71-mt-gyd-1_34.lib (and DLL) without any problems, it's > just linking to this library that's going wrong for me. Are you certain? I was pretty sure I never did anything to support auto linking in Boost.Python. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com Don't Miss BoostCon 2007! ==> http://www.boostcon.com From t_spens at yahoo.com Fri May 18 02:02:21 2007 From: t_spens at yahoo.com (t_spens) Date: Thu, 17 May 2007 17:02:21 -0700 (PDT) Subject: [C++-sig] Problems importing a c++ shared library Message-ID: <10674432.post@talk.nabble.com> ImportError: dynamic module does not define init function (initlibhello) - I have no idea why I'm getting this error. I'm using gcc to create my library libhello.so from the .cpp file below Here are my gcc arguments: gcc -g -Wall -I ../../../usr/include/boost -I ../../../usr/include/python2.5 -c hello.cpp -o hello.o gcc -shared -fPIC -g -Wall -I ../../../usr/include/boost -I ../../../usr/include/python2.5 -L /usr/lib -lstdc++ -lboost_python -o libhello.so hello.o #include using namespace std; void print(char * stringToPrint){cout << stringToPrint << endl;} int main () { print("hello from c++"); return 0; } #include using namespace boost::python; BOOST_PYTHON_MODULE(hello) { def("print", print); } ~/pythonScripts$ python Python 2.5.1c1 (release25-maint, Apr 12 2007, 21:00:25) [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import libhello Traceback (most recent call last): File "", line 1, in ImportError: dynamic module does not define init function (initlibhello) >>> Any ideas? -- View this message in context: http://www.nabble.com/Problems-importing-a-c%2B%2B-shared-library-tf3775017.html#a10674432 Sent from the Python - c++-sig mailing list archive at Nabble.com. From p.jaroszynski at gmail.com Fri May 18 02:37:21 2007 From: p.jaroszynski at gmail.com (Piotr Jaroszynski) Date: Fri, 18 May 2007 02:37:21 +0200 Subject: [C++-sig] Problems importing a c++ shared library In-Reply-To: <10674432.post@talk.nabble.com> References: <10674432.post@talk.nabble.com> Message-ID: <200705180237.21804.p.jaroszynski@gmail.com> On Friday 18 of May 2007 02:02:21 t_spens wrote: > BOOST_PYTHON_MODULE(hello) > >>> import libhello these two must match, so try BOOST_PYTHON_MODULE(libhello). -- Best Regards, Piotr Jaroszynski From j.reid at mail.cryst.bbk.ac.uk Fri May 18 10:15:32 2007 From: j.reid at mail.cryst.bbk.ac.uk (John Reid) Date: Fri, 18 May 2007 09:15:32 +0100 Subject: [C++-sig] Auto-Linking to Boost.Python In-Reply-To: <871whf9hey.fsf@grogan.peloton> References: <871whf9hey.fsf@grogan.peloton> Message-ID: David Abrahams wrote: > Are you certain? I was pretty sure I never did anything to support > auto linking in Boost.Python. > > I noticed this at the end of python/detail/config.hpp: // enable automatic library variant selection ------------------------------// #if !defined(BOOST_PYTHON_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_PYTHON_NO_LIB) // // Set the name of our library, this will get undef'ed by auto_link.hpp // once it's done with it: // #define BOOST_LIB_NAME boost_python // // If we're importing code from a dll, then tell auto_link.hpp about it: // #ifdef BOOST_PYTHON_DYNAMIC_LIB # define BOOST_DYN_LINK #endif // // And include the header that does the work: // #include #endif // auto-linking disabled From iladyko at odesk.com Fri May 18 10:17:56 2007 From: iladyko at odesk.com (Irene Ladyko) Date: Fri, 18 May 2007 15:17:56 +0700 Subject: [C++-sig] embeded python and winsound Message-ID: <1453152813.20070518151756@odesk.com> Hello, c++-sig. I use Python version 2.4.4 under win32. I built python using pcbuild.sln. There is winsound module project in it, so I built it too. After that I can run python.exe interpeter directly and load winsound module in it. All be OK. D:\....>python.exe Python 2.4.4 (#71, May 17 2007, 16:53:33) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> >>>import winsound >>>winsound.PlaySound("SystemExit", winsound.SND_ALIAS) But I am interested in embeded python. I use this interpreter in C++ code (MSVC7.1). And when I load winsound programmatically, the following error appears: "No module named winsound". But such module as 'array' is imported correctly: import array What is wrong. Please, point me on my error. Code: #include #include "Python.h" int main(int /*argc*/, char** /*argv*/) { PyThreadState *m_threadState; // Initialize python Py_NoSiteFlag = 1; Py_Initialize(); // Enable thread support. PyEval_InitThreads(); // Delete default thread state. PyThreadState *l_default = PyThreadState_Get(); Py_EndInterpreter(l_default); // Release global interpreter lock. PyEval_ReleaseLock(); //start python PyEval_AcquireLock(); m_threadState = Py_NewInterpreter(); PyEval_ReleaseThread(m_threadState); //-------Load winsound module----------!!!!!!!!!!!!!!!!!!!!!!!! PyEval_AcquireThread(m_threadState); PyObject *l_module; PyObject *l_dict; PyObject *l_retValue; // we will use __main__ module as our global and local namespace. l_module = PyImport_AddModule("__main__"); if (!l_module) { PyEval_ReleaseThread(m_threadState); return -1; } std::string l_str = "import winsound"; l_dict = PyModule_GetDict(l_module); l_retValue = PyRun_StringFlags( (char *)l_str.c_str(), Py_file_input, l_dict, l_dict, NULL); if (!l_retValue) { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Enter into this block!!!!!!!!!!!!!!!!!!! PyEval_ReleaseThread(m_threadState); return -1; } Py_DECREF(l_retValue); PyEval_ReleaseThread(m_threadState); //End PyEval_AcquireThread(m_threadState); Py_EndInterpreter(m_threadState); PyEval_ReleaseLock(); PyEval_AcquireLock(); // Create default interpreter back. Py_NewInterpreter(); Py_Finalize(); return 0; } -- Best Regards, Irene Ladyko. From pk at cs.tut.fi Fri May 18 11:30:10 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Fri, 18 May 2007 12:30:10 +0300 Subject: [C++-sig] Exposing a template class Message-ID: <464D7222.4020509@cs.tut.fi> Are there examples around of exposing instances of template classes? I'm assuming it should be as easy as enclosing a BOOST_PYTHON_MODULE inside a template and instantiating the template, but it would be reassuring to have some hand holding in case there are issues I have not thought about. -- Pertti From roman.yakovenko at gmail.com Fri May 18 20:26:19 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 18 May 2007 20:26:19 +0200 Subject: [C++-sig] embeded python and winsound In-Reply-To: <1453152813.20070518151756@odesk.com> References: <1453152813.20070518151756@odesk.com> Message-ID: <7465b6170705181126p517f5942q2bbaadfd592e6011@mail.gmail.com> On 5/18/07, Irene Ladyko wrote: > Hello, c++-sig. > > I use Python version 2.4.4 under win32. > I built python using pcbuild.sln. There is winsound module project in > it, so I built it too. After that I can run python.exe interpeter > directly and load winsound module in it. All be OK. > D:\....>python.exe > Python 2.4.4 (#71, May 17 2007, 16:53:33) [MSC v.1310 32 bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> > >>>import winsound > >>>winsound.PlaySound("SystemExit", winsound.SND_ALIAS) > > But I am interested in embeded python. I use this interpreter in > C++ code (MSVC7.1). And when I load winsound programmatically, the following error appears: > "No module named winsound". But such module as 'array' is imported > correctly: > import array > > What is wrong. Please, point me on my error. I guess the problem is related to location of winsound module. May be you can move the module to one of the directories Python is looking at or adjust sys.path variable. By the way you can use Boost.Python functionality to simplify a lot your code: http://boost.org/libs/python/doc/tutorial/doc/html/python/embedding.html > > > Code: > #include > > #include "Python.h" > > > int main(int /*argc*/, char** /*argv*/) > { > PyThreadState *m_threadState; > > // Initialize python > Py_NoSiteFlag = 1; > Py_Initialize(); > > // Enable thread support. > PyEval_InitThreads(); > > // Delete default thread state. > PyThreadState *l_default = PyThreadState_Get(); > Py_EndInterpreter(l_default); > > // Release global interpreter lock. > PyEval_ReleaseLock(); > > //start python > PyEval_AcquireLock(); > m_threadState = Py_NewInterpreter(); > PyEval_ReleaseThread(m_threadState); > > //-------Load winsound module----------!!!!!!!!!!!!!!!!!!!!!!!! > PyEval_AcquireThread(m_threadState); > > PyObject *l_module; > PyObject *l_dict; > PyObject *l_retValue; > > // we will use __main__ module as our global and local namespace. > l_module = PyImport_AddModule("__main__"); > if (!l_module) > { > PyEval_ReleaseThread(m_threadState); > return -1; > } > > std::string l_str = "import winsound"; > l_dict = PyModule_GetDict(l_module); > l_retValue = PyRun_StringFlags( > (char *)l_str.c_str(), > Py_file_input, > l_dict, > l_dict, > NULL); > if (!l_retValue) > { > //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > // Enter into this block!!!!!!!!!!!!!!!!!!! > PyEval_ReleaseThread(m_threadState); > return -1; > } > Py_DECREF(l_retValue); > > PyEval_ReleaseThread(m_threadState); > > //End > PyEval_AcquireThread(m_threadState); > Py_EndInterpreter(m_threadState); > PyEval_ReleaseLock(); > PyEval_AcquireLock(); > // Create default interpreter back. > Py_NewInterpreter(); > Py_Finalize(); > > return 0; > } > > -- > Best Regards, Irene Ladyko. > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Fri May 18 20:27:55 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 18 May 2007 20:27:55 +0200 Subject: [C++-sig] Exposing a template class In-Reply-To: <464D7222.4020509@cs.tut.fi> References: <464D7222.4020509@cs.tut.fi> Message-ID: <7465b6170705181127u63e13c0fue99b57e175f4ab2a@mail.gmail.com> On 5/18/07, Pertti Kellom?ki wrote: > Are there examples around of exposing instances of > template classes? I'm assuming it should be as easy > as enclosing a BOOST_PYTHON_MODULE inside a template > and instantiating the template, but it would be reassuring > to have some hand holding in case there are issues I have > not thought about. It is not that clear what you want to do. Exposing instantiation of template class is not different from exposing non-template class. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From pk at cs.tut.fi Fri May 18 20:42:50 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Fri, 18 May 2007 21:42:50 +0300 Subject: [C++-sig] Exposing a template class In-Reply-To: <7465b6170705181127u63e13c0fue99b57e175f4ab2a@mail.gmail.com> References: <464D7222.4020509@cs.tut.fi> <7465b6170705181127u63e13c0fue99b57e175f4ab2a@mail.gmail.com> Message-ID: <464DF3AA.80701@cs.tut.fi> Roman Yakovenko wrote: > It is not that clear what you want to do. Exposing instantiation of > template class is not different from exposing non-template class. I have a template class, whose three different instantiations are used as base classes for some concrete classes. I was wondering whether I could write a template that would expand into the appropriate declarations for exposing a particular instantiation. Just writing the wrapper struct as a template would of course already go a long way. -- Pertti From roman.yakovenko at gmail.com Fri May 18 20:44:26 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 18 May 2007 20:44:26 +0200 Subject: [C++-sig] Exposing a template class In-Reply-To: <464DF3AA.80701@cs.tut.fi> References: <464D7222.4020509@cs.tut.fi> <7465b6170705181127u63e13c0fue99b57e175f4ab2a@mail.gmail.com> <464DF3AA.80701@cs.tut.fi> Message-ID: <7465b6170705181144l7d23e3dft2084942ace05e6d0@mail.gmail.com> On 5/18/07, Pertti Kellom?ki wrote: > Roman Yakovenko wrote: > > It is not that clear what you want to do. Exposing instantiation of > > template class is not different from exposing non-template class. > > I have a template class, whose three different instantiations > are used as base classes for some concrete classes. I was > wondering whether I could write a template that would expand > into the appropriate declarations for exposing a particular > instantiation. Just writing the wrapper struct as a template > would of course already go a long way. Do you mean something like this: template< class T > void export_xx(const sd::string& name){ boost::python::class_< T, ... >( name ) .... ; } export_xx( "X1" ); export_xx( "X2" ); export_xx( "X3" ); Than yes, you can do this. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From seefeld at sympatico.ca Fri May 18 20:55:04 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Fri, 18 May 2007 14:55:04 -0400 Subject: [C++-sig] Exposing a template class In-Reply-To: <7465b6170705181144l7d23e3dft2084942ace05e6d0@mail.gmail.com> References: <464D7222.4020509@cs.tut.fi> <7465b6170705181127u63e13c0fue99b57e175f4ab2a@mail.gmail.com> <464DF3AA.80701@cs.tut.fi> <7465b6170705181144l7d23e3dft2084942ace05e6d0@mail.gmail.com> Message-ID: <464DF688.3040700@sympatico.ca> Roman Yakovenko wrote: > template< class T > > void export_xx(const sd::string& name){ > boost::python::class_< T, ... >( name ) > .... > ; > } > > export_xx( "X1" ); > export_xx( "X2" ); > export_xx( "X3" ); or even: template void export_instance(std::string const &name) { boost::python::class_, ...>(name.c_str()) ... } export_instance("int_container"); export_instance("float_container"); > Than yes, you can do this. > By the way, what you are referring to as 'template class' is actually a class template. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From roman.yakovenko at gmail.com Fri May 18 21:02:02 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 18 May 2007 21:02:02 +0200 Subject: [C++-sig] Exposing a template class In-Reply-To: <464DF688.3040700@sympatico.ca> References: <464D7222.4020509@cs.tut.fi> <7465b6170705181127u63e13c0fue99b57e175f4ab2a@mail.gmail.com> <464DF3AA.80701@cs.tut.fi> <7465b6170705181144l7d23e3dft2084942ace05e6d0@mail.gmail.com> <464DF688.3040700@sympatico.ca> Message-ID: <7465b6170705181202w611f6a50wfed90035da40e631@mail.gmail.com> On 5/18/07, Stefan Seefeld wrote: > By the way, what you are referring to as 'template class' is actually > a class template. Thanks. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From pk at cs.tut.fi Sat May 19 08:33:29 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Sat, 19 May 2007 09:33:29 +0300 Subject: [C++-sig] Exposing a template class In-Reply-To: <7465b6170705181144l7d23e3dft2084942ace05e6d0@mail.gmail.com> References: <464D7222.4020509@cs.tut.fi> <7465b6170705181127u63e13c0fue99b57e175f4ab2a@mail.gmail.com> <464DF3AA.80701@cs.tut.fi> <7465b6170705181144l7d23e3dft2084942ace05e6d0@mail.gmail.com> Message-ID: <464E9A39.4090708@cs.tut.fi> Roman Yakovenko wrote: > Do you mean something like this: [...] > Than yes, you can do this. That's exactly what I was looking for. Thanks! -- Pertti From srossross at gmail.com Sat May 19 21:38:12 2007 From: srossross at gmail.com (Sean Ross-Ross) Date: Sat, 19 May 2007 13:38:12 -0600 Subject: [C++-sig] Boost "From Python" Conversion and Template Classes Message-ID: <1ABEC499-AD7B-4753-B2F2-0DC027881F4C@gmail.com> I have a project where there is an internal reference count pointer to the objects passed through. And all of class methods are templated similar to: template class BasicEigenproblem : public virtual Eigenproblem { .... setOperator( const Teuchos::RefCountPtr& Op ); .... } In the C++ code to call this method you must do: RefCountPtr< Matrix > A = rcp( new Matrix( ... ) ); eigenproblem. setOperator(A); I would like to have the methods in python be just: A = Matrix() eigenproblem. setOperator(A) where I have templated BasicEigenproblem. And without dealing with the RefCountPtr, and have some method that calls in the background: RefCountPtr< object > RCPA = rcp( A ); I have tried experimenting with the extraction methods with no luck: 8: using namespace boost::python; 10: typedef Teuchos::RefCountPtr RCP; 12: void* extract_rcp(PyObject* obj) 13: { 14: RCP *r = new RCP( new object(handle<>(obj)), false ); 15: return r; 16: } 18: converter::registry::insert ( &extract_rcp, type_id() ); I get a few errors with this at compile time: extraction.cpp:18: error: expected constructor, destructor, or type conversion before '(' token I can not see to find a concrete example of how to do this. Am I one the right track, any Sugestions? Thanks, and sorry for the long winded message. ~Sean From tim at klingt.org Sat May 19 23:34:21 2007 From: tim at klingt.org (Tim Blechmann) Date: Sat, 19 May 2007 21:34:21 +0000 Subject: [C++-sig] call objects with argument-list / keyword Message-ID: <1179610461.9762.32.camel@localhost> hi all, is it possible to call a python object with argument-list as tuple and keyword-arguments as dictionary? something like: object callme; tuple args; dict keywords; callme(args, keywords); or do i need to call PyObject_Call directly? thanks, tim -- tim at klingt.org ICQ: 96771783 http://tim.klingt.org You can play a shoestring if you're sincere John Coltrane -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part URL: From fullung at gmail.com Mon May 21 15:14:05 2007 From: fullung at gmail.com (Albert Strasheim) Date: Mon, 21 May 2007 15:14:05 +0200 Subject: [C++-sig] Moving "decorator" into C++ part of module Message-ID: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> Hello all I have a class with various methods that return uBLAS matrices. I've wrapped various instantiations of these matrices with: template struct matrix_wrapper { static void wrap(const char* python_name) { py::class_(python_name, py::no_init) .add_property("__array_struct__", array_struct__) ; } static void cleanup(void* obj) { PyArrayInterface* ai = (PyArrayInterface*) obj; delete [] ai->shape; delete [] ai->strides; delete ai; } static PyObject* array_struct__(T const& self) { // http://numpy.scipy.org/array_interface.shtml PyArrayInterface* ai = new PyArrayInterface; // ... more code here ... ai->data = (void*) self.data().begin(); return PyCObject_FromVoidPtr(ai, cleanup); } } In Python this allows me to do: foo = WrappedClass() cmatrix = foo.somefunc() numpyarr = numpy.asarray(cmatrix) without a copy of cmatrix's contents having to be made. Now I'd just like to get rid of the asarray bit so that it looks like my wrapped functions return NumPy arrays. In Python I can "decorate" this function like so: def return_asarray(func): from numpy import asarray def call(*args, **kwargs): return asarray(func(*args, **kwargs)) return call WrappedClass.somefunc = return_asarray(WrappedClass.somefunc) but I would like to move this "decoration" into the C++ code, so that my module doesn't need to have the extra Python bits. Any thoughts on how this could be done? I looked at the documentation for class_, but nothing jumped out at me. Regards, Albert From roman.yakovenko at gmail.com Mon May 21 15:26:45 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 21 May 2007 16:26:45 +0300 Subject: [C++-sig] Moving "decorator" into C++ part of module In-Reply-To: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> References: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> Message-ID: <7465b6170705210626m2f7a5577r72eaa29af9bbe657@mail.gmail.com> On 5/21/07, Albert Strasheim wrote: > > Hello all > ... > without a copy of cmatrix's contents having to be made. Now I'd just > like to get rid of the asarray bit so that it looks like my wrapped > functions return NumPy arrays. In Python I can "decorate" this function > like so: > > def return_asarray(func): > from numpy import asarray > def call(*args, **kwargs): > return asarray(func(*args, **kwargs)) > return call > WrappedClass.somefunc = return_asarray(WrappedClass.somefunc) > > but I would like to move this "decoration" into the C++ code, so that > my module doesn't need to have the extra Python bits. > > Any thoughts on how this could be done? I looked at the documentation > for class_, but nothing jumped out at me. > Even call policies? If I understand right, you can create new call policy, implement postcall only member function and that's all. Am I missing something? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndbecker2 at gmail.com Mon May 21 15:45:26 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Mon, 21 May 2007 09:45:26 -0400 Subject: [C++-sig] Moving "decorator" into C++ part of module References: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> Message-ID: Albert Strasheim wrote: > Hello all > > I have a class with various methods that return uBLAS matrices. I've > wrapped various instantiations of these matrices with: > [...] I'm very interested in this. I thought array_interface was only a proposal at this point. You are using it? If I have python2.5, do I need something to try this out? (Like, where is the array_interface include file?) Could you post a complete code that shows how you convert ublas::matrix to numpy? Do you have converters in the other direction? From fullung at gmail.com Mon May 21 15:56:34 2007 From: fullung at gmail.com (Albert Strasheim) Date: Mon, 21 May 2007 15:56:34 +0200 Subject: [C++-sig] Moving "decorator" into C++ part of module In-Reply-To: <7465b6170705210626m2f7a5577r72eaa29af9bbe657@mail.gmail.com> References: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> <7465b6170705210626m2f7a5577r72eaa29af9bbe657@mail.gmail.com> Message-ID: <20070521135634.GB12892@dogbert.sdsl.sun.ac.za> Hello On Mon, 21 May 2007, Roman Yakovenko wrote: > Even call policies? If I understand right, you can create new call policy, > implement postcall only member function and that's all. > > Am I missing something? Thanks, got it working. Cheers, Albert From fullung at gmail.com Mon May 21 16:02:07 2007 From: fullung at gmail.com (Albert Strasheim) Date: Mon, 21 May 2007 16:02:07 +0200 Subject: [C++-sig] Moving "decorator" into C++ part of module In-Reply-To: References: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> Message-ID: <20070521140207.GC12892@dogbert.sdsl.sun.ac.za> Howdy On Mon, 21 May 2007, Neal Becker wrote: > Albert Strasheim wrote: > > > Hello all > > > > I have a class with various methods that return uBLAS matrices. I've > > wrapped various instantiations of these matrices with: > > > [...] > > I'm very interested in this. > > I thought array_interface was only a proposal at this point. You are using > it? If I have python2.5, do I need something to try this out? (Like, > where is the array_interface include file?) NumPy's array interface is ready to go. I think you might be thinking about the enhanced buffer protocol PEP thing. > Could you post a complete code that shows how you convert ublas::matrix to > numpy? Do you have converters in the other direction? Code attached. This is still very much a work in progress. Test it with: import numpy as N import os from numpy.testing import * # directory where you compiled the module set_local_path(os.path.join('..', 'win_build', 'Debug')) import pyublas restore_path() at = pyublas.array_test() print at print at.ref_return() print at.const_ref_return() print at.pointer_return() print at.const_pointer_return() As you can see, I can now convert return types (just haven't implemented return by-value yet). Now that I understand call policies properly, I'm going to look at converting arguments. Cheers, Albert -------------- next part -------------- #include #include #define PYUBLAS_FILE_WITH_INIT #ifndef PYUBLAS_FILE_WITH_INIT #define NO_IMPORT_ARRAY #endif #include // XXX for debugging purposes... remove later #include #include namespace ublas = boost::numeric::ublas; namespace py = boost::python; template struct matrix_wrapper { static void wrap(const char* python_name) { py::class_(python_name, py::no_init) // This will have to copy for things like symmetric matrices .add_property("__array_struct__", array_struct__) ; // register conversion for value arguments py::to_python_converter >(); // return conversion for return by-value py::converter::registry::push_back(convertible, construct, py::type_id()); } static void cleanup(void* obj) { PyArrayInterface* ai = (PyArrayInterface*) obj; delete [] ai->shape; delete [] ai->strides; delete ai; } static PyObject* array_struct__(T const& self) { // http://numpy.scipy.org/array_interface.shtml PyArrayInterface* ai = new PyArrayInterface; // contains the integer 2 as a sanity check ai->two = 2; // number of dimensions: two for a matrix ai->nd = 2; // kind in array --- character code of typestr ai->typekind = 'f'; // size of each element ai->itemsize = sizeof(T::value_type); // how should be data interpreted ai->flags = NPY_CONTIGUOUS | NPY_ALIGNED | NPY_NOTSWAPPED | NPY_WRITEABLE; // A length-nd array of shape information ai->shape = new npy_intp[2]; ai->shape[0] = self.size1(); ai->shape[1] = self.size2(); // A length-nd array of stride information ai->strides = new npy_intp[2]; ai->strides[0] = ai->shape[1] * ai->itemsize; ai->strides[1] = ai->itemsize; // A pointer to the first element of the array ai->data = (void*) self.data().begin(); ai->descr = NULL; return PyCObject_FromVoidPtr(ai, cleanup); } static void* convertible(PyObject* obj) { return PyArray_Check(obj) ? obj : NULL; } static void construct(PyObject* obj, py::converter::rvalue_from_python_stage1_data* data) { // get the storage typedef py::converter::rvalue_from_python_storage storage_t; storage_t* the_storage = reinterpret_cast(data); void* memory_chunk = the_storage->storage.bytes; // placement new T* a = new (memory_chunk) T(0, 0); // TODO need a special array adaptor here... data->convertible = memory_chunk; } static PyObject* convert(const T& a) { // TODO still need to do some work here return py::incref(Py_None); } }; typedef ublas::matrix > matrix_type; struct array_test { typedef matrix_type array_t; array_test() : data_(3, 4) { for (unsigned i = 0; i < data_.size1(); ++i) { for (unsigned j = 0; j < data_.size2(); ++j) { data_(i, j) = 3 * i + j; } } } array_t value_return() const { return data_; } array_t const* const_pointer_return() const { return &data_; } array_t* pointer_return() { return &data_; } array_t const& const_ref_return() const { return data_; } array_t& ref_return() { return data_; } void value_arg(array_t a) { print(a); } void pointer_arg(array_t* a) { print(*a); } void const_pointer_arg(array_t const* a) { } void ref_arg(array_t& a) { } void const_ref_arg(array_t const& a) { } private: void print(array_t const& a) { std::cout << a << std::endl; } array_t data_; }; template struct return_asarray : BasePolicy_ { template static PyObject* postcall(ArgumentPackage const& args_, PyObject* result) { result = BasePolicy_::postcall(args_, result); if (result == 0) { return 0; } return PyArray_FromStructInterface(result); } }; BOOST_PYTHON_MODULE(pyublas) { import_array(); matrix_wrapper::wrap("matrix_double"); py::class_("array_test") .def("value_return", &array_test::value_return) .def("const_pointer_return", &array_test::const_pointer_return, return_asarray >()) .def("pointer_return", &array_test::pointer_return, return_asarray >()) .def("const_ref_return", &array_test::const_ref_return, return_asarray >()) .def("ref_return", &array_test::ref_return, return_asarray >()) #if 0 .def("value_arg", &array_test::value_arg) .def("pointer_arg", &array_test::pointer_arg) .def("const_pointer_arg", &array_test::const_pointer_arg) .def("ref_arg", &array_test::ref_arg) .def("const_ref_arg", &array_test::const_ref_arg) #endif ; } From nick.lee at volition-inc.com Mon May 21 18:07:17 2007 From: nick.lee at volition-inc.com (Nick Lee) Date: Mon, 21 May 2007 11:07:17 -0500 Subject: [C++-sig] building static boost.python libraries in 1.34? Message-ID: I just downloaded Boost 1.34 as well as Boost.Jam 3.1.14. I'm trying to manually build the Boost.Python libraries from the command line, but it looks like things have changed from 1.33.1. I switched to the libs\python\build\ directory and entered the following command: bjam --toolset=msvc release It looks like it built the dynamic-link library ("boost_python-vc80-mt-1_34.dll") and its corresponding import library ("boost_python-vc80-mt-1_34.lib"), but the static-link library is nowhere to be found. According to the new documentation, the file should be named something like "libboost_python-vc80-xxx.lib", but I can't find it anywhere. Under 1.33.1, the file would have been named "libboost_python.lib", and the command-line call to bjam would have automatically created it. How do I build the Boost.Python static-link library in 1.34? Is there a command-line parameter I'm missing for bjam? From ndbecker2 at gmail.com Mon May 21 20:21:17 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Mon, 21 May 2007 14:21:17 -0400 Subject: [C++-sig] Moving "decorator" into C++ part of module References: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> <20070521140207.GC12892@dogbert.sdsl.sun.ac.za> Message-ID: This looks very good so far. I see there is c++ ublas -> python numpy conversion. Have you tried the other direction? python numpy -> c++ ublas? From fullung at gmail.com Mon May 21 20:54:33 2007 From: fullung at gmail.com (Albert Strasheim) Date: Mon, 21 May 2007 20:54:33 +0200 Subject: [C++-sig] Moving "decorator" into C++ part of module In-Reply-To: References: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> <20070521140207.GC12892@dogbert.sdsl.sun.ac.za> Message-ID: <20070521185433.GA19431@dogbert.sdsl.sun.ac.za> Hello On Mon, 21 May 2007, Neal Becker wrote: > This looks very good so far. I see there is c++ ublas -> python numpy > conversion. With a few more templates and whatnot one can take care of things figuring out that for a matrix the typecode should be 'i', etc. For now I'm just focusing on getting double working. But soon... > Have you tried the other direction? python numpy -> c++ ublas? I'm trying to sort this out now. Here there are a few more complications: 1. Some array adaptor complications (nothing too major) to make a uBLAS matrix use the array's data without a copy 2. Conversion of NumPy array arguments to uBLAS I'm currently stuck here. I was hoping to do something like: template < class T, std::size_t arg, class BasePolicy_ = py::default_call_policies > struct convert_array : BasePolicy_ { BOOST_STATIC_ASSERT(arg > 0); template static bool precall(ArgumentPackage const& args_) { unsigned int arity_ = PyTuple_GET_SIZE(args_); if (arg > arity_) { PyErr_SetString( PyExc_IndexError, "convert_array: argument index out of range"); return false; } PyObject* obj = PyTuple_GetItem(args_, arg); if (obj == NULL) { return false; } if (!PyArray_Check(obj)) { PyErr_SetString( PyExc_TypeError, "convert_array: ndarray argument expected"); return NULL; } // XXX magic happens here see below return BasePolicy_::precall(args_); } }; What I wanted to attempt at XXX is to create an instance of a uBLAS vector/matrix/whatever inside its associated PyObject, with the uBLAS matrix using the memory of the NumPy array. I was hoping I could then do a little bait and switch on the tuple item to put this new uBLAS-PyObject-using-a-Numpy-array into the arguments before the function gets called. You could then wrap the method something like this: py::class_("array_test") .def("pointer_arg", &array_test::pointer_arg, convert_array, 1>()) Unfortunately, it seems checking of argument types happens before the the convert_array precall (not much of a *pre*call is it? ;-)), so this trick doesn't work (you get an ArgumentError). Any ideas would help at this point. :-) Regards, Albert From nick.lee at volition-inc.com Mon May 21 20:55:40 2007 From: nick.lee at volition-inc.com (Nick Lee) Date: Mon, 21 May 2007 13:55:40 -0500 Subject: [C++-sig] building static boost.python libraries in 1.34? References: Message-ID: Um, nevermind. I think I figured it out. I just ran bjam from the boost root directory rather than from the libs\python\build\ directory. Built everything properly. Funny how things work better when you follow directions. :) Niq From ndbecker2 at gmail.com Mon May 21 21:11:43 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Mon, 21 May 2007 15:11:43 -0400 Subject: [C++-sig] Moving "decorator" into C++ part of module References: <20070521131405.GA12892@dogbert.sdsl.sun.ac.za> <20070521140207.GC12892@dogbert.sdsl.sun.ac.za> <20070521185433.GA19431@dogbert.sdsl.sun.ac.za> Message-ID: Albert Strasheim wrote: > Hello > > On Mon, 21 May 2007, Neal Becker wrote: > >> This looks very good so far. I see there is c++ ublas -> python numpy >> conversion. > > With a few more templates and whatnot one can take care of things > figuring out that for a matrix the typecode should be 'i', etc. For > now I'm just focusing on getting double working. But soon... > >> Have you tried the other direction? python numpy -> c++ ublas? > > I'm trying to sort this out now. Here there are a few more > complications: > > 1. Some array adaptor complications (nothing too major) to make a uBLAS > matrix use the array's data without a copy > > 2. Conversion of NumPy array arguments to uBLAS > > I'm currently stuck here. I was hoping to do something like: > > template < > class T, > std::size_t arg, > class BasePolicy_ = py::default_call_policies >> > struct convert_array : BasePolicy_ > { > BOOST_STATIC_ASSERT(arg > 0); > > template > static bool precall(ArgumentPackage const& args_) > { > unsigned int arity_ = PyTuple_GET_SIZE(args_); > if (arg > arity_) { > PyErr_SetString( > PyExc_IndexError, > "convert_array: argument index out of range"); > return false; > } > PyObject* obj = PyTuple_GetItem(args_, arg); > if (obj == NULL) { > return false; > } > if (!PyArray_Check(obj)) { > PyErr_SetString( > PyExc_TypeError, > "convert_array: ndarray argument expected"); > return NULL; > } > > // XXX magic happens here see below > > return BasePolicy_::precall(args_); > } > }; > > What I wanted to attempt at XXX is to create an instance of a uBLAS > vector/matrix/whatever inside its associated PyObject, with the > uBLAS matrix using the memory of the NumPy array. I was hoping I could > then do a little bait and switch on the tuple item to put this new > uBLAS-PyObject-using-a-Numpy-array into the arguments before the > function gets called. > > You could then wrap the method something like this: > > py::class_("array_test") > .def("pointer_arg", > &array_test::pointer_arg, > convert_array, 1>()) > > Unfortunately, it seems checking of argument types happens before the > the convert_array precall (not much of a *pre*call is it? ;-)), so this > trick doesn't work (you get an ArgumentError). > > Any ideas would help at this point. :-) > Mostly I'd be interested in the following. My use case is I have lots of c++ algorithms written for ublas interface (or maybe a more generic superset of that). I want to use them from python. I want to call them with numpy arrays. Someone has to convert the numpy array to a ublas interface, then call the c++ algorithm, and maybe convert the ublas object back to numpy to python. From jmoorkan at uci.edu Tue May 22 04:56:25 2007 From: jmoorkan at uci.edu (Jayram) Date: Mon, 21 May 2007 19:56:25 -0700 Subject: [C++-sig] boost python installation problem Message-ID: Hi all, My configuration is the following: MS-Visual Studio 95 - "vc-8_0", Boost = 1.33.1, Python = 2.5 I was trying to build python boost using the command: >> bjam -sTOOLS=vc-8_0 -sPYTHON_VERSION=2.5 -sPYTHON_ROOT=C:\Python25" A part of build output is the following which starts immediately after compiling all the files. --------------------------- vc-C++ ..\..\..\bin\boost\libs\python\build\boost_python.dll\vc-8_0\debug\threading-multi\object_operators.obj object_operators.cpp vc-C++ ..\..\..\bin\boost\libs\python\build\boost_python.dll\vc-8_0\debug\threading-multi\wrapper.obj wrapper.cpp vc-Link ..\..\..\bin\boost\libs\python\build\boost_python.dll\vc-8_0\debug\threading-multi\boost_python_debug.dll ..\..\..\bin\boost\libs\python\build\boost_python.dll\vc-8_0\debug\threading-multi\boost_python_debug.lib Creating library ..\..\..\bin\boost\libs\python\build\boost_python.dll\vc-8_0\debug\threading-multi\boost_python_debug.lib and object ..\..\..\bin\boost\libs\python\build\boost_python.dll\vc-8_0\debug\threading-multi\boost_python_debug.exp function.obj : error LNK2019: unresolved external symbol __imp__PyErr_Format referenced in function "public: virtual void * __thiscall boost::python::error_already_set::`vector deleting destructor'(unsigned int)" (??_Eerror_already_set at python@boost@@UAEPAXI at Z) numeric.obj : error LNK2001: unresolved external symbol __imp__PyErr_Format from_python.obj : error LNK2001: unresolved external symbol __imp__PyErr_Format registry.obj : error LNK2001: unresolved external symbol __imp__PyErr_Format ------------------------- and the unresolved external symbol error continues and boost_python_debug.dll is not generated. I have been working only in GNU/Linux build environment, BUT M$ Windows is totally new to me. So can anyone point out how to fix this error ? What I understood is that vc-Link does not find some important libraries during linking which is associated with Python and Boost ? But I am unable to proceed from here to determine what is the problem and how to fix it ? Thanks and any suggestion to me will be helpful. - Jay From luca.sbardella at gmail.com Tue May 22 12:53:28 2007 From: luca.sbardella at gmail.com (Luca Sbardella) Date: Tue, 22 May 2007 12:53:28 +0200 Subject: [C++-sig] exposing iterator for the values of std::map Message-ID: <8315652a0705220353m3e0e41d9k89200115951c9641@mail.gmail.com> Hi, I'm trying to expose to python the iterator of a specific class with this skeleton class bla; typedef boost::shared_ptr BLA; class bla { public: typedef std::map container; typedef container::iterator iterator; static BLA get(const std::string& code); static iterator begin() {return s_db.begin();} static iterator end() {return s_db.end();} std::string code() const {return ...} private: static container s_db; }; the bla class is exposed to Python in the usual way. my question is how do I expose the iterator such that in Python I can iterate through the elements in s_db as it was a list (I want to see the BLA elements not the keys of the map). In other words I would like to be able to do this b = bla(...) for i in b: print i.code() Naively, I tried to use .def("__iter__", range(&bla::begin,&bla::end)) but, not surprisingly, it doesn't work (something to do with the implementation of NextPolicies I assume). Best Luca -------------- next part -------------- An HTML attachment was scrubbed... URL: From rwgk at yahoo.com Tue May 22 19:14:42 2007 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 22 May 2007 10:14:42 -0700 (PDT) Subject: [C++-sig] Better introspection/apidoc extraction support? Message-ID: <566772.7647.qm@web31107.mail.mud.yahoo.com> > > How exactly does this work? Are there web pages about this? > > Not that I know of. AFAICS, there is no public API for that (that's why I > wrote "half-private"), but if you look at a functions func_code.co_XXX and > func_defaults properties, you see that there is a lot of internal information > available in CPython. Sorry, this looks like more work than I'm able to squeeze in. I was hoping for a well-established, time-tested API, but it looks more like work in progress. If someone contributes patches including docs I'd be happy to try them out and check them in. The current docstring support isn't all that complicated. Look in boost/libs/python/src/object/function.cpp, mainly function::signature(). Ralf ____________________________________________________________________________________ Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center. http://autos.yahoo.com/green_center/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From pk at cs.tut.fi Wed May 23 18:17:31 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Wed, 23 May 2007 19:17:31 +0300 Subject: [C++-sig] Transfer of ownership, constructors and Py++ Message-ID: <4654691B.7020906@cs.tut.fi> I am trying out Py++, and so far it looks very nice. I figured how to do transfer of ownership for ordinary member functions using function_transformers.transfer_ownership(), but is there a simple way to do the same for constructors? -- Pertti From roman.yakovenko at gmail.com Wed May 23 19:39:41 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 23 May 2007 20:39:41 +0300 Subject: [C++-sig] Transfer of ownership, constructors and Py++ In-Reply-To: <4654691B.7020906@cs.tut.fi> References: <4654691B.7020906@cs.tut.fi> Message-ID: <7465b6170705231039i19f894e9q23ebf8f20c95387e@mail.gmail.com> On 5/23/07, Pertti Kellom?ki wrote: > I am trying out Py++, and so far it looks very nice. Thanks > I figured how to do transfer of ownership for ordinary > member functions using function_transformers.transfer_ownership(), > but is there a simple way to do the same for constructors? No, this functionality is missing, but it should be pretty simple to add it. Please open "Feature request": http://sourceforge.net/tracker/?group_id=118209 Or if you need it badly we can work together on this feature. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From nick.lee at volition-inc.com Thu May 24 17:24:12 2007 From: nick.lee at volition-inc.com (Nick Lee) Date: Thu, 24 May 2007 10:24:12 -0500 Subject: [C++-sig] newbie question: returning a tuple of strings Message-ID: How do I write a C++ function that returns a tuple of strings to Python using Boost.Python? Is std::string the only string format that Boost.Python recognizes? Niq From seefeld at sympatico.ca Thu May 24 17:36:17 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 24 May 2007 11:36:17 -0400 Subject: [C++-sig] newbie question: returning a tuple of strings In-Reply-To: References: Message-ID: <4655B0F1.2050707@sympatico.ca> Nick Lee wrote: > How do I write a C++ function that returns a tuple of strings to Python > using Boost.Python? Is std::string the only string format that Boost.Python > recognizes? char const * should work just fine: object result = make_tuple("first", "second", "third"); ... HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From meine at informatik.uni-hamburg.de Fri May 25 14:40:54 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Fri, 25 May 2007 14:40:54 +0200 Subject: [C++-sig] Better introspection/apidoc extraction support? In-Reply-To: <566772.7647.qm@web31107.mail.mud.yahoo.com> References: <566772.7647.qm@web31107.mail.mud.yahoo.com> Message-ID: <200705251440.54910.meine@informatik.uni-hamburg.de> Hi Ralf! Am Dienstag, 22. Mai 2007 19:14:42 schrieb Ralf W. Grosse-Kunstleve: > Sorry, this looks like more work than I'm able to squeeze in. I was hoping > for a well-established, time-tested API, but it looks more like work in > progress. That's a pity, but I can understand it. OTOH, I don't think there is much progress ATM, as long as PEP 362 is not implemented. (Is there a reason you did not reply to my later post where I mentioned http://www.python.org/dev/peps/pep-0362/ - I just want to make sure you saw it.) I indeed wrote a parser for the C++ signatures for epydoc, but it is quite complicated since I have to - parse arbitrary C++ types (templates with argument literals, namespaces, ...), which made me hack together a rather largish pyparsing-based parser (and as you know, writing a C++ parser is not what you wanna do..) - parse arbitrary Python __repr__ output for the default arguments. Again, that is not doable with just regular expressions, also the __repr__ can be basically anything, so it cannot be 100% safe. It would be much better if there was an API to extract argument names and default values. > The current docstring support isn't all that complicated. Look in > boost/libs/python/src/object/function.cpp, mainly function::signature(). When using epydoc, I noticed that the resulting docstrings are no valid reST anymore if the original docstring does not end with a \n: """foo bar C++ signature: test(void) -> void""" However, this would be a valid description list: """foo bar C++ signature: test(void) -> void""" Would it make sense to just add two \n instead of one in libs/python/src/object/function.cpp:510? Or look at the attached patch, which also cares about docstrings to which a \n has manually been appended for boost 1.34.0beta + epydoc support. That does not yet lead to a very pretty output, but it is a minimal change that makes epydoc w/ reST work at least, without further modifications. -- Ciao, / / /--/ / / ANS -------------- next part -------------- A non-text attachment was scrubbed... Name: boost_separated_cppsignatures.diff Type: text/x-diff Size: 602 bytes Desc: not available URL: From srossross at gmail.com Fri May 25 17:18:53 2007 From: srossross at gmail.com (Sean Ross-Ross) Date: Fri, 25 May 2007 09:18:53 -0600 Subject: [C++-sig] exposing Template methods and classes Message-ID: <69E14FC7-CB04-49E8-BBBF-E62625042FBD@gmail.com> Is there a way that I can smartly template classes or functions depending on the type of python Object passed to them? for example, say you expose a vector class and as a constructor pass a extra argument "dtype", like numpy, that templates the vector to that type. or any what at all that does not involve templating it on a PyObject. So I don't have to template every type that I could possibly want? ~Sean From Lawrence.Spector at CanfieldSci.com Fri May 25 20:35:52 2007 From: Lawrence.Spector at CanfieldSci.com (Lawrence Spector) Date: Fri, 25 May 2007 14:35:52 -0400 Subject: [C++-sig] [Boost.Python] Issues Building Boost.Python Extensions with Boost.Build v2 using Boost 1.34.0 In-Reply-To: <69E14FC7-CB04-49E8-BBBF-E62625042FBD@gmail.com> References: <69E14FC7-CB04-49E8-BBBF-E62625042FBD@gmail.com> Message-ID: I successfully was building Boost.Python extensions using bjam version 1 in Boost 1.33.1. Since the upgrade, I converted my Jamfile to Jamfile.v2 and am getting the following errors when I try to build: bjam -sTOOLS=vc-8_0 -sBOOST_ROOT=C:\3rdparty\boost_1_34_0 -sBUILD=debug error: Could not find parent for project at '.' error: Did not find Jamfile or project-root.jam in any parent directory. Here's my Jamfile: # This is the top of our own project tree project-root ; import python ; extension MyLib # Declare a Python extension : MyLib.cpp # source # requirements and dependencies for Boost.Python extensions