From nies.stephan at googlemail.com Thu Feb 1 20:33:32 2007 From: nies.stephan at googlemail.com (stephan nies) Date: Thu, 1 Feb 2007 20:33:32 +0100 Subject: [C++-sig] can't import Boost.Python Extension OSX 10.4 Message-ID: <79f682bf0702011133v520496f6k9913bb1a4dbf6bd@mail.gmail.com> Hello, i am porting an app from linux to osx which uses bost.python - extension module Machine: 2 GHz PowerPC G5 OS: Mac OS X 10.4.8 Python: python-2.4.4-macosx2006-10-18.dmg from http://pythonmac.org/packages/py24-fat/dmg/ (this is a framework build) Boost: 1.33.1 build from source (./configure && make) i am building my extension by invoking: g++ -dynamic myextension.cpp -I/Library/Frameworks/Python.framework/Headers -I/System/Library/Frameworks/GLUT.framework/Headers -I/usr/include -I/Users/nies/src/boost_1_33_1 -c -o myextension.o and g++ -v -dynamiclib -framework Python -framework OpenGL -framework GLUT -L/Users/nies/src/boost_1_33_1/bin/boost/libs/python/build/libboost_python.dylib/darwin/release/shared-linkable-true/ -lboost_python-1_33_1 myextension.o -o myextension.dylib this compiles and when i try to import the extension in pythonw: Python 2.4.4 (#1, Oct 18 2006, 10:34:39) [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import myextension Traceback (most recent call last): File "", line 1, in ? ImportError: No module named myextension as far as i understand this is because python searches for .so files. when i symbolic-link myextension.so -> myextension.dylib and than try to import: Python 2.4.4 (#1, Oct 18 2006, 10:34:39) [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import myextension Traceback (most recent call last): File "", line 1, in ? ImportError: Inappropriate file type for dynamic loading so what am i doing wrong here? i searched around now quite some time but didn't find anything but the .dylib to .so renaming. I would really appreciate some hints at this point. Thanks, Stephan From newsuser at stacom-software.de Fri Feb 2 20:09:48 2007 From: newsuser at stacom-software.de (Alexander Eisenhuth) Date: Fri, 02 Feb 2007 20:09:48 +0100 Subject: [C++-sig] Issues with Debug/Release versions of Python and extensions Message-ID: Hello everybody, did some of you got ever into a hell of runtime problems like _CrtIsValidHeapPointer on Windows ? (Debug Version of a multithreaded Python extension) No? Ok a straight question, that hopefully anybody can answer. Might there appear problems, when I use a standard python Installation (nodebug-version) on windows to debug a extension (debug-version) ? Now a bit more deeper in detail what happens: I import a debug c++ extension build with vc6.0 with bosst.python. After some calls from python -> Extension, various threads are initialized and do a lot of work (but no python API calls). In total I've 4 threads. The python (main) thread waits on a raw_input(), so I'm quite sure nothing happens in the main thread. After some time (not predictable) the _CrtIsValidHeapPointer() assertion fails (This is only done by CRT in debug mode) in a extension thread. When I compile the extension as release, no _CrtIsValidHeapPointer() appears of course, but no other noticable problems appear also. I'm quite sure that the extensions code is clean, because this is used for many years without python as C++ application. Every comment is very welcome. Thank a lot for reading Alexander From roman.yakovenko at gmail.com Fri Feb 2 20:18:16 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 2 Feb 2007 21:18:16 +0200 Subject: [C++-sig] Issues with Debug/Release versions of Python and extensions In-Reply-To: References: Message-ID: <7465b6170702021118g717c45fap28f9e797ff7197ae@mail.gmail.com> On 2/2/07, Alexander Eisenhuth wrote: > Hello everybody, > > did some of you got ever into a hell of runtime problems like > _CrtIsValidHeapPointer on Windows ? (Debug Version of a multithreaded Python > extension) Yes. I used Python.Net project for create huge number of tests for code written in Managed C++. > > Ok a straight question, that hopefully anybody can answer. > > Might there appear problems, when I use a standard python Installation > (nodebug-version) on windows to debug a extension (debug-version) ? Except this annoying problem, I didn't have any problem. I was able to debug managed and unmanaged code. > Now a bit more deeper in detail what happens: > > I import a debug c++ extension build with vc6.0 with bosst.python. After some > calls from python -> Extension, various threads are initialized and do a lot of > work (but no python API calls). In total I've 4 threads. The python (main) > thread waits on a raw_input(), so I'm quite sure nothing happens in the main thread. > > After some time (not predictable) the _CrtIsValidHeapPointer() assertion fails > (This is only done by CRT in debug mode) in a extension thread. > When I compile the extension as release, no _CrtIsValidHeapPointer() appears of > course, but no other noticable problems appear also. > > I'm quite sure that the extensions code is clean, because this is used for many > years without python as C++ application. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From newsuser at stacom-software.de Fri Feb 2 20:38:43 2007 From: newsuser at stacom-software.de (Alexander Eisenhuth) Date: Fri, 02 Feb 2007 20:38:43 +0100 Subject: [C++-sig] Issues with Debug/Release versions of Python and extensions In-Reply-To: <7465b6170702021118g717c45fap28f9e797ff7197ae@mail.gmail.com> References: <7465b6170702021118g717c45fap28f9e797ff7197ae@mail.gmail.com> Message-ID: Thanks for your quick answer Roman Yakovenko schrieb: > On 2/2/07, Alexander Eisenhuth wrote: >> Hello everybody, >> >> did some of you got ever into a hell of runtime problems like >> _CrtIsValidHeapPointer on Windows ? (Debug Version of a multithreaded Python >> extension) > > Yes. I used Python.Net project for create huge number of tests for > code written in > Managed C++. That means you also use a "release exe" and "debug exe" and got _CrtIsValidHeapPointer() assertions ? > >> Ok a straight question, that hopefully anybody can answer. >> >> Might there appear problems, when I use a standard python Installation >> (nodebug-version) on windows to debug a extension (debug-version) ? > > Except this annoying problem, I didn't have any problem. I was able to debug > managed and unmanaged code. Did you look for compiler switches or pragmas to turn _CrtIsValidHeapPointer() off? From e.tadeu at gmail.com Fri Feb 2 20:49:50 2007 From: e.tadeu at gmail.com (Edson Tadeu) Date: Fri, 2 Feb 2007 17:49:50 -0200 Subject: [C++-sig] init from free function instead of constructor Message-ID: I'm also getting the same errors when trying to wrap a "free" constructor returning by value for a class whose holder is itself. Inside detail::install_holder::dispatch(Ptr x, mpl::false_), it is trying to access the type pointee::type, but Ptr is my own class and not a smart pointer, so the compiler gets angry with pointee_impl::apply trying to get T::element_type. Is there any fix for this or any solution that do not involve an ugly hack with heap allocation and converting back and forth between shared_ptr<>? Thanks John Reid wrote: Ok so by-value should be handled by the default call policies if the documentation is right. I have checked with a minimal test case that I get the same errors: class X { }; X make_x( const std::string & ) { return X(); } void export_x() { using namespace boost::python; class_< X > x( "X" ); x.def( "__init__", make_constructor( make_x ) ); } -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Fri Feb 2 20:53:59 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 2 Feb 2007 21:53:59 +0200 Subject: [C++-sig] Issues with Debug/Release versions of Python and extensions In-Reply-To: References: <7465b6170702021118g717c45fap28f9e797ff7197ae@mail.gmail.com> Message-ID: <7465b6170702021153y2d3c0030n7ac0db4e9a41c41d@mail.gmail.com> On 2/2/07, Alexander Eisenhuth wrote: > > Yes. I used Python.Net project for create huge number of tests for > > code written in > > Managed C++. > > That means you also use a "release exe" and "debug exe" and got > _CrtIsValidHeapPointer() assertions ? Python 2.4 release build( standard Python 2.4 setup ), [un]managed code was built in debug mode. > > > >> Ok a straight question, that hopefully anybody can answer. > >> > >> Might there appear problems, when I use a standard python Installation > >> (nodebug-version) on windows to debug a extension (debug-version) ? > > > > Except this annoying problem, I didn't have any problem. I was able to debug > > managed and unmanaged code. > > Did you look for compiler switches or pragmas to turn _CrtIsValidHeapPointer() off? I did not have time to find out what is the exact problem. I just built release version with debug information. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Fri Feb 2 21:43:58 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 2 Feb 2007 22:43:58 +0200 Subject: [C++-sig] init from free function instead of constructor In-Reply-To: References: Message-ID: <7465b6170702021243p3e7e3af8lbb9fce6b0c06d20@mail.gmail.com> On 2/2/07, Edson Tadeu wrote: > I'm also getting the same errors when trying to wrap a "free" constructor > returning by value for a class whose holder is itself. > > Inside detail::install_holder::dispatch(Ptr x, > mpl::false_), it is trying to access the type pointee::type, but Ptr is > my own class and not a smart pointer, so the compiler gets angry with > pointee_impl::apply trying to get T::element_type. > > Is there any fix for this or any solution that do not involve an ugly hack > with heap allocation and converting back and forth between shared_ptr<>? According to source ( http://tinyurl.com/3bddpf ) make_constructor function should return raw pointer or an instance of a smart pointer. The unit test( http://tinyurl.com/2oktkh ) confirms this. It makes sense. Otherwise you will create 3 instances of the class: 1. The first instance within the function 2. The instance, which will be created using copy-constructor, as function return value 3. (I could be wrong here, I am not sure! ) Boost.Python allocate and manage all instances of classes using heap. So here you will construct another instance on heap, using copy constructor. I believe it is pretty simple to add functionality you want, but does it worse that? P.S. The documentation for the functionality could be improved, care to submit a patch? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From e.tadeu at gmail.com Mon Feb 5 12:56:35 2007 From: e.tadeu at gmail.com (Edson Tadeu) Date: Mon, 5 Feb 2007 09:56:35 -0200 Subject: [C++-sig] init from free function instead of constructor In-Reply-To: <7465b6170702021243p3e7e3af8lbb9fce6b0c06d20@mail.gmail.com> References: <7465b6170702021243p3e7e3af8lbb9fce6b0c06d20@mail.gmail.com> Message-ID: Hi Roman, thanks for the answer, According to source ( http://tinyurl.com/3bddpf ) make_constructor function > should return raw pointer or an instance of a smart pointer. > The unit test( http://tinyurl.com/2oktkh ) confirms this. > > It makes sense. Otherwise you will create 3 instances of the class: > 1. The first instance within the function > 2. The instance, which will be created using copy-constructor, as > function return > value > 3. (I could be wrong here, I am not sure! ) Boost.Python allocate and > manage all > instances of classes using heap. So here you will construct another > instance > on heap, using copy constructor. Well, I'm not sure about 3 too and I do not know where to find about it, but if 3 is really true, I think there is no point in wrapping a class using itself as holder (e.g., class_< T, T >), it would always be better to wrap it using a shared_ptr as a holder (class_ < T, shared_ptr >). I have a class that already manages some things in the heap and have smart copy constructors, etc., and I would not like the extra indirection to have the class instances themselves in the heap. But maybe you are right, or it would not make too much difference between the objects being in the heap or in the body of a PyObject, and I will just wrap them inside shared_ptr holders. I believe it is pretty simple to add functionality you want, but does > it worse that? Do you mean, to add it in the library? Maybe it really is simple. I use the library a lot, but I do not know very well its underlying mechanisms, but it would be a good exercise for me. P.S. The documentation for the functionality could be improved, care > to submit a patch? That's ok, I could do it when I have full certainty about the problem. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ext at sidvind.com Tue Feb 6 11:43:03 2007 From: ext at sidvind.com (David Sveningsson) Date: Tue, 06 Feb 2007 11:43:03 +0100 Subject: [C++-sig] Converting custom string pointer to python string In-Reply-To: <4427.83.209.20.150.1169843735.squirrel@mail.sidvind.com> References: <725570.16730.qm@web31114.mail.mud.yahoo.com> <4541.83.209.20.150.1169841863.squirrel@mail.sidvind.com> <45BA5F78.7000305@sympatico.ca> <4427.83.209.20.150.1169843735.squirrel@mail.sidvind.com> Message-ID: <45C85BB7.5050405@sidvind.com> ext at sidvind.com skrev: >>> Yes, I read that. That helped me to come as far as I have. But it only >>> shows how to use copied instances and references, not pointers. >>> >> In Python, strings are invariant (i.e. const). You can't modify a string >> in place. Thus, what I believe you are aiming for isn't possible, on the >> language level. >> >> Regards, >> Stefan >> >> > > First I should explain the CustomString class. It has no methods to modify > the string, they are constructed once and then used as they are. > > CustomString is often passed around in my c++ code using pointers. > > What I want to do is to be able to use strings to/from python. If I call a > function that takes a CustomString pointer I don't want to call a factory > function to create the string first, I just want to use a python string. > > Like this: > > c++ prototype: void func(CustomString* str); > current python code: func(factory('asdf')) > wanted python code: func('asdf') > > I would also like to have a function returning a CustomString pointer to > also be converted to a python string. > > c++ prototype: CustomString* foo() > > Right now the CustomString class is exposed and has the __str__ function > overloaded to allow me to print it. But I would rather like to deal with > it completely as a python string. > > I hope and think this is possible. As I said, I don't need to modify the > strings. > > What about opaque pointer? Cant that be used to archive this? > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > > I still don't get this to work, using const doesn't help either. Should I try to wrap the pointers with the raw python c api instead of boost? -- //*David Sveningsson [eXt]* Freelance coder | Game Development Student http://sidvind.com Thou shalt make thy program's purpose and structure clear to thy fellow man by using the One True Brace Style, even if thou likest it not, for thy creativity is better used in solving problems than in creating beautiful new impediments to understanding. From python_news.3.strot_at_paraxip at spamgourmet.org Tue Feb 6 19:54:36 2007 From: python_news.3.strot_at_paraxip at spamgourmet.org (Francis Moreau) Date: Tue, 6 Feb 2007 13:54:36 -0500 Subject: [C++-sig] Passing a C++ instance to a Python script Message-ID: Hello, I need to pass a C++ instance to a Python function, then the Python function can call back the C++ instance object. I found this following sample that do it well when the script is embedded into the C++ code within the PyRun_String function. I need to have something similar but with the PyRun_String content in a .py file. As a matter of fact, when I am trying to move the PyRun_String content into a .py file the line "object foo(main_module.attr("foo"));" fails since the foo function is unknown from the main dictionary. Thanks for help, Francis // Copyright David Abrahams 2002. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Example by Vladimir Prus that passes C++ object into Python, and // call that object back from Python. Based on: // embedded_hello -- A simple Boost.Python embedding example -- by // Dirk Gerrits #include #include #include #include #include #include using namespace boost::python; namespace python = boost::python; void export_classes_to_python(); class InterfaceForPython { public: void say() const { std::cout << "InterfaceForPython::say(), address is " << this << "\n"; } void run() const { std::cout << "InterfaceForPython::run(), address is " << this << "\n"; std::cout << "About to call Python function\n"; export_classes_to_python(); Py_Initialize(); // Retrieve the main module object main_module(( handle<>(python::borrowed(PyImport_AddModule("__main__"))))); // Retrieve the main module's namespace object main_namespace((main_module.attr("__dict__"))); // Prepare the Python code. We'll call the 'foo' method. python::handle<> result(PyRun_String( "from extended_test import * \n" "def foo(p): \n" " print 'Calling C++ method from Python' \n" " p.say() \n", Py_file_input, main_namespace.ptr(), main_namespace.ptr()) ); // Result is not needed result.reset(); // Get the 'foo' function. object foo(main_module.attr("foo")); // Invoke it, passing ourselfs *by pointer*. foo(ptr(this)); } }; BOOST_PYTHON_MODULE(extended_test) { object class_InterfaceForPython = class_("InterfaceForPython") .def("say", &InterfaceForPython::say); } void export_classes_to_python() { // Register the module with the interpreter if (PyImport_AppendInittab("extended_test", initextended_test) == -1) throw std::runtime_error("Failed to add embedded_hello to the interpreter's " "builtin modules"); } int main() { InterfaceForPython pyint; if (python::handle_exception(boost::bind(&InterfaceForPython::run, pyint))) { if (PyErr_Occurred()) PyErr_Print(); return 1; } return 0; } From seefeld at sympatico.ca Tue Feb 6 20:11:24 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 06 Feb 2007 14:11:24 -0500 Subject: [C++-sig] Passing a C++ instance to a Python script In-Reply-To: References: Message-ID: <45C8D2DC.8080309@sympatico.ca> Francis Moreau wrote: > Hello, > > I need to pass a C++ instance to a Python function, then the Python function > can call back the C++ instance object. I found this following sample that do > it well when the script is embedded into the C++ code within the > PyRun_String function. I need to have something similar but with the > PyRun_String content in a .py file. As a matter of fact, when I am trying to > move the PyRun_String content into a .py file the line "object > foo(main_module.attr("foo"));" fails since the foo function is unknown from > the main dictionary. Have a look at the test code in boost/libs/python/test/exec.cpp (http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/exec.cpp?revision=1.5.2.1&view=markup&pathrev=RC_1_34_0) I think that contains all you need. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From nies.stephan at googlemail.com Wed Feb 7 00:22:13 2007 From: nies.stephan at googlemail.com (stephan nies) Date: Wed, 7 Feb 2007 00:22:13 +0100 Subject: [C++-sig] can't import Boost.Python Extension OSX 10.4 In-Reply-To: <79f682bf0702011133v520496f6k9913bb1a4dbf6bd@mail.gmail.com> References: <79f682bf0702011133v520496f6k9913bb1a4dbf6bd@mail.gmail.com> Message-ID: <79f682bf0702061522n4633ab19vd4bb96d880bc58e1@mail.gmail.com> SOLVED the trick is to link the extension module using the -bundle flag on OS X but still nameing it extension.so and not extension.dylib perhaps it might be a good idea to mention this somewhere in the documentation since this might not be obvious for programmers used to Unix or Linux Thanks go to Torsten Sadowski over at macpython-sig http://mail.python.org/pipermail/pythonmac-sig/2007-February/018672.html Also i want to thank the creators of boost.python for this great Library Stephan On 2/1/07, stephan nies wrote: > Hello, > > i am porting an app from linux to osx which uses > bost.python - extension module > > Machine: 2 GHz PowerPC G5 > OS: Mac OS X 10.4.8 > Python: python-2.4.4-macosx2006-10-18.dmg > from http://pythonmac.org/packages/py24-fat/dmg/ > (this is a framework build) > Boost: 1.33.1 build from source (./configure && make) > > i am building my extension by invoking: > > g++ -dynamic myextension.cpp > -I/Library/Frameworks/Python.framework/Headers > -I/System/Library/Frameworks/GLUT.framework/Headers -I/usr/include > -I/Users/nies/src/boost_1_33_1 -c -o myextension.o > > and > > g++ -v -dynamiclib -framework Python -framework OpenGL -framework GLUT > -L/Users/nies/src/boost_1_33_1/bin/boost/libs/python/build/libboost_python.dylib/darwin/release/shared-linkable-true/ > -lboost_python-1_33_1 myextension.o -o myextension.dylib > > this compiles and when i try to import the extension in pythonw: > > Python 2.4.4 (#1, Oct 18 2006, 10:34:39) > [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> import myextension > Traceback (most recent call last): > File "", line 1, in ? > ImportError: No module named myextension > > as far as i understand this is because python searches for > .so files. when i symbolic-link myextension.so -> myextension.dylib > and than try to import: > > Python 2.4.4 (#1, Oct 18 2006, 10:34:39) > [GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> import myextension > Traceback (most recent call last): > File "", line 1, in ? > ImportError: Inappropriate file type for dynamic loading > > so what am i doing wrong here? i searched around now quite some > time but didn't find anything but the .dylib to .so renaming. I would really > appreciate some hints at this point. > > Thanks, > Stephan > From paul at mustagh.com Wed Feb 7 18:06:39 2007 From: paul at mustagh.com (Paul Guse) Date: Wed, 7 Feb 2007 10:06:39 -0700 Subject: [C++-sig] compile times Message-ID: <005a01c74ada$5d43d140$6c01a8c0@paul> I'm using boost to help with embedding python in my c++ program. I'm exposing an extensively used class (used as a base class to many types) to python, and I have some functions in that class that return a boost::python::object. However, this seems to increase the compile times of my program dramatically. So I'd like to explore ways to reduce the compile times by minimizing where boost is included. If I have a class: class CProperty { boost::python::object GetProperty (str) ; } Is there a way to not include the entire boost library in the class header? Can I minimize this? Will such a reduction help with compile times? Are there any other suggestions to help with this setup? eg) wrapping the class somehow? Any thoughts? Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From fmoreau at paraxip.com Wed Feb 7 20:49:53 2007 From: fmoreau at paraxip.com (Francis Moreau) Date: Wed, 7 Feb 2007 14:49:53 -0500 Subject: [C++-sig] Passing a C++ instance to a Python script Message-ID: <000301c74af1$2393c8d0$9c0ba8c0@FMOREAU> Thanks for the quick response. As you know the function exec_file is only available in version 1.34, what is the best way to get this version? If it is through cvs do I have to get the head or there is a stable tag somewhere? Thanks, Francis "Stefan Seefeld" wrote in message news:<45C8D2DC.8080309 at sympatico.ca>... > Francis Moreau wrote: > > Hello, > > > > I need to pass a C++ instance to a Python function, then the Python function > > can call back the C++ instance object. I found this following sample that do > > it well when the script is embedded into the C++ code within the > > PyRun_String function. I need to have something similar but with the > > PyRun_String content in a .py file. As a matter of fact, when I am trying to > > move the PyRun_String content into a .py file the line "object > > foo(main_module.attr("foo"));" fails since the foo function is unknown from > > the main dictionary. > > Have a look at the test code in boost/libs/python/test/exec.cpp > (http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/exec.cpp?revi sion=1.5.2.1&view=markup&pathrev=RC_1_34_0) > > I think that contains all you need. > > HTH, > Stefan > > -- > > ...ich hab' noch einen Koffer in Berlin... From seefeld at sympatico.ca Wed Feb 7 21:20:48 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 07 Feb 2007 15:20:48 -0500 Subject: [C++-sig] Passing a C++ instance to a Python script In-Reply-To: <000301c74af1$2393c8d0$9c0ba8c0@FMOREAU> References: <000301c74af1$2393c8d0$9c0ba8c0@FMOREAU> Message-ID: <45CA34A0.609@sympatico.ca> Francis Moreau wrote: > Thanks for the quick response. As you know the function exec_file is only > available in version 1.34, what is the best way to get this version? If it > is through cvs do I have to get the head or there is a stable tag somewhere? Yes, I think the current release branch is called 1_34_RC or so. You'll have to check. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From ryan.wingate at ge.com Thu Feb 8 01:54:51 2007 From: ryan.wingate at ge.com (Wingate, Ryan (GE Indust, Security)) Date: Wed, 7 Feb 2007 19:54:51 -0500 Subject: [C++-sig] Convert unsigned short* to Python Message-ID: <1A1D177ED885934DB6D62FFB199BFA4C01371866@CINMLVEM17.e2k.ad.ge.com> Hello, I have been working with Boost.Python for a very short time, and quickly encountered some difficulty. I need to wrap a function that returns a pointer to some image data of type unsigned short. unsigned short *PixP()const {return pixP;} From roman.yakovenko at gmail.com Thu Feb 8 08:37:46 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 8 Feb 2007 09:37:46 +0200 Subject: [C++-sig] Convert unsigned short* to Python In-Reply-To: <1A1D177ED885934DB6D62FFB199BFA4C01371866@CINMLVEM17.e2k.ad.ge.com> References: <1A1D177ED885934DB6D62FFB199BFA4C01371866@CINMLVEM17.e2k.ad.ge.com> Message-ID: <7465b6170702072337m3a65537ah75a7f77a75deb1d0@mail.gmail.com> On 2/8/07, Wingate, Ryan (GE Indust, Security) wrote: > > > Hello, > > I have been working with Boost.Python for a very short time, and quickly encountered some difficulty. > I need to wrap a function that returns a pointer to some image data of type unsigned short. > > unsigned short *PixP()const {return pixP;} Take a look on next source code( http://svn.berlios.de/wsvn/tnfox/trunk/Python/patches.cpp.h?op=file&rev=0&sc=0 ) It does exactly what you want. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From newsuser at stacom-software.de Thu Feb 8 17:32:04 2007 From: newsuser at stacom-software.de (Alexander Eisenhuth) Date: Thu, 08 Feb 2007 17:32:04 +0100 Subject: [C++-sig] Py ++ generated code contains static ... Message-ID: Hello, Py++: 0.8.5 Compiler: VC6.0 GCC-XML version 0.6.0 I tried Py++ GUI. The generated Boost.Python C++ code couldn't be compiled. Reason: (VC compile error): : error C2352: 'Math::Math_E::what' : illegal call of non-static member function : see declaration of 'what' Coresponding Codesnips: : virtual char const * what( ) const { if( bp::override func_what = this->get_override( "what" ) ) return func_what( ); else return Math::Math_E::what( ); // (wrong, not static) }
: virtual const char * what () const; At stdout there are a lot of warnings ... but they seems not be related on what. What is the reason? Thanks in advance ... Alexander From roman.yakovenko at gmail.com Thu Feb 8 20:04:25 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 8 Feb 2007 21:04:25 +0200 Subject: [C++-sig] Py ++ generated code contains static ... In-Reply-To: References: Message-ID: <7465b6170702081104t191cffafod9e100ed709ae6e5@mail.gmail.com> On 2/8/07, Alexander Eisenhuth wrote: > Hello, > > Py++: 0.8.5 > Compiler: VC6.0 > GCC-XML version 0.6.0 > > I tried Py++ GUI. The generated Boost.Python C++ code couldn't be compiled. Reason: > > (VC compile error): > : > error C2352: 'Math::Math_E::what' : illegal call of non-static member function > : see declaration of 'what' > > Coresponding Codesnips: > > : > virtual char const * what( ) const { > if( bp::override func_what = this->get_override( "what" ) ) > return func_what( ); > else > return Math::Math_E::what( ); // (wrong, not static) > } You didn't provide enough details, but I think I can make reasonable assumption. First of all "what" function belong to Math_E_wrapper class struct Math_E_wrapper : Math::Math_E, boost::python::wrapper Am I right? If so, than the line "return Math::Math_E::what( ); " should be interpreted by compiler as a call to base class member function. I think can fix the error by changing generated code to be "return this->Math::Math_E::what( );" Can you test it? Take a look on tutorials( http://www.boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.virtual_functions_with_default_implementations) The generated code is not that different. >
: > virtual const char * what () const; > At stdout there are a lot of warnings ... but they seems not be related on what. > What is the reason? I don't understand the question, can you explain what do you mean? P.S. If it is possible than switch to MSVC 7.1 compiler. It is much better. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From newsuser at stacom-software.de Fri Feb 9 10:05:09 2007 From: newsuser at stacom-software.de (Alexander Eisenhuth) Date: Fri, 09 Feb 2007 10:05:09 +0100 Subject: [C++-sig] Py ++ generated code contains static ... In-Reply-To: <7465b6170702081104t191cffafod9e100ed709ae6e5@mail.gmail.com> References: <7465b6170702081104t191cffafod9e100ed709ae6e5@mail.gmail.com> Message-ID: Roman Yakovenko schrieb: ... > > I tried Py++ GUI. The generated Boost.Python C++ code couldn't be > compiled. Reason: > > > > (VC compile error): > > : > > error C2352: 'Math::Math_E::what' : illegal call of non-static member > function > > : see declaration of 'what' > > > > Coresponding Codesnips: > > > > : > > virtual char const * what( ) const { > > if( bp::override func_what = this->get_override( "what" ) ) > > return func_what( ); > > else > > return Math::Math_E::what( ); // (wrong, not static) > > } > > You didn't provide enough details, but I think I can make reasonable > assumption. > > First of all "what" function belong to Math_E_wrapper class > > struct Math_E_wrapper : Math::Math_E, boost::python::wrapper > > Am I right? Yes you're right > If so, than the line "return Math::Math_E::what( ); " should be > interpreted by compiler > as a call to base class member function. I think can fix the error by > changing generated > code to be "return this->Math::Math_E::what( );" You ment this->Math_E::what( ); > > Can you test it? I've tested "this->Math_E::what( )" and it compiled ! Thanks a lot for that hint. > P.S. If it is possible than switch to MSVC 7.1 compiler. It is much better. I know, but I cannot switch at the moment. At stdout there are a lot of warnings like: WARNING: void Math::XYZ_TC::GetPolar(double & pol_, double & pol_a, double & mer) const [member function] > warning W1009: The function takes as argument (name=mer, pos=2) > non-const reference to Python immutable type - function could not be > called from Python. Take a look on "Function Transformation" > functionality and define the transformation. The warning say that the methode couldn't be called from python because: - argument mer is a "in/out" argument The solution according to Function Transformation": 1) Write wrapper code 2) Use py++ on the python side Right? Alexander From roman.yakovenko at gmail.com Fri Feb 9 11:33:55 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 9 Feb 2007 12:33:55 +0200 Subject: [C++-sig] Py ++ generated code contains static ... In-Reply-To: References: <7465b6170702081104t191cffafod9e100ed709ae6e5@mail.gmail.com> Message-ID: <7465b6170702090233y5390bd4cy64b941753a45055c@mail.gmail.com> On 2/9/07, Alexander Eisenhuth wrote: > You ment this->Math_E::what( ); > > > > > Can you test it? > > I've tested "this->Math_E::what( )" and it compiled ! > Thanks a lot for that hint. Thanks, I committed the fix to SVN( revision 897 ) > At stdout there are a lot of warnings like: > > WARNING: void Math::XYZ_TC::GetPolar(double & pol_, double & > pol_a, double & mer) const [member function] > > warning W1009: The function takes as argument (name=mer, pos=2) > > non-const reference to Python immutable type - function could not be > > called from Python. Take a look on "Function Transformation" > > functionality and define the transformation. > > > The warning say that the methode couldn't be called from python because: > - argument mer is a "in/out" argument > > The solution according to Function Transformation": > > 1) Write wrapper code > 2) Use py++ on the python side > > Right? No, ask Py++ to create wrapper code, but for this you will have to switch to API. The GUI has "generate Py++ code" button. This will generate skeleton for your project. Than you have to add next code: from pyplusplus import function_transformers as FT mb = module_builder_t( ... ) GetPolar = mb.member_function( 'GetPolar' ) #search API explained here: http://language-binding.net/pygccxml/query_interface.html GetPolar.add_transformation( FT.output( 'pol_' ), FT.output( 'pol_a' ), FT.output( 'mer' ) ) That's all. Py++ will generate function wrapper, which will return tuple( pol_ value, pol_a value, mer value ). Function Transformers docs: http://language-binding.net/pyplusplus/documentation/functions/transformation/built_in/output.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From pk at cs.tut.fi Fri Feb 9 12:15:33 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Fri, 09 Feb 2007 13:15:33 +0200 Subject: [C++-sig] Constructors taking raw pointers Message-ID: <45CC57D5.30909@cs.tut.fi> Sorry if this a FAQ. I'm wrapping a C++ library where raw pointers are passed around. I've read the relevant FAQ entry about object ownership at , and I've got things working with transfer of ownership in function calls. However, I'm unsure how to extend that to constructors. How would one expose a constructor that takes a raw pointer and grabs ownership of the pointer? Thanks, -- Pertti From luis.f.teixeira at inescporto.pt Fri Feb 9 12:49:24 2007 From: luis.f.teixeira at inescporto.pt (Luis F. Teixeira) Date: Fri, 09 Feb 2007 11:49:24 +0000 Subject: [C++-sig] boost::python compile error with custom smart pointer Message-ID: <45CC5FC4.2020709@inescporto.pt> Hi all, I'm using boost python in a project and everything was compiling and running ok in Windows but when I tried to compile it under Linux a strange compile error appeared. I'm using a custom smart pointer but also have to define a class wrapper. Both register_ptr_to_python and implicitly_convertible do the c++/python conversion. In Linux: /usr/include/boost/python/object/pointer_holder.hpp:125: error: no matching function for call to get_pointer(mrs_ptr&) /usr/include/boost/python/object/pointer_holder.hpp:130: error: no matching function for call to get_pointer(mrs_ptr&) Note that get_pointer is defined for mrs_ptr. If I comment out the register_ptr_to_python line it compiles fine but when the script is executed the "No to_python (by-value) converter found" error pops up, of course. I'm attaching a small test that demonstrates my problem. It compiles and works fine with boost 1.33.1 and MSVC2005 under Windows but doesn't compile with the same version of boost and g++ 4.1.2 (Ubuntu Edgy). What am I doing wrong here? Any suggestions? Thank you, Luis FT -------------- next part -------------- A non-text attachment was scrubbed... Name: test.py Type: text/x-python Size: 96 bytes Desc: not available URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test-boost.cpp URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: mrs_ptr.h URL: From e.tadeu at gmail.com Fri Feb 9 16:11:46 2007 From: e.tadeu at gmail.com (Edson Tadeu) Date: Fri, 9 Feb 2007 13:11:46 -0200 Subject: [C++-sig] Bug when exporting function overloaded on base and derived classes Message-ID: Hi, I've found a bug where Boost.Python calls the wrong function overload. Here is a small unit test: ===== The C++ module "_test.cpp": ===== #include #include class Base { }; class Derived : public Base { }; std::string f(Base& b) { return "Base"; } std::string f(Derived& d) { return "Derived"; } BOOST_PYTHON_MODULE( _test ) { using namespace boost::python; class_("Base"); class_ >("Derived"); def("f", static_cast(&f)); def("f", static_cast(&f)); } ===== The small test in python: ===== >>> from _test import * >>> f(Base()) 'Base' >>> f(Derived()) 'Base' ===== Interestingly enough, if the function overloads are exported in the inverse order, it actually works, i.e., if using this code: ===== BOOST_PYTHON_MODULE( _test ) { using namespace boost::python; class_("Base"); class_ >("Derived"); def("f", static_cast(&f)); def("f", static_cast(&f)); } ===== I do not know very well how does the boost.python registry works, but it seems that it is selecting the first match instead of testing all matches and selecting the "best one". -------------- next part -------------- An HTML attachment was scrubbed... URL: From paul at mustagh.com Fri Feb 9 19:41:10 2007 From: paul at mustagh.com (Paul Guse) Date: Fri, 9 Feb 2007 11:41:10 -0700 Subject: [C++-sig] adding functions to module Message-ID: <037801c74c79$df8249c0$6c01a8c0@paul> I'm using boost.python to embed python in my c++ program. I have defined a module (foo). In my c++ code, before I run a script, I am adding a variable to the foo namespace using: object foo_mod (handle<>borrowed (PyImport_AddModule ("foo")))); object foo_dict = foo_mod.attr ("__dict__") ; foo_dict['_root'] = object (MyIntrusivePtr (root_object)) ; This adds the correct variable to the foo namespace, but I also want to add a function to retrieve the variable. For example: def foo.root (): return foo._root so that I can use: r = foo.root() in my scripts. What is the best way to add a function to an existing namespace? I have seen some info on PyFunction_New but am not sure how to best use that. Also, can I make the _root object in foo private and only accessible through a defined function? Any thoughts would be greatly appreciated. Thanks for your time! Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: From tkirke at gmail.com Sat Feb 10 00:30:22 2007 From: tkirke at gmail.com (Tony Kirke) Date: Fri, 9 Feb 2007 15:30:22 -0800 Subject: [C++-sig] boost python build/linking/distribution questions Message-ID: <4dcfdcab0702091530j217c24edhd235ac596065640a@mail.gmail.com> Hi, Has anyone automated the process after building a python package using boost/bjam so that either .rpm or .deb distribution packages can be created? (I know there is documentation available but I'm looking for some shortcuts/examples). One issue is the libboost_python.so file. Does it need to be packaged or declared as a dependency. Can this issue be avoided by building with static? Thanks Tony -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Sat Feb 10 02:01:43 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Fri, 09 Feb 2007 20:01:43 -0500 Subject: [C++-sig] boost python build/linking/distribution questions In-Reply-To: <4dcfdcab0702091530j217c24edhd235ac596065640a@mail.gmail.com> References: <4dcfdcab0702091530j217c24edhd235ac596065640a@mail.gmail.com> Message-ID: <45CD1977.1060807@sympatico.ca> Tony Kirke wrote: > Hi, > Has anyone automated the process after building a python package using > boost/bjam so that either .rpm or .deb distribution packages can be > created? (I know there is documentation available but I'm looking for > some shortcuts/examples). > One issue is the libboost_python.so file. Does it need to be packaged or > declared as a dependency. Can this issue be avoided by building with > static? I'm not exactly sure what your question is about. When building an rpm package, you typically start by writing an rpm spec file, containing (among many other bits) explicit dependencies ('Requires:'). Using this you can mention any boost rpm package you depend on. However, rpmbuild itself will figure out what runtime dependencies your compiled application / library has (such as DSOs), so any boost.python dependency should be resolved automatically. None of this involves the build system of boost (or boost.python) itself. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From lucio at image-engine.com Sat Feb 10 01:45:05 2007 From: lucio at image-engine.com (Lucio Moser) Date: Fri, 09 Feb 2007 16:45:05 -0800 Subject: [C++-sig] problems downcasting intrusive_ptr. Message-ID: <45CD1591.9040408@image-engine.com> Hello, I created a factory function that returns an intrusive pointer for a derived class. The returned pointer is for the base class, but boost.python apparently downcast it correctly. I can call methods from the derived class with no problem. But then, if I pass that object to any function that requires a derived pointer it will fail. If I use shared_ptr instead. It works fine. Any ideas? Thank you! PS: I'm using boost 1.33.1. python test case: ============ Object b can't be given as a parameter for test2() function!!! Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> a = Derived() >>> b = factory() >>> b >>> a.test1() 0 >>> b.test1() 0 >>> a.test2(a) 1 >>> b.test2(a) 1 >>> b.test2(b) Traceback (most recent call last): File "", line 1, in Boost.Python.ArgumentError: Python argument types in Derived.test2(Derived, Derived) did not match C++ signature: test2(Derived {lvalue}, boost::intrusive_ptr) >>> a.test2(b) Traceback (most recent call last): File "", line 1, in Boost.Python.ArgumentError: Python argument types in Derived.test2(Derived, Derived) did not match C++ signature: test2(Derived {lvalue}, boost::intrusive_ptr) >>> simpleTest.cpp: =========== #include class Base { public : Base ( ) : m_numRefs( 0 ) { } // Functions used for intrusive_ptr reference counting. /// Add a reference to the current object void addRef() const { m_numRefs ++; } /// Remove a reference from the current object void removeRef() const { m_numRefs --; if ( m_numRefs == 0 ) { delete this; } } protected : mutable unsigned int m_numRefs; virtual ~Base() { } }; class Derived; #ifdef USE_SHARED_PTR #include "boost/shared_ptr.hpp" typedef boost::shared_ptr BasePtr; typedef boost::shared_ptr DerivedPtr; #else // USE_SHARED_PTR #include "boost/intrusive_ptr.hpp" typedef boost::intrusive_ptr BasePtr; typedef boost::intrusive_ptr DerivedPtr; /// Functions required to allow use of Base with boost::intrusive_ptr inline void intrusive_ptr_add_ref( const Base *r ) { r->addRef(); } inline void intrusive_ptr_release( const Base *r ) { r->removeRef(); } #endif // USE_SHARED_PTR class Derived : public Base { public : Derived( ) : Base ( ), m_data( 0 ) { } int test1() { return this->m_data; } int test2( DerivedPtr d ) { return (this->m_data == d->m_data); } protected : int m_data; }; BasePtr factory( void ) { return BasePtr( new Derived() ); } using namespace boost::python; BOOST_PYTHON_MODULE(simpleTest) { class_< Base, boost::noncopyable, BasePtr > BaseClass("Base", no_init); class_< Derived, boost::noncopyable, DerivedPtr, bases< Base > > DerivedClass( "Derived" ); DerivedClass.def( "test1", &Derived::test1 ); DerivedClass.def( "test2", &Derived::test2 ); def("factory", &factory); implicitly_convertible(); } From tkirke at gmail.com Sat Feb 10 02:25:04 2007 From: tkirke at gmail.com (Tony Kirke) Date: Fri, 9 Feb 2007 17:25:04 -0800 Subject: [C++-sig] boost python build/linking/distribution questions In-Reply-To: <45CD1977.1060807@sympatico.ca> References: <4dcfdcab0702091530j217c24edhd235ac596065640a@mail.gmail.com> <45CD1977.1060807@sympatico.ca> Message-ID: <4dcfdcab0702091725o48d9c635k9900179388543bdb@mail.gmail.com> On 2/9/07, Stefan Seefeld wrote: > > Tony Kirke wrote: > > Hi, > > Has anyone automated the process after building a python package using > > boost/bjam so that either .rpm or .deb distribution packages can be > > created? (I know there is documentation available but I'm looking for > > some shortcuts/examples). > > One issue is the libboost_python.so file. Does it need to be packaged or > > declared as a dependency. Can this issue be avoided by building with > > static? > > I'm not exactly sure what your question is about. > When building an rpm package, you typically start by writing an rpm spec > file, containing (among many other bits) explicit dependencies > ('Requires:'). > Using this you can mention any boost rpm package you depend on. > > However, rpmbuild itself will figure out what runtime dependencies your > compiled application / library has (such as DSOs), so any boost.python > dependency should be resolved automatically. > > None of this involves the build system of boost (or boost.python) itself. > > HTH, > Stefan > > -- > > ...ich hab' noch einen Koffer in Berlin... > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig Thanks for replying. The first question was not boost/python specific and I was looking for examples from someone who may have done this for a boost related package. it wasn't clear to me if extra steps are necessary when using boost/bjam vs the typical makefile way of creating packages for distribution - which is what all of the examples I've seen use. What is boost specific, is whether a libboost_python.so file is always required or whether whatever of it that's needed can be contained in the .pyd/.dll files through a linker/compiler flag. -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Sat Feb 10 02:35:20 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Fri, 09 Feb 2007 20:35:20 -0500 Subject: [C++-sig] boost python build/linking/distribution questions In-Reply-To: <4dcfdcab0702091725o48d9c635k9900179388543bdb@mail.gmail.com> References: <4dcfdcab0702091530j217c24edhd235ac596065640a@mail.gmail.com> <45CD1977.1060807@sympatico.ca> <4dcfdcab0702091725o48d9c635k9900179388543bdb@mail.gmail.com> Message-ID: <45CD2158.6000209@sympatico.ca> Tony Kirke wrote: > Thanks for replying. The first question was not boost/python specific > and I was looking for examples from someone who may have done this for a > boost related package. it wasn't clear to me if extra steps are > necessary when using boost/bjam vs the typical makefile way of creating > packages for distribution - which is what all of the examples I've seen use. Building an rpm package does not really rely on any particular build tool, be it make or bjam. You merely specify a shell script chunk used to 'install' your code into a fake root, and rpmbuild will collect all the thusly installed files into the package. > What is boost specific, is whether a libboost_python.so file is always > required or whether whatever of it that's needed can be contained in the > .pyd/.dll files through a linker/compiler flag. I'm not sure. As I said, rpmbuild will figure out what libraries your files depend on (using ldd, I guess), though these may or may not originate from rpm packages, so rpmbuild may not be able to resolve those dependencies to required rpm packages. It's probably always best if you can explicitely specify package dependencies using the 'Required' keyword. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From tkirke at gmail.com Sat Feb 10 03:32:32 2007 From: tkirke at gmail.com (Tony Kirke) Date: Fri, 9 Feb 2007 18:32:32 -0800 Subject: [C++-sig] boost python build/linking/distribution questions In-Reply-To: <45CD2158.6000209@sympatico.ca> References: <4dcfdcab0702091530j217c24edhd235ac596065640a@mail.gmail.com> <45CD1977.1060807@sympatico.ca> <4dcfdcab0702091725o48d9c635k9900179388543bdb@mail.gmail.com> <45CD2158.6000209@sympatico.ca> Message-ID: <4dcfdcab0702091832l1af0904aq8f4baf726ef96426@mail.gmail.com> On 2/9/07, Stefan Seefeld wrote: > > Tony Kirke wrote: > > > Thanks for replying. The first question was not boost/python specific > > and I was looking for examples from someone who may have done this for a > > boost related package. it wasn't clear to me if extra steps are > > necessary when using boost/bjam vs the typical makefile way of creating > > packages for distribution - which is what all of the examples I've seen > use. > > Building an rpm package does not really rely on any particular build tool, > be it make or bjam. You merely specify a shell script chunk used to > 'install' > your code into a fake root, and rpmbuild will collect all the thusly > installed > files into the package. > > > What is boost specific, is whether a libboost_python.so file is always > > required or whether whatever of it that's needed can be contained in the > > .pyd/.dll files through a linker/compiler flag. > > I'm not sure. As I said, rpmbuild will figure out what libraries your > files depend on (using ldd, I guess), though these may or may not > originate > from rpm packages, so rpmbuild may not be able to resolve those > dependencies > to required rpm packages. It's probably always best if you can explicitely > specify package dependencies using the 'Required' keyword. > > > Well since libboost_python.so is built locally it would not be resolved. That is why i was hoping that whether a compile option would remove the need for the libboost_python.so shared object. This would do away with the need to change the LD_LIBRARY_PATH in some cases. -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Sat Feb 10 03:45:33 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Fri, 09 Feb 2007 21:45:33 -0500 Subject: [C++-sig] boost python build/linking/distribution questions In-Reply-To: <4dcfdcab0702091832l1af0904aq8f4baf726ef96426@mail.gmail.com> References: <4dcfdcab0702091530j217c24edhd235ac596065640a@mail.gmail.com> <45CD1977.1060807@sympatico.ca> <4dcfdcab0702091725o48d9c635k9900179388543bdb@mail.gmail.com> <45CD2158.6000209@sympatico.ca> <4dcfdcab0702091832l1af0904aq8f4baf726ef96426@mail.gmail.com> Message-ID: <45CD31CD.3070801@sympatico.ca> Tony Kirke wrote: > Well since libboost_python.so is built locally it would not be resolved. > That is why i was hoping that whether a compile option would remove the > need for the libboost_python.so shared object. This would do away with > the need to change the LD_LIBRARY_PATH in some cases. If you build a package that requires boost.python, you need to make sure the installer of your package can figure out what package it takes to get boost.python installed. To validate, you should definitely use the same version (i.e. package) of boost.python that you expect your package's users to use. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From roman.yakovenko at gmail.com Sat Feb 10 19:45:12 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 10 Feb 2007 20:45:12 +0200 Subject: [C++-sig] Constructors taking raw pointers In-Reply-To: <45CC57D5.30909@cs.tut.fi> References: <45CC57D5.30909@cs.tut.fi> Message-ID: <7465b6170702101045p1d59fb85v3949af19d35b8d4e@mail.gmail.com> On 2/9/07, Pertti Kellom?ki wrote: > Sorry if this a FAQ. I'm wrapping a C++ library where > raw pointers are passed around. I've read the relevant > FAQ entry about object ownership at > , > and I've got things working with transfer of ownership in > function calls. > > However, I'm unsure how to extend that to constructors. How > would one expose a constructor that takes a raw pointer and > grabs ownership of the pointer? You can use make_constructor functionality docs: http://www.boost.org/libs/python/doc/v2/make_function.html unit tests: http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/injected.cpp?view=markup -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Sat Feb 10 19:49:56 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 10 Feb 2007 20:49:56 +0200 Subject: [C++-sig] boost::python compile error with custom smart pointer In-Reply-To: <45CC5FC4.2020709@inescporto.pt> References: <45CC5FC4.2020709@inescporto.pt> Message-ID: <7465b6170702101049g66efd298k617a517595c6f9c6@mail.gmail.com> On 2/9/07, Luis F. Teixeira wrote: > Hi all, > I'm using boost python in a project and everything was compiling and > running ok in Windows but when I tried to compile it under Linux a > strange compile error appeared. I'm using a custom smart pointer but > also have to define a class wrapper. Both register_ptr_to_python and > implicitly_convertible do the c++/python conversion. > > In Linux: > /usr/include/boost/python/object/pointer_holder.hpp:125: error: no > matching function for call to get_pointer(mrs_ptr&) > /usr/include/boost/python/object/pointer_holder.hpp:130: error: no > matching function for call to get_pointer(mrs_ptr&) Yes. I think you will fund useful next web page: http://language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smart_ptrs.html The solution to your problem is here: http://python-ogre.python-hosting.com/file/trunk/python-ogre/shared_ptr/py_shared_ptr.h Python-Ogre is developed on Windows and Linux. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Sat Feb 10 19:54:15 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 10 Feb 2007 20:54:15 +0200 Subject: [C++-sig] Bug when exporting function overloaded on base and derived classes In-Reply-To: References: Message-ID: <7465b6170702101054l398c4f9agb55f1007239a500b@mail.gmail.com> On 2/9/07, Edson Tadeu wrote: > Hi, > I've found a bug where Boost.Python calls the wrong function overload. Here > is a small unit test: > > ===== > The C++ module "_test.cpp": > ===== > > #include > #include > > class Base { }; > > class Derived : public Base { }; > > std::string f(Base& b) { > return "Base"; > } > > std::string f(Derived& d) { > return "Derived"; > } > > BOOST_PYTHON_MODULE( _test ) > { > using namespace boost::python; > > class_("Base"); > class_ >("Derived"); > > def("f", static_cast(&f)); > def("f", static_cast(&f)); > } > > > ===== > The small test in python: > ===== > > >>> from _test import * > >>> f(Base()) > 'Base' > >>> f(Derived()) > 'Base' > > > ===== > > Interestingly enough, if the function overloads are exported in the inverse > order, it actually works, i.e., if using this code: > > ===== > BOOST_PYTHON_MODULE( _test ) > { > using namespace boost::python; > > class_("Base"); > class_ >("Derived"); > > def("f", static_cast(&f)); > def("f", static_cast(&f)); > } > ===== > > I do not know very well how does the boost.python registry works, but it > seems that it is selecting the first match instead of testing all matches > and selecting the "best one". There are cases where it is impossible to select the best match: void do_smth( char ) void do_smth( const char* ) Any way this pitfall explained here: http://language-binding.net/pyplusplus/documentation/functions/registration_order.html#registration-order-pitfalls -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From ndbecker2 at gmail.com Sat Feb 10 20:44:53 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Sat, 10 Feb 2007 14:44:53 -0500 Subject: [C++-sig] expose python iterators to c++? Message-ID: Has anyone looked into exposing python iterators to c++? It would be very nice if a python object implementing the python iterator protocol was able to be used as a boost::range. Then c++ algorithms conforming to boost::range requirements could accept a python object conforming to the python iterator protocol. From roman.yakovenko at gmail.com Sat Feb 10 22:35:01 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sat, 10 Feb 2007 23:35:01 +0200 Subject: [C++-sig] problems downcasting intrusive_ptr. In-Reply-To: <45CD1591.9040408@image-engine.com> References: <45CD1591.9040408@image-engine.com> Message-ID: <7465b6170702101335p22a87175h26e66cba106f255c@mail.gmail.com> On 2/10/07, Lucio Moser wrote: > Hello, > > I created a factory function that returns an intrusive pointer for a > derived class. > The returned pointer is for the base class, but boost.python apparently > downcast it correctly. > I can call methods from the derived class with no problem. > But then, if I pass that object to any function that requires a derived > pointer it will fail. > > If I use shared_ptr instead. It works fine. > > Any ideas? I could be wrong! Take a look on http://boost.cvs.sourceforge.net/boost/boost/boost/python/converter/shared_ptr_from_python.hpp?view=markup file. I think this custom converter is exactly the reason why you can do this with shared_ptr and cannot do this with other smart pointer. Even in C++, in order to do down casting you should use special API ( http://www.boost.org/libs/smart_ptr/intrusive_ptr.html#dynamic_pointer_cast ) Of course, Boost.Python is not aware of this API and you should help it a little. Introducing your own intrusive_ptr_from_python class should help. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From kelly.burkhart at gmail.com Sun Feb 11 03:03:48 2007 From: kelly.burkhart at gmail.com (Kelly Burkhart) Date: Sat, 10 Feb 2007 20:03:48 -0600 Subject: [C++-sig] map_indexing_suite object map Message-ID: Is it possible to create a map of arbitrary python objects using the map indexing suite? I was hoping the following would work: class_ >("ObMap") .def(map_indexing_suite >()) ; However it results in the following: >>> from tst import * >>> om = ObMap() >>> om['1'] = 1 >>> v = om['1'] Traceback (most recent call last): File "", line 1, in TypeError: No Python class registered for C++ class boost::python::api::object >>> Is there any way to use map indexing suite in this way? Thanks, -K From roman.yakovenko at gmail.com Sun Feb 11 08:25:54 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 11 Feb 2007 09:25:54 +0200 Subject: [C++-sig] map_indexing_suite object map In-Reply-To: References: Message-ID: <7465b6170702102325n70c701ddh7ac5d08c3c9679cd@mail.gmail.com> On 2/11/07, Kelly Burkhart wrote: > Is it possible to create a map of arbitrary python objects using the > map indexing suite? I was hoping the following would work: > > class_ >("ObMap") > .def(map_indexing_suite >()) > ; > > However it results in the following: > > >>> from tst import * > >>> om = ObMap() > >>> om['1'] = 1 > >>> v = om['1'] > Traceback (most recent call last): > File "", line 1, in > TypeError: No Python class registered for C++ class boost::python::api::object > >>> > > Is there any way to use map indexing suite in this way? Take a look on NoProxy template argument. I think it could help http://boost.org/libs/python/doc/v2/indexing.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From pk at cs.tut.fi Mon Feb 12 10:20:52 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Mon, 12 Feb 2007 11:20:52 +0200 Subject: [C++-sig] Constructors taking raw pointers In-Reply-To: <7465b6170702101045p1d59fb85v3949af19d35b8d4e@mail.gmail.com> References: <45CC57D5.30909@cs.tut.fi> <7465b6170702101045p1d59fb85v3949af19d35b8d4e@mail.gmail.com> Message-ID: <45D03174.7070305@cs.tut.fi> Roman Yakovenko kirjoitti: > You can use make_constructor functionality Thanks. -- Pertti From paul at mustagh.com Mon Feb 12 23:19:52 2007 From: paul at mustagh.com (Paul Guse) Date: Mon, 12 Feb 2007 15:19:52 -0700 Subject: [C++-sig] Memory issues Message-ID: <062201c74ef3$ed136840$6c01a8c0@paul> Hello. I have a few boost::python issues I need help with . Firstly, I'm getting some memory leaks by just including the boost libraries. (Dynamically linked dll, VS2005. Using boost to embed python in c++) >From what I gather this is still an outstanding issue with no, as of yet, solution? Is that correct? Second, this is also causing some issues as I need to free the resources allocated during the running of scripts. Specifically, I'm using the intrusive_ptr to wrap my own object's reference counting. When these objects are referenced in a python script the reference count is incremented, but not decremented when the script ends. As expected, this is causing some issues. Is there a way to clean up the variables allocated in a namespace? Or to effectively clear the main namespace? Thanks. Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucio at image-engine.com Mon Feb 12 23:50:16 2007 From: lucio at image-engine.com (Lucio Moser) Date: Mon, 12 Feb 2007 14:50:16 -0800 Subject: [C++-sig] problems downcasting intrusive_ptr. In-Reply-To: <7465b6170702101335p22a87175h26e66cba106f255c@mail.gmail.com> References: <45CD1591.9040408@image-engine.com> <7465b6170702101335p22a87175h26e66cba106f255c@mail.gmail.com> Message-ID: <45D0EF28.6070900@image-engine.com> Thanks a lot Roman! It solved the problem. Now I face another one. If I derive a python class "Derived2" from the "Derived" C++ class and send to "upcast" function below then I receive a Derive object and not Derive2. I imagined that if I created an intrusive_ptr version for shared_ptr_arg_to_python it would solve the problem. But it didn't. Do you have another tip on how to downcast for python-derived classes too? BasePtr upcast(BasePtr data) { return data; } Roman Yakovenko wrote: > On 2/10/07, Lucio Moser wrote: > >> Hello, >> >> I created a factory function that returns an intrusive pointer for a >> derived class. >> The returned pointer is for the base class, but boost.python apparently >> downcast it correctly. >> I can call methods from the derived class with no problem. >> But then, if I pass that object to any function that requires a derived >> pointer it will fail. >> >> If I use shared_ptr instead. It works fine. >> >> Any ideas? >> > > I could be wrong! > > Take a look on http://boost.cvs.sourceforge.net/boost/boost/boost/python/converter/shared_ptr_from_python.hpp?view=markup > file. I think this custom converter is exactly the reason why you can do this > with shared_ptr and cannot do this with other smart pointer. > > Even in C++, in order to do down casting you should use special API > ( http://www.boost.org/libs/smart_ptr/intrusive_ptr.html#dynamic_pointer_cast ) > Of course, Boost.Python is not aware of this API and you should help > it a little. > > Introducing your own intrusive_ptr_from_python class should help. > > From roman.yakovenko at gmail.com Tue Feb 13 10:02:58 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 13 Feb 2007 11:02:58 +0200 Subject: [C++-sig] problems downcasting intrusive_ptr. In-Reply-To: <45D0EF28.6070900@image-engine.com> References: <45CD1591.9040408@image-engine.com> <7465b6170702101335p22a87175h26e66cba106f255c@mail.gmail.com> <45D0EF28.6070900@image-engine.com> Message-ID: <7465b6170702130102x6198bfa1r2985d237b584574a@mail.gmail.com> On 2/13/07, Lucio Moser wrote: > Thanks a lot Roman! It solved the problem. Please post your solution. Thus it will be available to other people too. > Now I face another one. If I derive a python class "Derived2" from the > "Derived" C++ class and send to "upcast" function below then I receive a > Derive object and not Derive2. I imagined that if I created an > intrusive_ptr version for shared_ptr_arg_to_python it would solve the > problem. But it didn't. Do you have another tip on how to downcast for > python-derived classes too? I don't completely understand you. You have class defined in C++ and another one defined in Python, derived from the first one, right? Now you want to downcast to the class defined in Python? If so you cannot do this. You can get reference to relevant Python object and than using Boost.Python to get access to desired functionality. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From lucio at image-engine.com Tue Feb 13 19:38:25 2007 From: lucio at image-engine.com (Lucio Moser) Date: Tue, 13 Feb 2007 10:38:25 -0800 Subject: [C++-sig] problems downcasting intrusive_ptr. In-Reply-To: <7465b6170702130102x6198bfa1r2985d237b584574a@mail.gmail.com> References: <45CD1591.9040408@image-engine.com> <7465b6170702101335p22a87175h26e66cba106f255c@mail.gmail.com> <45D0EF28.6070900@image-engine.com> <7465b6170702130102x6198bfa1r2985d237b584574a@mail.gmail.com> Message-ID: <45D205A1.9000401@image-engine.com> Yes, that's what I wanted. I have a core C++ library that works using intrusive_ptr everywhere. And I'm binding that to Python. The downcasting to a Python class works if I compile my test case using shared_ptr. There should be a way to do it with intrusive_ptr. I appreciate your help. The code that solves the previous problem is listed below. It also shows the new problem. To compile it for shared_ptr, just define USE_SHARED_PTR. The functions upcast and store/retrieve will work correctly for shared_ptr and not for intrusive_ptr (shown below). python test code using shared_ptr: ======================== Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> >>> class Derived2(Derived): ... pass ... >>> a = Derived2() >>> a <__main__.Derived2 object at 0xb7f3743c> >>> store(a) >>> b = retrieve() >>> b <__main__.Derived2 object at 0xb7f3743c> >>> >>> upcast(a) <__main__.Derived2 object at 0xb7f3743c> >>> python test code using intrusive_ptr: ========================== Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> >>> class Derived2(Derived): ... pass ... >>> a = Derived2() >>> a <__main__.Derived2 object at 0xb7edea7c> >>> store(a) >>> b = retrieve() >>> b >>> >>> upcast(a) >>> simpleTest.cpp: =========== #include #include "register_intrusive_ptr_from_python.hpp" class Base { public : Base ( ) : m_numRefs( 0 ) { } /// Add a reference to the current object void addRef() const { m_numRefs ++; } /// Remove a reference from the current object void removeRef() const { m_numRefs --; if ( m_numRefs == 0 ) { delete this; } } protected : mutable unsigned int m_numRefs; virtual ~Base() { } }; class Derived; #ifdef USE_SHARED_PTR #include "boost/shared_ptr.hpp" typedef boost::shared_ptr BasePtr; typedef boost::shared_ptr DerivedPtr; #else // USE_SHARED_PTR #include "boost/intrusive_ptr.hpp" typedef boost::intrusive_ptr BasePtr; typedef boost::intrusive_ptr DerivedPtr; /// Functions required to allow use of Base with boost::intrusive_ptr inline void intrusive_ptr_add_ref( const Base *r ) { r->addRef(); } inline void intrusive_ptr_release( const Base *r ) { r->removeRef(); } #endif // USE_SHARED_PTR class Derived : public Base { public : Derived( ) : Base ( ), m_data( 0 ) { } int test1() { return this->m_data; } int test2( DerivedPtr d ) { return (this->m_data == d->m_data); } protected : int m_data; }; BasePtr factory( void ) { return BasePtr( new Derived() ); } BasePtr baseUpcast( BasePtr base ) { return base; } struct GlobalsTest { static BasePtr g_object ; static BasePtr retrieve() { return g_object; } static void store( const BasePtr &o) { g_object = o; } }; BasePtr GlobalsTest::g_object; using namespace boost::python; BOOST_PYTHON_MODULE(simpleTest) { typedef class_< Base, boost::noncopyable, BasePtr > BaseClass; BaseClass baseClass("Base", no_init); #ifndef USE_SHARED_PTR boostPatch::register_intrusive_ptr_from_python_and_casts( (Base *)0, BaseClass::metadata::bases() ); #endif typedef class_< Derived, boost::noncopyable, DerivedPtr, bases< Base > > DerivedClass; DerivedClass derivedClass( "Derived" ); #ifndef USE_SHARED_PTR boostPatch::register_intrusive_ptr_from_python_and_casts( (Derived *)0, DerivedClass::metadata::bases() ); #endif derivedClass.def( "test1", &Derived::test1 ); derivedClass.def( "test2", &Derived::test2 ); def("factory", &factory); def("upcast", &baseUpcast); def("store", & GlobalsTest::store ); def("retrieve", & GlobalsTest::retrieve ); implicitly_convertible(); } register_intrusive_ptr_from_python.hpp ============================= #ifndef REGISTER_INTRUSIVE_PTR_FROM_PYTHON_HPP # define REGISTER_INTRUSIVE_PTR_FROM_PYTHON_HPP # include #include "intrusive_ptr_from_python.hpp" namespace boostPatch { // This function was based on register_shared_ptr_from_python_and_casts() from class_metadata.hpp. // // Preamble of register_class. Also used for callback classes, which // need some registration of their own. // template inline void register_intrusive_ptr_from_python_and_casts(T*, Bases) { using namespace boost::python::objects; // Constructor performs registration python::detail::force_instantiate(intrusive_ptr_from_python()); // // register all up/downcasts here. We're using the alternate // interface to mpl::for_each to avoid an MSVC 6 bug. // register_dynamic_id(); mpl::for_each(register_base_of(), (Bases*)0, (boost::add_pointer*)0); } } // namespace boostPatch #endif // INTRUSIVE_PTR_FROM_PYTHON_HPP intrusive_ptr_from_python.hpp ======================= // Based on boost header: shared_ptr_from_python.hpp. #ifndef INTRUSIVE_PTR_FROM_PYTHON_HPP # define INTRUSIVE_PTR_FROM_PYTHON_HPP # include # include # include # include # include # include namespace boostPatch { using namespace boost; using namespace boost::python; using namespace boost::python::converter; template struct intrusive_ptr_from_python { intrusive_ptr_from_python() { converter::registry::insert(&convertible, &construct, type_id >()); } private: static void* convertible(PyObject* p) { if (p == Py_None) return p; return converter::get_lvalue_from_python(p, registered::converters); } static void construct(PyObject* source, rvalue_from_python_stage1_data* data) { void* const storage = ((converter::rvalue_from_python_storage >*)data)->storage.bytes; // Deal with the "None" case. if (data->convertible == source) new (storage) intrusive_ptr(); else new (storage) intrusive_ptr( static_cast(data->convertible) ); data->convertible = storage; } }; } // namespace boostPatch #endif // INTRUSIVE_PTR_FROM_PYTHON_HPP Roman Yakovenko wrote: > On 2/13/07, Lucio Moser wrote: > >> Thanks a lot Roman! It solved the problem. >> > > Please post your solution. Thus it will be available to other people too. > > >> Now I face another one. If I derive a python class "Derived2" from the >> "Derived" C++ class and send to "upcast" function below then I receive a >> Derive object and not Derive2. I imagined that if I created an >> intrusive_ptr version for shared_ptr_arg_to_python it would solve the >> problem. But it didn't. Do you have another tip on how to downcast for >> python-derived classes too? >> > > I don't completely understand you. You have class defined in C++ and another one > defined in Python, derived from the first one, right? Now you want to > downcast to > the class defined in Python? If so you cannot do this. You can get > reference to relevant Python object and than using Boost.Python to get > access to desired > functionality. > > From roman.yakovenko at gmail.com Tue Feb 13 19:42:56 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 13 Feb 2007 20:42:56 +0200 Subject: [C++-sig] problems downcasting intrusive_ptr. In-Reply-To: <45D205A1.9000401@image-engine.com> References: <45CD1591.9040408@image-engine.com> <7465b6170702101335p22a87175h26e66cba106f255c@mail.gmail.com> <45D0EF28.6070900@image-engine.com> <7465b6170702130102x6198bfa1r2985d237b584574a@mail.gmail.com> <45D205A1.9000401@image-engine.com> Message-ID: <7465b6170702131042q64dd8bc9qa9bfa690b790487e@mail.gmail.com> On 2/13/07, Lucio Moser wrote: > Yes, that's what I wanted. I have a core C++ library that works using > intrusive_ptr everywhere. And I'm binding that to Python. > The downcasting to a Python class works if I compile my test case using > shared_ptr. There should be a way to do it with intrusive_ptr. I still don't understand what you try to do. Please start new thread with clear explanation what you tries to do. > I appreciate your help. The code that solves the previous problem is > listed below. It also shows the new problem. To compile it for > shared_ptr, just define USE_SHARED_PTR. The functions upcast and > store/retrieve will work correctly for shared_ptr and not for > intrusive_ptr (shown below). Thanks. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From lucio at image-engine.com Tue Feb 13 20:04:05 2007 From: lucio at image-engine.com (Lucio Moser) Date: Tue, 13 Feb 2007 11:04:05 -0800 Subject: [C++-sig] problems downcasting from C++ base class intrusive pointers to Python derived instances. Message-ID: <45D20BA5.8080902@image-engine.com> I created a simpleTest python module that provides two C++ classes, named "Base" and "Derived". I also provide some methods that receive and/or return intrusive_ptr for the "Base" class. If I instantiate "Derived" class in Python and use it on the functions then it's ok. If I create a class in Python that is derived from "Derived" class and use it on the library functions then I lose the Python object and get only the most derived C++ instance. If I compile the same simpleTest library, using shared_ptr only then everything works fine, like shown below. Thank you for your help. python test code using shared_ptr: ================================== Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> >>> class Derived2(Derived): ... pass ... >>> a = Derived2() >>> a <__main__.Derived2 object at 0xb7f3743c> >>> store(a) >>> b = retrieve() >>> b <__main__.Derived2 object at 0xb7f3743c> >>> >>> upcast(a) <__main__.Derived2 object at 0xb7f3743c> >>> python test code using intrusive_ptr: ===================================== Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> >>> class Derived2(Derived): ... pass ... >>> a = Derived2() >>> a <__main__.Derived2 object at 0xb7edea7c> >>> store(a) >>> b = retrieve() >>> b >>> >>> upcast(a) >>> simpleTest.cpp: =============== #include #include "register_intrusive_ptr_from_python.hpp" class Base { public : Base ( ) : m_numRefs( 0 ) { } /// Add a reference to the current object void addRef() const { m_numRefs ++; } /// Remove a reference from the current object void removeRef() const { m_numRefs --; if ( m_numRefs == 0 ) { delete this; } } protected : mutable unsigned int m_numRefs; virtual ~Base() { } }; class Derived; #ifdef USE_SHARED_PTR #include "boost/shared_ptr.hpp" typedef boost::shared_ptr BasePtr; typedef boost::shared_ptr DerivedPtr; #else // USE_SHARED_PTR #include "boost/intrusive_ptr.hpp" typedef boost::intrusive_ptr BasePtr; typedef boost::intrusive_ptr DerivedPtr; /// Functions required to allow use of Base with boost::intrusive_ptr inline void intrusive_ptr_add_ref( const Base *r ) { r->addRef(); } inline void intrusive_ptr_release( const Base *r ) { r->removeRef(); } #endif // USE_SHARED_PTR class Derived : public Base { public : Derived( ) : Base ( ), m_data( 0 ) { } protected : int m_data; }; BasePtr baseUpcast( BasePtr base ) { return base; } struct GlobalsTest { static BasePtr g_object ; static BasePtr retrieve() { return g_object; } static void store( const BasePtr &o) { g_object = o; } }; BasePtr GlobalsTest::g_object; using namespace boost::python; BOOST_PYTHON_MODULE(simpleTest) { typedef class_< Base, boost::noncopyable, BasePtr > BaseClass; BaseClass baseClass("Base", no_init); #ifndef USE_SHARED_PTR boostPatch::register_intrusive_ptr_from_python_and_casts( (Base *)0, BaseClass::metadata::bases() ); #endif typedef class_< Derived, boost::noncopyable, DerivedPtr, bases< Base > > DerivedClass; DerivedClass derivedClass( "Derived" ); #ifndef USE_SHARED_PTR boostPatch::register_intrusive_ptr_from_python_and_casts( (Derived *)0, DerivedClass::metadata::bases() ); #endif def("upcast", &baseUpcast); def("store", & GlobalsTest::store ); def("retrieve", & GlobalsTest::retrieve ); implicitly_convertible(); } register_intrusive_ptr_from_python.hpp ======================================= #ifndef REGISTER_INTRUSIVE_PTR_FROM_PYTHON_HPP # define REGISTER_INTRUSIVE_PTR_FROM_PYTHON_HPP # include #include "intrusive_ptr_from_python.hpp" namespace boostPatch { // This function was based on register_shared_ptr_from_python_and_casts() from class_metadata.hpp. // // Preamble of register_class. Also used for callback classes, which // need some registration of their own. // template inline void register_intrusive_ptr_from_python_and_casts(T*, Bases) { using namespace boost::python::objects; // Constructor performs registration python::detail::force_instantiate(intrusive_ptr_from_python()); // // register all up/downcasts here. We're using the alternate // interface to mpl::for_each to avoid an MSVC 6 bug. // register_dynamic_id(); mpl::for_each(register_base_of(), (Bases*)0, (boost::add_pointer*)0); } } // namespace boostPatch #endif // INTRUSIVE_PTR_FROM_PYTHON_HPP intrusive_ptr_from_python.hpp ============================== // Based on boost header: shared_ptr_from_python.hpp. #ifndef INTRUSIVE_PTR_FROM_PYTHON_HPP # define INTRUSIVE_PTR_FROM_PYTHON_HPP # include # include # include # include # include # include namespace boostPatch { using namespace boost; using namespace boost::python; using namespace boost::python::converter; template struct intrusive_ptr_from_python { intrusive_ptr_from_python() { converter::registry::insert(&convertible, &construct, type_id >()); } private: static void* convertible(PyObject* p) { if (p == Py_None) return p; return converter::get_lvalue_from_python(p, registered::converters); } static void construct(PyObject* source, rvalue_from_python_stage1_data* data) { void* const storage = ((converter::rvalue_from_python_storage >*)data)->storage.bytes; // Deal with the "None" case. if (data->convertible == source) new (storage) intrusive_ptr(); else new (storage) intrusive_ptr( static_cast(data->convertible) ); data->convertible = storage; } }; } // namespace boostPatch #endif // INTRUSIVE_PTR_FROM_PYTHON_HPP From roman.yakovenko at gmail.com Tue Feb 13 20:32:19 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 13 Feb 2007 21:32:19 +0200 Subject: [C++-sig] problems downcasting from C++ base class intrusive pointers to Python derived instances. In-Reply-To: <45D20BA5.8080902@image-engine.com> References: <45D20BA5.8080902@image-engine.com> Message-ID: <7465b6170702131132g5334da8cnd86da73d2fc882c7@mail.gmail.com> On 2/13/07, Lucio Moser wrote: > > I created a simpleTest python module that provides two C++ classes, > named "Base" and "Derived". I also provide some methods that receive > and/or return intrusive_ptr for the "Base" class. If I instantiate > "Derived" class in Python and use it on the functions then it's ok. If I > create a class in Python that is derived from "Derived" class and use it > on the library functions then I lose the Python object and get only the > most derived C++ instance. I don't know how this possible. It does not matter what smart pointer you use you cannot downcast to Python class. This is just impossible. You only can downcast to the class defined in C++. After reading your post few times, I think I understand your question and unfortunately I cannot help. I have 2 advices to you: Try to use class wrapper( http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions ). May be this will help. Try to introduce pure virtual function to your classes. May be compiler will find for you the places, you make class "slicing"( http://www.informit.com/articles/printerfriendly.asp?p=31529&rl=1 ) -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From lucio at image-engine.com Tue Feb 13 20:54:20 2007 From: lucio at image-engine.com (Lucio Moser) Date: Tue, 13 Feb 2007 11:54:20 -0800 Subject: [C++-sig] problems downcasting from C++ base class intrusive pointers to Python derived instances. In-Reply-To: <7465b6170702131132g5334da8cnd86da73d2fc882c7@mail.gmail.com> References: <45D20BA5.8080902@image-engine.com> <7465b6170702131132g5334da8cnd86da73d2fc882c7@mail.gmail.com> Message-ID: <45D2176C.2080902@image-engine.com> > I don't know how this possible. It does not matter what smart pointer you use > you cannot downcast to Python class. This is just impossible. You only > can downcast to the class defined in C++. > Well, the reality is, it works for shared_ptr. If you compile the code you'll see it. Whatever boost.python is doing, it knows to downcast the shared_ptr for a C++ class to a python derived class. There should be a solution for intrusive_ptr too. > After reading your post few times, I think I understand your question > and unfortunately I cannot help. > I have 2 advices to you: > > Try to use class wrapper( > http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions > ). May be this will help. > > Try to introduce pure virtual function to your classes. May be > compiler will find > for you the places, you make class "slicing"( > http://www.informit.com/articles/printerfriendly.asp?p=31529&rl=1 ) > > Thank you for the links. I'll check them out in detail. Although they do not seem related to the problem I'm facing. I'm not trying to redefine the virtual methods of the C++ class on the python derived class. I'm just creating a very simple derived python class, and I'm not getting it back if I send it to the C++ functions. This is my simple Python derived class. I'm not redefining any method on it. class Derived2(Derived): pass From roman.yakovenko at gmail.com Tue Feb 13 21:07:35 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 13 Feb 2007 22:07:35 +0200 Subject: [C++-sig] problems downcasting from C++ base class intrusive pointers to Python derived instances. In-Reply-To: <45D2176C.2080902@image-engine.com> References: <45D20BA5.8080902@image-engine.com> <7465b6170702131132g5334da8cnd86da73d2fc882c7@mail.gmail.com> <45D2176C.2080902@image-engine.com> Message-ID: <7465b6170702131207y1616e571x6f8f7a1282daf3c@mail.gmail.com> On 2/13/07, Lucio Moser wrote: > > > I don't know how this possible. It does not matter what smart pointer you use > > you cannot downcast to Python class. This is just impossible. You only > > can downcast to the class defined in C++. > > > Well, the reality is, it works for shared_ptr. If you compile the code > you'll see it. Whatever boost.python is doing, it knows to downcast the > shared_ptr for a C++ class to a python derived class. There should be a > solution for intrusive_ptr too. > > > After reading your post few times, I think I understand your question > > and unfortunately I cannot help. > > I have 2 advices to you: > > > > Try to use class wrapper( > > http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions > > ). May be this will help. > > > > Try to introduce pure virtual function to your classes. May be > > compiler will find > > for you the places, you make class "slicing"( > > http://www.informit.com/articles/printerfriendly.asp?p=31529&rl=1 ) > > > > > Thank you for the links. I'll check them out in detail. Although they do > not seem related to the problem I'm facing. I'm not trying to redefine > the virtual methods of the C++ class on the python derived class. I'm > just creating a very simple derived python class, and I'm not getting it > back if I send it to the C++ functions. The first link was to explain what the class wrapper I meant. If you introduce class-wrapper for your classes, then I think the problem will gone, because Boost.Python will create relevant "BaseWrap" class, where it will keep reference to relevant Python object. I think it worth to check this option. The second one was to explain what is "slicing" problem. May be your code contains the problem. If you define pure virtual function, the compiler will help you to find it. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From lucio at image-engine.com Tue Feb 13 22:14:34 2007 From: lucio at image-engine.com (Lucio Moser) Date: Tue, 13 Feb 2007 13:14:34 -0800 Subject: [C++-sig] problems downcasting from C++ base class intrusive pointers to Python derived instances. In-Reply-To: <7465b6170702131207y1616e571x6f8f7a1282daf3c@mail.gmail.com> References: <45D20BA5.8080902@image-engine.com> <7465b6170702131132g5334da8cnd86da73d2fc882c7@mail.gmail.com> <45D2176C.2080902@image-engine.com> <7465b6170702131207y1616e571x6f8f7a1282daf3c@mail.gmail.com> Message-ID: <45D22A3A.7090706@image-engine.com> Roman Yakovenko wrote: > The first link was to explain what the class wrapper I meant. If you introduce > class-wrapper for your classes, then I think the problem will gone, > because Boost.Python will create relevant "BaseWrap" class, where it > will keep reference > to relevant Python object. I think it worth to check this option. > Ok. I followed the steps on that page. I created a wrapper for Base and Derived classes (listed at the end of this e-mail). It worked nicely with shared_ptr and I got an exception for intrusive_ptr while passing a proper C++ Derived instance to the upcast() function. There's no information on that page regarding wrappers and smart pointers to the wrapped classes. But the fact that shared_ptr works leads me to think that I'm doing the right thing. You could verify this by compiling the code as shared_ptr and intrusive_ptr and executing the following commands on python: INTRUSIVE_PTR case: ================== Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> >>> a = Derived() >>> a >>> upcast(a) *** glibc detected *** free(): invalid pointer: 0x088b9df8 *** Abort SHARED_PTR case: ================= Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> a = Derived() >>> >>> upcast(a) >>> >>> class sub(Derived): ... pass ... >>> a >>> b = sub() >>> b <__main__.sub object at 0xb7f66a7c> >>> >>> upcast(b) <__main__.sub object at 0xb7f66a7c> >>> > The second one was to explain what is "slicing" problem. May be your code > contains the problem. If you define pure virtual function, the > compiler will help > you to find it. > Do you think that the Derived2 python class is someway "sliced" to a Derived object when it is sent to the C++ library? If yes, why this does not happen when I use shared_ptr? My only explanation for this would be that boost.python has loads of specific code for shared_ptr and it is not fully compatible with intrusive_ptr. Should we consider that this is a flaw on boost.python regarding intrusive_ptr? Here's the new simpleTest.cpp (with wrapped classes): ====================================== #include #include "register_intrusive_ptr_from_python.hpp" class Base { public : Base ( ) : m_numRefs( 0 ) { } /// Add a reference to the current object void addRef() const { m_numRefs ++; } /// Remove a reference from the current object void removeRef() const { m_numRefs --; if ( m_numRefs == 0 ) { delete this; } } protected : mutable unsigned int m_numRefs; virtual ~Base() { } }; class Derived; #ifdef USE_SHARED_PTR #include "boost/shared_ptr.hpp" typedef boost::shared_ptr BasePtr; typedef boost::shared_ptr DerivedPtr; #else // USE_SHARED_PTR #include "boost/intrusive_ptr.hpp" typedef boost::intrusive_ptr BasePtr; typedef boost::intrusive_ptr DerivedPtr; /// Functions required to allow use of Base with boost::intrusive_ptr inline void intrusive_ptr_add_ref( const Base *r ) { r->addRef(); } inline void intrusive_ptr_release( const Base *r ) { r->removeRef(); } #endif // USE_SHARED_PTR class Derived : public Base { public : Derived( ) : Base ( ), m_data( 0 ) { } virtual int test1() { return this->m_data; } virtual int test2( DerivedPtr d ) { return (this->m_data == d->m_data); } protected : int m_data; }; BasePtr factory( void ) { return BasePtr( new Derived() ); } BasePtr baseUpcast( BasePtr base ) { return base; } struct GlobalsTest { static BasePtr g_object ; static BasePtr retrieve() { return g_object; } static void store( const BasePtr &o) { g_object = o; } }; BasePtr GlobalsTest::g_object; using namespace boost::python; struct BaseWrap : Base, wrapper { // there's no virtual method on Base class }; struct DerivedWrap : Derived, wrapper { int test1() { if (override test1 = this->get_override("test1")) return test1(); return Derived::test1(); } int test2( DerivedPtr d ) { if (override test2 = this->get_override("test2")) return test2( d ); return Derived::test2( d ); } int default_test1() { return this->Derived::test1(); } int default_test2( DerivedPtr d ) { return this->Derived::test2( d ); } }; BOOST_PYTHON_MODULE(simpleTest) { typedef class_< BaseWrap, boost::noncopyable > BaseClass; BaseClass baseClass("Base", no_init); #ifndef USE_SHARED_PTR IECore::register_intrusive_ptr_from_python_and_casts( (Base *)0, BaseClass::metadata::bases() ); #endif typedef class_< DerivedWrap, boost::noncopyable, bases< Base > > DerivedClass; DerivedClass derivedClass( "Derived" ); #ifndef USE_SHARED_PTR IECore::register_intrusive_ptr_from_python_and_casts( (Derived *)0, DerivedClass::metadata::bases() ); #endif derivedClass.def( "test1", &Derived::test1 ); derivedClass.def( "test2", &Derived::test2 ); def("factory", &factory); def("upcast", &baseUpcast); def("store", & GlobalsTest::store ); def("retrieve", & GlobalsTest::retrieve ); implicitly_convertible(); } From lucio at image-engine.com Tue Feb 13 22:26:05 2007 From: lucio at image-engine.com (Lucio Moser) Date: Tue, 13 Feb 2007 13:26:05 -0800 Subject: [C++-sig] problems downcasting from C++ base class intrusive pointers to Python derived instances. In-Reply-To: <7465b6170702131207y1616e571x6f8f7a1282daf3c@mail.gmail.com> References: <45D20BA5.8080902@image-engine.com> <7465b6170702131132g5334da8cnd86da73d2fc882c7@mail.gmail.com> <45D2176C.2080902@image-engine.com> <7465b6170702131207y1616e571x6f8f7a1282daf3c@mail.gmail.com> Message-ID: <45D22CED.8020706@image-engine.com> A note: If I remove the calls to register_intrusive_ptr_from_python_and_casts() function then it won't crash any more. But also, It won't convert between the wrapped class instances to the intrusive_ptr on the original functions. Python 2.5 (r25:51908, Nov 17 2006, 14:19:39) [GCC 4.0.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from simpleTest import * >>> a = Derived() >>> upcast(a) Traceback (most recent call last): File "", line 1, in Boost.Python.ArgumentError: Python argument types in simpleTest.upcast(Derived) did not match C++ signature: upcast(boost::intrusive_ptr) >>> a = factory() Traceback (most recent call last): File "", line 1, in TypeError: No to_python (by-value) converter found for C++ type: boost::intrusive_ptr >>> From duranlef at iro.umontreal.ca Wed Feb 14 04:40:17 2007 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Tue, 13 Feb 2007 22:40:17 -0500 (EST) Subject: [C++-sig] expose python iterators to c++? In-Reply-To: References: Message-ID: On Sat, 10 Feb 2007, Neal Becker wrote: > Has anyone looked into exposing python iterators to c++? > > It would be very nice if a python object implementing the python iterator > protocol was able to be used as a boost::range. Then c++ algorithms > conforming to boost::range requirements could accept a python object > conforming to the python iterator protocol. I did recently, although I did not fully test it. I put the code and a sample test here: http://tinyurl.com/24dpdf It supports SinglePassRange and ForwardRange (although I don't like my solution so far for this type, that is, accumulate the values in a vector and replay the iteration with that). Making SinglePassRange is not difficult, but for other types, it's trickier, because Python's iterators are really single pass iterators. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al From ichijoji at gmail.com Wed Feb 14 09:29:29 2007 From: ichijoji at gmail.com (ichijoji) Date: Wed, 14 Feb 2007 00:29:29 -0800 (PST) Subject: [C++-sig] How to import a boost::python dll in windows? Message-ID: <8960577.post@talk.nabble.com> I'm trying to port some research code that uses boost::python to expose a library to python to windows, but I'm having trouble importing the dll into python. I'm compiling using msvc 2005 and using python 2.5, but when I try to import the module I get this: Traceback (most recent call last): File "main.py", line 1, in import object File "c:\code\sge\code\scripts\object.py", line 1, in import sge ImportError: No module named sge My module is named sge and I'm compiling to sge.dll. Is there some obvious reason why python wouldn't be able to find my dll? When I compile on linux into an so this code works fine. -- View this message in context: http://www.nabble.com/How-to-import-a-boost%3A%3Apython-dll-in-windows--tf3225845.html#a8960577 Sent from the Python - c++-sig mailing list archive at Nabble.com. From roman.yakovenko at gmail.com Wed Feb 14 13:38:50 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 14 Feb 2007 14:38:50 +0200 Subject: [C++-sig] How to import a boost::python dll in windows? In-Reply-To: <8960577.post@talk.nabble.com> References: <8960577.post@talk.nabble.com> Message-ID: <7465b6170702140438g5d93eb2an87f817022e705950@mail.gmail.com> On 2/14/07, ichijoji wrote: > > I'm trying to port some research code that uses boost::python to expose a > library to python to windows, but I'm having trouble importing the dll into > python. I'm compiling using msvc 2005 and using python 2.5, but when I try > to import the module I get this: > > Traceback (most recent call last): > File "main.py", line 1, in > import object > File "c:\code\sge\code\scripts\object.py", line 1, in > import sge > ImportError: No module named sge > > My module is named sge and I'm compiling to sge.dll. Is there some obvious > reason why python wouldn't be able to find my dll? When I compile on linux > into an so this code works fine. You are using Python2.5. In this version of Python you have to have file extension to be "pyd" - sge.pyd -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From meine at informatik.uni-hamburg.de Wed Feb 14 15:03:40 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Wed, 14 Feb 2007 15:03:40 +0100 Subject: [C++-sig] OT(?): Building boost::python with distutils? Message-ID: <200702141503.42276.meine@informatik.uni-hamburg.de> Hi! David Abrahams once asked on the distutils list whether distutils could be used to build shared libraries (like libboost_python.so) which are no extension modules: http://mail.python.org/pipermail/distutils-sig/2002-October/002966.html Apparently, the answers all contain more or less hackish ways around using distutils.Extension(..) I am sorry if this is more or less off-topic here, but does anybody know whether there is a solution to that problem? (To draw a real connection to BPL: This is about distributing BPL extension modules which all link against a common shared library.) Ciao, / / /--/ / / ANS From seefeld at sympatico.ca Wed Feb 14 15:18:08 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 14 Feb 2007 09:18:08 -0500 Subject: [C++-sig] OT(?): Building boost::python with distutils? In-Reply-To: <200702141503.42276.meine@informatik.uni-hamburg.de> References: <200702141503.42276.meine@informatik.uni-hamburg.de> Message-ID: <45D31A20.5050105@sympatico.ca> Hans Meine wrote: > Hi! > > David Abrahams once asked on the distutils list whether distutils could be > used to build shared libraries (like libboost_python.so) which are no > extension modules: > http://mail.python.org/pipermail/distutils-sig/2002-October/002966.html > > Apparently, the answers all contain more or less hackish ways around using > distutils.Extension(..) > > I am sorry if this is more or less off-topic here, but does anybody know > whether there is a solution to that problem? (To draw a real connection to > BPL: This is about distributing BPL extension modules which all link against > a common shared library.) My 'solution' is indeed to work around the 'Extension' mechanism. Completely. In my case (Synopsis: http://synopsis.fresco.org/, for the curious), I build a C++ library as well as a set of python (extension) modules, so this is a hybrid project, which distutils wasn't exactly designed for. I have basically reimplemented all the main distutils commands that relate to that, and then added a 'build_clib' command for the shared (in the above sense) library. My build_clib and build_ext commands are essentially opaque wrappers around invocations to 'make'. None of those commands uses the distutils.Extension type at all. I don't think it is worth waiting for distutils to fix this. I would, however, be interested in looking into ways to add distutils-like capabilities to boost.build. (I mentored a Google SoC project last summer to do something similar to SCons.) Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From pk at cs.tut.fi Wed Feb 14 20:45:44 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Wed, 14 Feb 2007 21:45:44 +0200 Subject: [C++-sig] Loss of polymorphism with std::auto_ptr Message-ID: <45D366E8.7070507@cs.tut.fi> I've followed the recipe for transfering ownership at . Everything works nicely, except that I seem to lose polymorphism. Let's say I have a base class A and a derived class A1, and class B which has a member function set_a(A*). If I wrap B::set_a() using an auto_ptr as suggested in the FAQ, and try to call it from Python with an A1 object, I get the following error: Boost.Python.ArgumentError: Python argument types in B.set_a(B, A1) did not match C++ signature: set_a(B {lvalue}, std::auto_ptr) I know how to fix this by creating another wrapper for set_a that takes std::auto_ptr and binding it to "set_a" in Python. However, I would like to avoid this if possible, since the number of wrappers can grow quite large. Any suggestions as to how to avoid the per subclass wrappers? I have attached a small but complete example. -- Pertti -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: testing.cpp URL: From roman.yakovenko at gmail.com Wed Feb 14 20:54:19 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 14 Feb 2007 21:54:19 +0200 Subject: [C++-sig] Loss of polymorphism with std::auto_ptr In-Reply-To: <45D366E8.7070507@cs.tut.fi> References: <45D366E8.7070507@cs.tut.fi> Message-ID: <7465b6170702141154w775d8080wcd2a160cb61a683f@mail.gmail.com> On 2/14/07, Pertti Kellom?ki wrote: > I've followed the recipe for transfering ownership at > . > Everything works nicely, except that I seem to lose polymorphism. > > Let's say I have a base class A and a derived class A1, and > class B which has a member function set_a(A*). If I wrap > B::set_a() using an auto_ptr as suggested in the FAQ, and try > to call it from Python with an A1 object, I get the following > error: > > Boost.Python.ArgumentError: Python argument types in > B.set_a(B, A1) > did not match C++ signature: > set_a(B {lvalue}, std::auto_ptr) > > I know how to fix this by creating another wrapper for set_a > that takes std::auto_ptr and binding it to "set_a" in Python. > However, I would like to avoid this if possible, since the > number of wrappers can grow quite large. > > Any suggestions as to how to avoid the per subclass wrappers? > > I have attached a small but complete example. > -- > Pertti > > #include > class A { > }; > > class A1 : public A { > }; > > class B { > public: > B(); > void set_a(A* a); > A* a_; > }; > > B::B() { a_ = new A(); }; > > void B::set_a(A* a) { > delete a_; > a_ = a; > }; > > void set_a(B& b, std::auto_ptr a) { > b.set_a(a.get()); > a.release(); > }; > > using namespace boost::python; > > BOOST_PYTHON_MODULE(testing) { > class_ >("A", init<>()) > ; > class_, std::auto_ptr >("A1", init<>()) > ; > class_("B", init<>()) > .def("set_a", &set_a) > ; > } > > /* > Running this in Python > > $ python2.4 > Python 2.4.4 (#3, Dec 21 2006, 12:46:16) > [GCC 4.1.1] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> from testing import * > >>> b = B() > >>> b.set_a(A()) > >>> b.set_a(A1()) > Traceback (most recent call last): > File "", line 1, in ? > Boost.Python.ArgumentError: Python argument types in > B.set_a(B, A1) > did not match C++ signature: > set_a(B {lvalue}, std::auto_ptr) > >>> > > */ Take a look on http://boost.org/libs/python/doc/v2/implicit.html#implicitly_convertible-spec I think you need to register implicit conversion between auto_ptr and auto_ptr -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From pk at cs.tut.fi Wed Feb 14 21:06:20 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Wed, 14 Feb 2007 22:06:20 +0200 Subject: [C++-sig] Loss of polymorphism with std::auto_ptr In-Reply-To: <7465b6170702141154w775d8080wcd2a160cb61a683f@mail.gmail.com> References: <45D366E8.7070507@cs.tut.fi> <7465b6170702141154w775d8080wcd2a160cb61a683f@mail.gmail.com> Message-ID: <45D36BBC.8070502@cs.tut.fi> Roman Yakovenko kirjoitti: > I think you need to register implicit conversion between auto_ptr and > auto_ptr Yes, that did the trick. Thank you, this really saved my day! -- Pertti From ngoodspeed at solidworks.com Wed Feb 14 21:09:09 2007 From: ngoodspeed at solidworks.com (Nat Goodspeed) Date: Wed, 14 Feb 2007 15:09:09 -0500 Subject: [C++-sig] Loss of polymorphism with std::auto_ptr References: <45D366E8.7070507@cs.tut.fi> Message-ID: <94F7A8DD4408D8499C6812FE42E2D4B7B116AD@corp-mail4.solidworks.swk> -----Original Message----- From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On Behalf Of Pertti Kellom?ki Sent: Wednesday, February 14, 2007 2:46 PM To: Development of Python/C++ integration Subject: [C++-sig] Loss of polymorphism with std::auto_ptr Boost.Python.ArgumentError: Python argument types in B.set_a(B, A1) did not match C++ signature: set_a(B {lvalue}, std::auto_ptr) Any suggestions as to how to avoid the per subclass wrappers? [Nat] Something quite like this came up only a few days ago: http://blog.gmane.org/gmane.comp.python.c%2B%2B/day=20070212 In fact the issue of passing smart pointers other than boost::shared_ptr seems to arise on a regular basis. It's probably worth a section in the Boost.Python reference documentation. I know, I know, standard answer: submit a doc patch. I'd like to, except that I haven't yet grasped the solution myself. We have the same problem; we presently work around it with a hideous assortment of (what should be) redundant overloads. I wish someone would post a recipe. From pk at cs.tut.fi Wed Feb 14 21:21:51 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Wed, 14 Feb 2007 22:21:51 +0200 Subject: [C++-sig] Loss of polymorphism with std::auto_ptr In-Reply-To: <94F7A8DD4408D8499C6812FE42E2D4B7B116AD@corp-mail4.solidworks.swk> References: <45D366E8.7070507@cs.tut.fi> <94F7A8DD4408D8499C6812FE42E2D4B7B116AD@corp-mail4.solidworks.swk> Message-ID: <45D36F5F.7000009@cs.tut.fi> Nat Goodspeed wrote: > I wish someone would post a recipe. Here's my (now working) example if that is of any help. -- Pertti -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: testing.cpp URL: From ndbecker2 at gmail.com Thu Feb 15 02:19:31 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Wed, 14 Feb 2007 20:19:31 -0500 Subject: [C++-sig] expose python iterators to c++? References: Message-ID: Fran?ois Duranleau wrote: > On Sat, 10 Feb 2007, Neal Becker wrote: > >> Has anyone looked into exposing python iterators to c++? >> >> It would be very nice if a python object implementing the python iterator >> protocol was able to be used as a boost::range. Then c++ algorithms >> conforming to boost::range requirements could accept a python object >> conforming to the python iterator protocol. > > I did recently, although I did not fully test it. I put the code and a > sample test here: > > http://tinyurl.com/24dpdf > > It supports SinglePassRange and ForwardRange (although I don't like my > solution so far for this type, that is, accumulate the values in a vector > and replay the iteration with that). Making SinglePassRange is not > difficult, but for other types, it's trickier, because Python's iterators > are really single pass iterators. > Looks very interesting. One thing I'm not sure about. Do I understand correctly that an python object is convertible to a c++ range iff PyObject_GetIter( obj )? I think it needs also that deref the iterator produces the correct type. In range_test.cpp: typedef ::pyfdl::range< int > range_int_type ; Don't we need different converters for range, range, etc? From ypodpruzhnikov at mcode.ru Thu Feb 15 15:56:19 2007 From: ypodpruzhnikov at mcode.ru (Podpruzhnikov Yuri) Date: Thu, 15 Feb 2007 17:56:19 +0300 Subject: [C++-sig] PyFinalize Safety Message-ID: We embed Python to our project and use Boost.Python. Very much code had been already created. But great problem came to us: python interpreter must be reinitialized, but Boost.Python doesn't support "PyFinalize Safety" (http://www.boost.org/libs/python/todo.html#pyfinalize-safety) I see 2 decisions of the problem: 1) We delete Boost.Python from our project. But this will make extension of Python very difficult. :) 2) We write (or find) "PyFinalize Safety" of Boost.Python. I choose 2-nd decision till now. But if it is very difficult, I'll choose the 1-st way of solving the problem. I have a few questions to ask: - What is the difficulty of this problem to be solved? - Have anyone already written this? - If yes, could you give me code or advice at least? Sorry for my English. From duranlef at iro.umontreal.ca Thu Feb 15 16:26:19 2007 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Thu, 15 Feb 2007 10:26:19 -0500 (EST) Subject: [C++-sig] expose python iterators to c++? In-Reply-To: References: Message-ID: > On Wed, 14 Feb 2007, Neal Becker wrote: > > Fran?ois Duranleau wrote: [...] > > http://tinyurl.com/24dpdf [...] I added a simple use test in Python (forgot the first time). > Looks very interesting. One thing I'm not sure about. Do I understand > correctly that an python object is convertible to a c++ range iff > PyObject_GetIter( obj )? I think it needs also that deref the iterator > produces the correct type. We should. However, because Python's sequences can contain objects of heterogenous types, we would actually need to test all objects in the sequence. But granted, only testing the first item could be a simple heuristic to avoid common errors. > In range_test.cpp: > typedef ::pyfdl::range< int > range_int_type ; > > Don't we need different converters for range, range, etc? Yes, of course. That typedef was just a sample use when you need an iterator over integer values (that's laziness from me for not writing comments in the example). Whenever you need to export a function requiring ranges or pairs of iterators, you would also need to call range_from_and_to_python for all required types in your application. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al From ndbecker2 at gmail.com Thu Feb 15 19:46:47 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 15 Feb 2007 13:46:47 -0500 Subject: [C++-sig] expose python iterators to c++? References: Message-ID: Cool. I'm not sure how this works (seems like magic to me), but it does appear to work: -------------- next part -------------- A non-text attachment was scrubbed... Name: range.hpp Type: text/x-c++src Size: 7239 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: range_test.cc Type: text/x-csrc Size: 1042 bytes Desc: not available URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: r.py URL: From duranlef at iro.umontreal.ca Thu Feb 15 21:10:36 2007 From: duranlef at iro.umontreal.ca (=?ISO-8859-1?Q?Fran=E7ois_Duranleau?=) Date: Thu, 15 Feb 2007 15:10:36 -0500 (EST) Subject: [C++-sig] expose python iterators to c++? In-Reply-To: References: Message-ID: On Thu, 15 Feb 2007, Neal Becker wrote: > Cool. I'm not sure how this works (seems like magic to me), but it does > appear to work: In bried, I first created a class "range" that adapts a Python iterator to a C++ range. This is done in a similar way to std::istream_iterator. Then, instead of exposing this class to Python, I created custom converters to and from Python. There is an example of such convertion for custom strings in the Boost.Python documentation: http://www.boost.org/libs/python/doc/v2/faq.html#custom_string Then all that needs to be done is to instantiate the functions with the class range for all appropriate types, expose them, and register the converters. If you encounter problems, let me know. -- Fran?ois Duranleau LIGUM, Universit? de Montr?al "Time is the best teacher. Unfortunately, it kills all of its students." - Aionias the Sapphire Mage (_A Guide to the Ethereal Plane_ by Bruce R. Cordell) From kanand at qualcomm.com Fri Feb 16 01:43:03 2007 From: kanand at qualcomm.com (Anand, Kumar) Date: Thu, 15 Feb 2007 16:43:03 -0800 Subject: [C++-sig] Py++ filter based on return type In-Reply-To: <7465b6170702130102x6198bfa1r2985d237b584574a@mail.gmail.com> Message-ID: Hi, Q 1 ) For a given class, how can I filter all member functions that return a pointer, so that I can apply call policies on each of them? Q2) What is wrong with the following code? I am trying to specify call policy on functions (inside class TCON) whose return type starts with the "TC_at_" string. This doesn't seem to work. mb.class_("TCON").member_functions( return_type = "/TC_at_.*/" ).call_policies = \ call_policies.return_internal_reference() Any suggestions? Thanks Kumar From roman.yakovenko at gmail.com Fri Feb 16 06:30:14 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 16 Feb 2007 07:30:14 +0200 Subject: [C++-sig] Py++ filter based on return type In-Reply-To: References: <7465b6170702130102x6198bfa1r2985d237b584574a@mail.gmail.com> Message-ID: <7465b6170702152130p293e2319ldaa1043ae038c010@mail.gmail.com> On 2/16/07, Anand, Kumar wrote: > Hi, > > Q 1 ) For a given class, how can I filter all member functions that > return a pointer, so that I can apply call policies on each of them? cls = mb.class_( ... ) funs = cls.mem_funs( lambda f: declarations.is_pointer( f.return_type ) ) > Q2) What is wrong with the following code? I am trying to specify call > policy on functions (inside class TCON) whose return type starts with > the "TC_at_" string. This doesn't seem to work. > > mb.class_("TCON").member_functions( return_type = "/TC_at_.*/" > ).call_policies = \ > call_policies.return_internal_reference() There is no partial match for types. You only can pass full type definition. The type could be passed as string or as instance of type_t class. You can write the previous select, using regular expression matcher: from declarations import custom_matcher_t as c_matcher from declarations import regex_matcher_t as re_matcher cls.mem_funs( c_matcher( lambda f: f.return_type ) & re_matcher( "TC_at_.*\*", lambda f: f.return_type.decl_string ) ) c_matcher - will check that function has return type re_matcher will apply regular expression on return_type string Few references to documentation: type_traits: http://www.language-binding.net/pygccxml/apidocs/pygccxml.declarations.type_traits-module.html matchers( build-in search / match algorithms ) -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From paul at mustagh.com Fri Feb 16 17:58:44 2007 From: paul at mustagh.com (Paul Guse) Date: Fri, 16 Feb 2007 09:58:44 -0700 Subject: [C++-sig] PyFinalize Safety References: Message-ID: <006a01c751eb$b8e75040$6c01a8c0@paul> Not sure if this solution/hack will work for you, but a quasi way to reinitialize the interpreter is to clear the main dictionary to the original state: - make a copy of the main dictionary upon initialization - run your python script - clear the main dictionary - set the dictionary to the original copy. Some code: object main_module (handle<> (borrowed (PyImport_AddModule ("__main__")))) ; object dictionary = main_module.attr ("__dict__") ; // copy the dictionary PyObject* clean_dict = PyDict_Copy (dictionary.ptr()) ; // run your python script. // reset main dictonary PyDict_Clear (dictionary.ptr()) ; PuDict_Update (dictionary.ptr(), clean_dict) ; Py_XDECREF (clean_dict) ; Something like anyways. This could be a total hack, and I'm not sure it's foolproof, but it at least resets the main dictionary so that it appears to be a new session. Paul ----- Original Message ----- From: "Podpruzhnikov Yuri" To: Sent: Thursday, February 15, 2007 7:56 AM Subject: [C++-sig] PyFinalize Safety > We embed Python to our project and use Boost.Python. Very much code had > been already created. > But great problem came to us: python interpreter must be reinitialized, > but Boost.Python doesn't support "PyFinalize Safety" > (http://www.boost.org/libs/python/todo.html#pyfinalize-safety) > > I see 2 decisions of the problem: > 1) We delete Boost.Python from our project. But this will make extension > of Python very difficult. :) > 2) We write (or find) "PyFinalize Safety" of Boost.Python. > > I choose 2-nd decision till now. But if it is very difficult, I'll > choose the 1-st way of solving the problem. > I have a few questions to ask: > - What is the difficulty of this problem to be solved? > - Have anyone already written this? > - If yes, could you give me code or advice at least? > > Sorry for my English. > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From seefeld at sympatico.ca Fri Feb 16 18:08:47 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Fri, 16 Feb 2007 12:08:47 -0500 Subject: [C++-sig] PyFinalize Safety In-Reply-To: <006a01c751eb$b8e75040$6c01a8c0@paul> References: <006a01c751eb$b8e75040$6c01a8c0@paul> Message-ID: <45D5E51F.5070200@sympatico.ca> Paul Guse wrote: > Not sure if this solution/hack will work for you, but a quasi way to > reinitialize the interpreter is to clear the main dictionary to the original > state: > > - make a copy of the main dictionary upon initialization > - run your python script > - clear the main dictionary > - set the dictionary to the original copy. When reading the original posting I wondered about the reason for wanting to reinitialize the python runtime. Your reply makes me even more curious. What do you mean by the 'main dictionary' ? Each call to boost::python::exec_file can take a new dictionary, making the individual invocations completely independent, can't it ? > Some code: > > object main_module (handle<> (borrowed (PyImport_AddModule > ("__main__")))) ; > object dictionary = main_module.attr ("__dict__") ; > > // copy the dictionary > PyObject* clean_dict = PyDict_Copy (dictionary.ptr()) ; > > // run your python script. > > // reset main dictonary > PyDict_Clear (dictionary.ptr()) ; > PuDict_Update (dictionary.ptr(), clean_dict) ; > Py_XDECREF (clean_dict) ; (nit-picking: all the above could be written using only boost.python) Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From paul at mustagh.com Fri Feb 16 19:18:05 2007 From: paul at mustagh.com (Paul Guse) Date: Fri, 16 Feb 2007 11:18:05 -0700 Subject: [C++-sig] PyFinalize Safety References: <006a01c751eb$b8e75040$6c01a8c0@paul> <45D5E51F.5070200@sympatico.ca> Message-ID: <009a01c751f6$cf20b3a0$6c01a8c0@paul> > Stefan wrote: >> Not sure if this solution/hack will work for you, but a quasi way to >> reinitialize the interpreter is to clear the main dictionary to the >> original >> state: >> >> - make a copy of the main dictionary upon initialization >> - run your python script >> - clear the main dictionary >> - set the dictionary to the original copy. > > When reading the original posting I wondered about the reason for wanting > to > reinitialize the python runtime. Your reply makes me even more curious. > > What do you mean by the 'main dictionary' ? Each call to > boost::python::exec_file > can take a new dictionary, making the individual invocations completely > independent, > can't it ? > By main dictionary I mean the "__dict__" attribute to the main module. Checking the documentation, exec/exec_file seems like the way to go, however, I can't actually find exec.hpp or import.hpp in my boost build. I'm using 1_33_1 and used the installer(win) from boost.consulting. Any thoughts on why I would not have those 2 headers? Newer version? My version of python.hpp does not include those files as well. Is this a new feature? The solution I proposed came about due to the main module namespace retaining enties in it's _dict_ upon successive sessions (embeded). So if I run the example code without clearing and updating the dictionary, then variables defined in once session will persist to the next. I'm eager to try your solution. >> Some code: >> >> object main_module (handle<> (borrowed (PyImport_AddModule >> ("__main__")))) ; >> object dictionary = main_module.attr ("__dict__") ; >> >> // copy the dictionary >> PyObject* clean_dict = PyDict_Copy (dictionary.ptr()) ; >> >> // run your python script. >> >> // reset main dictonary >> PyDict_Clear (dictionary.ptr()) ; >> PuDict_Update (dictionary.ptr(), clean_dict) ; >> Py_XDECREF (clean_dict) ; > > (nit-picking: all the above could be written using only boost.python) That it should be :) > > Regards, > Stefan > > -- > > ...ich hab' noch einen Koffer in Berlin... > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From seefeld at sympatico.ca Fri Feb 16 19:24:33 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Fri, 16 Feb 2007 13:24:33 -0500 Subject: [C++-sig] PyFinalize Safety In-Reply-To: <009a01c751f6$cf20b3a0$6c01a8c0@paul> References: <006a01c751eb$b8e75040$6c01a8c0@paul> <45D5E51F.5070200@sympatico.ca> <009a01c751f6$cf20b3a0$6c01a8c0@paul> Message-ID: <45D5F6E1.20205@sympatico.ca> Paul Guse wrote: > By main dictionary I mean the "__dict__" attribute to the main module. > Checking the documentation, exec/exec_file seems like the way to go, > however, I can't actually find exec.hpp or import.hpp in my boost build. I'm > using 1_33_1 and used the installer(win) from boost.consulting. Any thoughts > on why I would not have those 2 headers? Newer version? My version of > python.hpp does not include those files as well. Is this a new feature? I only added that code 1 1/2 years ago. Not enough time to make it into a release yet. > The solution I proposed came about due to the main module namespace > retaining enties in it's _dict_ upon successive sessions (embeded). > So if I run the example code without clearing and updating the dictionary, > then variables defined in once session will persist to the next. > I'm eager to try your solution. You don't have to use the main dictionary. I believe you may create a new one, as long as you make sure that all the required builtin objects are there (copied from the main one, probably). HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From paul at mustagh.com Fri Feb 16 20:15:26 2007 From: paul at mustagh.com (Paul Guse) Date: Fri, 16 Feb 2007 12:15:26 -0700 Subject: [C++-sig] PyFinalize Safety References: <006a01c751eb$b8e75040$6c01a8c0@paul> <45D5E51F.5070200@sympatico.ca><009a01c751f6$cf20b3a0$6c01a8c0@paul> <45D5F6E1.20205@sympatico.ca> Message-ID: <00ab01c751fe$d277d440$6c01a8c0@paul> > Stefan wrote: > >> By main dictionary I mean the "__dict__" attribute to the main module. >> Checking the documentation, exec/exec_file seems like the way to go, >> however, I can't actually find exec.hpp or import.hpp in my boost build. >> I'm >> using 1_33_1 and used the installer(win) from boost.consulting. Any >> thoughts >> on why I would not have those 2 headers? Newer version? My version of >> python.hpp does not include those files as well. Is this a new feature? > > I only added that code 1 1/2 years ago. Not enough time > to make it into a release yet. > >> The solution I proposed came about due to the main module namespace >> retaining enties in it's _dict_ upon successive sessions (embeded). >> So if I run the example code without clearing and updating the >> dictionary, >> then variables defined in once session will persist to the next. >> I'm eager to try your solution. > > You don't have to use the main dictionary. I believe you may create a new > one, as long as you make sure that all the required builtin objects are > there (copied from the main one, probably). > That's much better. Using a copy of the main dictionary is much cleaner. Thanks for your help Stefan. > HTH, > Stefan > > -- > > ...ich hab' noch einen Koffer in Berlin... > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From dwolfe at gforcetech.com Sun Feb 18 16:04:24 2007 From: dwolfe at gforcetech.com (Dave Wolfe) Date: Sun, 18 Feb 2007 10:04:24 -0500 Subject: [C++-sig] PyFinalize Safety In-Reply-To: References: Message-ID: Stefan Seefeld mentioned in a previous thread (see 'PyFinalize Safety'): > (nit-picking: all the above could be written using only boost.python) > You don't have to use the main dictionary. I believe you may create a > new one, as long as you make sure that all the required builtin > objects are there (copied from the main one, probably). I have a somewhat related question. I have a function to create python objects that looks like this: bpl::object CreatePythonCallable(const char* fileName, const char* className) { try { bpl::object main = bpl::import("__main__"); bpl::object global = main.attr("__dict__"); bpl::exec_file(fileName, global, global); bpl::object ClassType = global[className]; bpl::object retval = ClassType(); return retval; } catch (bpl::error_already_set const&) { std::cerr << GetPythonException(); } return bpl::object(); // <-- return 'None' } This works fine, except that test blocks in my code that look like this: if __name__ == '__main__': DoTests() get executed when run from C++. How do I arrange for the code to be executed in another context, using only boost.python calls? From seefeld at sympatico.ca Sun Feb 18 16:18:16 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Sun, 18 Feb 2007 10:18:16 -0500 Subject: [C++-sig] PyFinalize Safety In-Reply-To: References: Message-ID: <45D86E38.3050207@sympatico.ca> Dave Wolfe wrote: > I have a somewhat related question. I have a function to create python > objects that looks like this: > > bpl::object CreatePythonCallable(const char* fileName, > const char* className) > { > try { > bpl::object main = bpl::import("__main__"); > bpl::object global = main.attr("__dict__"); > bpl::exec_file(fileName, global, global); > bpl::object ClassType = global[className]; > bpl::object retval = ClassType(); > return retval; > } > catch (bpl::error_already_set const&) { > std::cerr << GetPythonException(); > } > > return bpl::object(); // <-- return 'None' > } > > This works fine, except that test blocks in my code that look like this: > > if __name__ == '__main__': > DoTests() > > get executed when run from C++. How do I arrange for the code to be > executed in another context, using only boost.python calls? The bpl::exec_file(filename) call is similar to calling 'python filename' in a shell. Thus, __name__ is indeed set to __main__. If you don't want that, you should execute a different script that imports your module, thereby not acting in stand-alone mode. (Reading in the whole file into string and then using bpl::exec() instead of bpl::exec_file() may work, too. I'm not sure.) HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From tom.klipps at arivis.com Mon Feb 19 11:29:50 2007 From: tom.klipps at arivis.com (Tom Klipps) Date: Mon, 19 Feb 2007 11:29:50 +0100 Subject: [C++-sig] Using boost::python in an /clr application Message-ID: Hi everyone! I'm embedding a python interpreter in an /clr application using visual studio 2005. For the most simple example I created a new CLR console application using the visual studio project wizard and added a few lines of code resulting in the following .cpp file. // CRLConsoleApp.cpp : main project file. #include "stdafx.h" // include as unmanaged and disable warnings for __fastcall #pragma unmanaged #pragma warning(disable:4561) #include #pragma warning(default:4561) #pragma managed // just a simple function int sampleFunction() { return 42; } // initialize a sample modul void initSampleModul() { boost::python::def("sampleFunction",sampleFunction); } int main(array ^args) { return 0; } This works perfectly fine, I can compile it, I can link it, I can run it, I can use the sample function in a python script running in an embedded python interpreter. Exposing a class to python is not working quite as I want it to. I change the above .cpp file to include to following lines of code. // most simple class to expose to python class SampleClass { }; // initialize the sample modul exposing the sample class void initSampleModul() { boost::python::class_("SampleClass"); } using the above code gives me two linking errors: error LNK2020: unresolved token (06000007) boost.python.handle<_object>:: error LNK2020: unresolved token (06000008) boost.python.handle<_object>:: The version of boost I'm using here is 1.33.1 which was build using the VC_80 tools and I'm using Python version 2.5. The above visual studio project is linked to boost_python-vc80-mt-1_33_1.lib and python25.lib I've done the very same thing (linking to the same .lib files using mostly the same code except /clr specific parts) in a win32 console application and exposing the sample class to python works as expected. I can use the class in my embedded python interpreter.... just doing that in an CLR application is not working. I'm very thankful for any help I can get! best regards, Tom From ypodpruzhnikov at mcode.ru Mon Feb 19 12:29:50 2007 From: ypodpruzhnikov at mcode.ru (Podpruzhnikov Yuri) Date: Mon, 19 Feb 2007 14:29:50 +0300 Subject: [C++-sig] PyFinalize Safety Message-ID: Accept my apologies for my wrong describing the problem, in my previous post. I'll try to describe it in another way. The interpreter is completely embedded into our program, that's why interpreter is only finalized during program termination. And our program will work permanently for 24 hours a day, 7 days a week. The program executes Python scripts from time to time. Everything described above makes next problems: 1) It increases amount of memory allocated for the program, after every script execution: + Executed scripts always stays in memory as modules. + If any exceptions are raised some local context objects doesn't delete from memory, even if used garbage collection. 2) Improper scripts changing data in sys-module (or any other common using modules) may influence on next scripts execution. In that way the simplest decision of this problem is periodical runtime reinitialization of Python interpreter. "__main__"-dictionary cleaning solves only the first part of problem, but it doesn't solve the other one. The general problem of reinitialization of Python (with Boost.Python) is next: After calling PyFinalize and then PyInitialize and trying to import extension C++ modules many errors occur. The same problem is described in http://mail.python.org/pipermail/c++-sig/2004-April/007147.html. ----- Original Message ----- From: "Podpruzhnikov Yuri" To: Sent: Thursday, February 15, 2007 7:56 AM Subject: [C++-sig] PyFinalize Safety > We embed Python to our project and use Boost.Python. Very much code > had been already created. But great problem came to us: python > interpreter must be reinitialized, but Boost.Python doesn't support > "PyFinalize Safety" > (http://www.boost.org/libs/python/todo.html#pyfinalize-safety) > > I see 2 decisions of the problem: > 1) We delete Boost.Python from our project. But this will make > extension of Python very difficult. :) > 2) We write (or find) "PyFinalize Safety" of Boost.Python. > > I choose 2-nd decision till now. But if it is very difficult, I'll > choose the 1-st way of solving the problem. I have a few questions to > ask: > - What is the difficulty of this problem to be solved? > - Have anyone already written this? > - If yes, could you give me code or advice at least? > From roman.yakovenko at gmail.com Tue Feb 20 12:16:36 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 20 Feb 2007 13:16:36 +0200 Subject: [C++-sig] new call policy - return_range Message-ID: <7465b6170702200316p1e29e3d7mb677821b50ede891@mail.gmail.com> Hi all. I created new and cool call policy: return_range. Class return_range is a model of CallPolicies, which can be used to wrap C++ functions that return a pointer to some array. The new call policy constructs object, which provides a regular Python sequence interface. For more information refer to documentation: http://language-binding.net/pyplusplus/documentation/functions/call_policies.html#return-range -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From meine at informatik.uni-hamburg.de Tue Feb 20 12:59:49 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Tue, 20 Feb 2007 12:59:49 +0100 Subject: [C++-sig] new call policy - return_range In-Reply-To: <7465b6170702200316p1e29e3d7mb677821b50ede891@mail.gmail.com> References: <7465b6170702200316p1e29e3d7mb677821b50ede891@mail.gmail.com> Message-ID: <200702201259.51371.meine@informatik.uni-hamburg.de> Hi! Am Dienstag, 20. Februar 2007 12:16 schrieb Roman Yakovenko: > Class return_range is a model of CallPolicies, which can be used to > wrap C++ functions that return a pointer to some array. The new call > policy constructs object, which provides a regular Python sequence > interface. Interesting. (Why) Is the second template parameter (TValueType) necessary? Are there cases where it is != the dereferenced pointer type? Greetings, Hans From roman.yakovenko at gmail.com Tue Feb 20 18:18:44 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 20 Feb 2007 19:18:44 +0200 Subject: [C++-sig] new call policy - return_range In-Reply-To: <200702201259.51371.meine@informatik.uni-hamburg.de> References: <7465b6170702200316p1e29e3d7mb677821b50ede891@mail.gmail.com> <200702201259.51371.meine@informatik.uni-hamburg.de> Message-ID: <7465b6170702200918v7982924cufe7c278fda48e514@mail.gmail.com> On 2/20/07, Hans Meine wrote: > Hi! > > Am Dienstag, 20. Februar 2007 12:16 schrieb Roman Yakovenko: > > Class return_range is a model of CallPolicies, which can be used to > > wrap C++ functions that return a pointer to some array. The new call > > policy constructs object, which provides a regular Python sequence > > interface. > > Interesting. (Why) Is the second template parameter (TValueType) necessary? > Are there cases where it is != the dereferenced pointer type? No, but Boost.Python call policies class does not provide that information. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From ajfrantz at umich.edu Wed Feb 21 06:11:14 2007 From: ajfrantz at umich.edu (AJ Frantz) Date: Wed, 21 Feb 2007 00:11:14 -0500 Subject: [C++-sig] Instantiating class_<> objects without use of an interpreter? Message-ID: <161778e60702202111i5aa6ac11m556de19da5a7ecf0@mail.gmail.com> Hi all, Let me start by saying how amazing Boost.Python is. I've loved all of Boost from the day I learned about it, and Boost.Python has only improved my opinion of the libraries. I have an issue that's been plaguing me for long enough that I'm going to defer to the wisdom of someone here, though. I have an extension written in Boost.Python where several class_<> instances are passed back into Python as more generic object's (think return type "object"). I now have developed a need to remove Python from the equation entirely in some instances, however keep backward compatibility--that is, use the same code in Python, but occasionally develop a client application entirely in C++. The *problem* as that it appears to me is that instantiating class_<> objects causes a segfault when there isn't a Python interpreter involved somewhere. I've tried to trace back through the flow of execution, but I'm afraid I haven't succeeded. A code example will probably clarify what I mean: let me paste a small sample of something akin to the interface that I have to work with... I'll put them at the bottom of the message. DataTypes.h/cpp compiles just fine to DataTypes.so, imports into Python cleanly and works exactly as I would expect. However if I compile cppClient.cpp into an executable it segfaults at the first makeSomething() call. I believe the problem is related to the lack of a Python interpreter somewhere... does that sound correct? If so, can I get around it? If not, do you have any other guesses? Is use of Boost.Python like this even possible? Thanks in advance for any input, AJ Frantz Here's the long, nasty, netiquette-unfriendly source code dump: DataTypes.h --------------------------------------- #pragma once class OneDataType { public: OneDataType(int one) : mOne(one) {} int someFunc() { return mOne; } private: int mOne; }; class SomeOtherDataType { public: SomeOtherDataType(double someother) : mSomeOther(someother) {} double otherFunc() { return mSomeOther; } private: double mSomeOther; }; class SomeFactoryClass { public: virtual object makeSomething() = 0; }; class OneFactory : public SomeFactoryClass { public: object makeSomething(); }; class SomeOtherFactory : public SomeFactoryClass { public: object makeSomething(); }; --------------------------------------- DataTypes.cpp --------------------------------------- #include #include using namespace std; using namespace boost::python; #include "test.h" object OneFactory::makeSomething() { object PyOneDataType = class_("OneDataType", init()) .def("someFunc", &OneDataType::someFunc); object o = PyOneDataType(42); return o; } object SomeOtherFactory::makeSomething() { object PySomeOtherDataType = class_("SomeOtherDataType", init()) .def("otherFunc", &SomeOtherDataType::otherFunc); object o = PySomeOtherDataType(3.1415926); return o; } BOOST_PYTHON_MODULE(DataTypes) { class_("OneDataType", init()) .def("someFunc", &OneDataType::someFunc); class_("SomeOtherDataType", init()) .def("otherFunc", &SomeOtherDataType::otherFunc); class_("SomeFactoryClass", no_init); class_ >("OneFactory") .def("makeSomething", &OneFactory::makeSomething); class_ >("SomeOtherFactory") .def("makeSomething", &SomeOtherFactory::makeSomething); } --------------------------------------- cppClient.cpp --------------------------------------- #include #include using namespace std; using namespace boost::python; #include "test.h" int main(int argc, char *argv[]) { cout << "Making factories..." << endl; OneFactory of; SomeOtherFactory sof; cout << "Calling makeSomething on OneFactory..." << endl; // Segfault at this line. object o = of.makeSomething(); cout << "Extracting C++ object." << endl; OneDataType odt = extract(o); cout << "Calling makesomething on SomeOtherFactory..." << endl; o = sof.makeSomething(); cout << "Extracting C++ object." << endl; SomeOtherDataType sodt = extract(o); return 0; } --------------------------------------- From ypodpruzhnikov at mcode.ru Wed Feb 21 12:50:20 2007 From: ypodpruzhnikov at mcode.ru (Podpruzhnikov Yuri) Date: Wed, 21 Feb 2007 14:50:20 +0300 Subject: [C++-sig] Instantiating class_<> objects without use of aninterpreter? - Bayesian Filter detected spam Message-ID: My decision of this problem is (it may be is not best): 1)Declare all class_<> only in module definition (BOOST_PYTHON_MODULE(DataTypes){...}): BOOST_PYTHON_MODULE(DataTypes) { class_("OneDataType", init()) .def("someFunc", &OneDataType::someFunc); class_("SomeFactoryClass", no_init); class_ >("OneFactory") .def("makeSomething", &OneFactory::makeSomething); } 2) Write this in all factories next code: object OneFactory::makeSomething() { return object(OneDataType(42)); } ATTENTION: Definition of class_ always must be before create object(OneDataType(42)) If class_ and function, which create object(OneDataType(42)), declared in one module - all right But its declared in different modules - module contain class_ must be imported before module contain function, which create object(OneDataType(42)) From ajfrantz at umich.edu Wed Feb 21 15:21:34 2007 From: ajfrantz at umich.edu (AJ Frantz) Date: Wed, 21 Feb 2007 09:21:34 -0500 Subject: [C++-sig] Instantiating class_<> objects without use of aninterpreter? - Bayesian Filter detected spam In-Reply-To: References: Message-ID: <161778e60702210621o23671d68gd16f85c119df8a9d@mail.gmail.com> Your "attention" notes at the bottom are all good policies, to be sure. However, I've tried placing the class_<> definitions in many places, as well as replicating it throughout the code, thinking that was somehow involved. I think I was closer with my initial assessment: the problem is the Python interpreter is not initialized. If you use my code from my original posting, but simply add a call to Py_Initialize() to the beginning of main(), everything seems to work, no errors... I'm not sure why it took me this long to try that. Does anyone see problems with this method? I'll probably be embedding Python at some point so it is perhaps not the worst alternative. AJ On 2/21/07, Podpruzhnikov Yuri wrote: > My decision of this problem is (it may be is not best): > > > 1)Declare all class_<> only in module definition > (BOOST_PYTHON_MODULE(DataTypes){...}): > BOOST_PYTHON_MODULE(DataTypes) > { > class_("OneDataType", init()) > .def("someFunc", &OneDataType::someFunc); > > class_("SomeFactoryClass", > no_init); > > class_ >("OneFactory") > .def("makeSomething", > &OneFactory::makeSomething); > } > > 2) Write this in all factories next code: > object OneFactory::makeSomething() > { > return object(OneDataType(42)); > } > > > > ATTENTION: > Definition of class_ always must be before create > object(OneDataType(42)) > > If class_ and function, which create > object(OneDataType(42)), declared in one module - all right > But its declared in different modules - > module contain class_ must be imported before > module contain function, which create object(OneDataType(42)) > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > From kanand at qualcomm.com Wed Feb 21 21:44:07 2007 From: kanand at qualcomm.com (Anand, Kumar) Date: Wed, 21 Feb 2007 12:44:07 -0800 Subject: [C++-sig] Py++: Memory Ownership Passing Message-ID: How can I pass the memory ownership of a Derived class object (created in Python) to C++ though an interface that takes a Base class pointer? Does the function transformer in Py++ tackle this use case? ---------------------------------------------------------- Scenario: There is a class 'Base' and a derived class 'Derived' that extends from 'Base'. Both the classes have been exposed to Python. Class Base {}; Class Derived: public Base {}; bp::class_< Base > ("Base " ) .def( bp::init< >() ); bp::class_< Derived, bp::bases< Base > > ("Derived " ) .def( bp::init< >() ); Now I have a C++ function f that has also been exposed to python: void func (Base class * ptr) { //this function takes memory ownership of the passed object and does say delete ptr; } Assume all the above bindings have been exposed in the Boost_Test module and I have the following python code: import Boost_Test d = Boost_Test.Derived() Boost_Test.func(d); //This finally causes the interpreter to crash because of double deletion of object 'd' --------------------------------------------------------------- Specifying the 'held_type' for Derived class as std::auto_ptr and writing a wrapper function for 'func' that takes a std::auto_ptr as argument does not work. Thanks Kumar -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Wed Feb 21 21:54:52 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 21 Feb 2007 22:54:52 +0200 Subject: [C++-sig] Py++: Memory Ownership Passing In-Reply-To: References: Message-ID: <7465b6170702211254w7c0c6008iaecb3a943ef8d260@mail.gmail.com> On 2/21/07, Anand, Kumar wrote: > How can I pass the memory ownership of a Derived class object (created in > Python) to C++ though an interface that takes a Base class pointer? Does the > function transformer in Py++ tackle this use case? > > ---------------------------------------------------------- > > Scenario: There is a class 'Base' and a derived class 'Derived' that extends > from 'Base'. Both the classes have been exposed to Python. > > Class Base {}; > > Class Derived: public Base {}; > > bp::class_< Base > ("Base " ) > > .def( bp::init< >() ); > > bp::class_< Derived, bp::bases< Base > > ("Derived " ) > > .def( bp::init< >() ); > > Now I have a C++ function f that has also been exposed to python: > > void func (Base class * ptr) > > { > > //this function takes memory ownership of the passed object and does say > delete ptr; > > } > > Assume all the above bindings have been exposed in the Boost_Test module and > I have the following python code: > > import Boost_Test > > d = Boost_Test.Derived() > > Boost_Test.func(d); > > //This finally causes the interpreter to crash because of double deletion of > object 'd' > > --------------------------------------------------------------- > > Specifying the 'held_type' for Derived class as std::auto_ptr and writing a > wrapper function for 'func' that takes a std::auto_ptr as argument > does not work. Please read this thread: https://sourceforge.net/mailarchive/forum.php?thread_id=31679293&forum_id=47898 It deals with almost identical situation. You should be able to find the answers to your questions in it. Also take a look on "transfer_ownership" function transformation documentation: http://language-binding.net/pyplusplus/documentation/functions/transformation/built_in/transfer_ownership.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From kanand at qualcomm.com Wed Feb 21 23:26:34 2007 From: kanand at qualcomm.com (Anand, Kumar) Date: Wed, 21 Feb 2007 14:26:34 -0800 Subject: [C++-sig] Py++: Memory Ownership Passing In-Reply-To: <7465b6170702211254w7c0c6008iaecb3a943ef8d260@mail.gmail.com> Message-ID: Ok, I have tried the following but it doesn't work. 1) Exposed class 'Base' as follows: bp::class_< Base, std::auto_ptr< Base > > ("Base" ) .def( bp::init< >() ); 1) Exposed class 'Derived' as follows: bp::class_< Derived, bp::bases< Base >, std::auto_ptr< Derived > > ("Derived" ) .def( bp::init< >() ); 2) Created the func_wrapper as follows and exposed it to python as 'func' Void func_wrapper (std::auto_ptr b) { func.(b.get()); b.release() } Now In Python when I do this: import Boost_Test d = Boost_Test.Derived() Boost_Test.func(d); Above code throws an error because of C++ signature mismatch. I am trying to pass a std::auto_ptrto a std::auto_ptr. How to solve this problem? Thanks Kumar -----Original Message----- From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On Behalf Of Roman Yakovenko Sent: Wednesday, February 21, 2007 12:55 PM To: Development of Python/C++ integration Subject: Re: [C++-sig] Py++: Memory Ownership Passing On 2/21/07, Anand, Kumar wrote: > How can I pass the memory ownership of a Derived class object (created in > Python) to C++ though an interface that takes a Base class pointer? Does the > function transformer in Py++ tackle this use case? > > ---------------------------------------------------------- > > Scenario: There is a class 'Base' and a derived class 'Derived' that extends > from 'Base'. Both the classes have been exposed to Python. > > Class Base {}; > > Class Derived: public Base {}; > > bp::class_< Base > ("Base " ) > > .def( bp::init< >() ); > > bp::class_< Derived, bp::bases< Base > > ("Derived " ) > > .def( bp::init< >() ); > > Now I have a C++ function f that has also been exposed to python: > > void func (Base class * ptr) > > { > > //this function takes memory ownership of the passed object and does say > delete ptr; > > } > > Assume all the above bindings have been exposed in the Boost_Test module and > I have the following python code: > > import Boost_Test > > d = Boost_Test.Derived() > > Boost_Test.func(d); > > //This finally causes the interpreter to crash because of double deletion of > object 'd' > > --------------------------------------------------------------- > > Specifying the 'held_type' for Derived class as std::auto_ptr and writing a > wrapper function for 'func' that takes a std::auto_ptr as argument > does not work. Please read this thread: https://sourceforge.net/mailarchive/forum.php?thread_id=31679293&forum_i d=47898 It deals with almost identical situation. You should be able to find the answers to your questions in it. Also take a look on "transfer_ownership" function transformation documentation: http://language-binding.net/pyplusplus/documentation/functions/transform ation/built_in/transfer_ownership.html -- 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 From gjcarneiro at gmail.com Wed Feb 21 23:45:12 2007 From: gjcarneiro at gmail.com (Gustavo Carneiro) Date: Wed, 21 Feb 2007 22:45:12 +0000 Subject: [C++-sig] Py++: Memory Ownership Passing In-Reply-To: References: <7465b6170702211254w7c0c6008iaecb3a943ef8d260@mail.gmail.com> Message-ID: On 2/21/07, Anand, Kumar wrote: > > Ok, I have tried the following but it doesn't work. > > 1) Exposed class 'Base' as follows: > bp::class_< Base, std::auto_ptr< Base > > ("Base" ) > .def( bp::init< >() ); > 1) Exposed class 'Derived' as follows: > bp::class_< Derived, bp::bases< Base >, std::auto_ptr< > Derived > > ("Derived" ) > .def( bp::init< >() ); > 2) Created the func_wrapper as follows and exposed it to python as > 'func' > Void func_wrapper (std::auto_ptr b) > { > func.(b.get()); > b.release() > } > > Now In Python when I do this: > import Boost_Test > d = Boost_Test.Derived() > Boost_Test.func(d); > > Above code throws an error because of C++ signature mismatch. I am > trying to pass a std::auto_ptrto a std::auto_ptr. How to > solve this problem? In Py++ code I think it's something like this: mb.class_('Base').add_registration_code( "boost::python::implicitly_convertible<" " std::auto_ptr< Derived >," " std::auto_ptr< Base > >();", False) However, if you have the same problem as I do then you will find out that all these std::auto_ptr hacks will not solve the memory error in the end. I have been trying to solve the exact same problem for a few days now... :-( -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." -------------- next part -------------- An HTML attachment was scrubbed... URL: From gjcarneiro at gmail.com Thu Feb 22 00:53:03 2007 From: gjcarneiro at gmail.com (Gustavo Carneiro) Date: Wed, 21 Feb 2007 23:53:03 +0000 Subject: [C++-sig] [pygccxml-development] Parameter passing, ownership semantics In-Reply-To: References: <7465b6170702181156l6d7b22dck3e2146a1d6be401c@mail.gmail.com> <7465b6170702182141q2a78c9acree28917f321ab084@mail.gmail.com> <7465b6170702191104g42578988w35c6a79490d78851@mail.gmail.com> Message-ID: On 2/20/07, Gustavo Carneiro wrote: > > On 2/19/07, Roman Yakovenko wrote: > > > > Hi. Unfortunately I reproduced the error and was not able to fix it > > :-(((((. > > There is something I don't understand and I think this is > > Boost.Python bug. > > > > I do made some progress. > > > > 1. When you derive Python class from a C++ one you have to define > > __init__ > > method, otherwise your code will not work: > > > > class MyEvent(EventImpl): > > def __init__( self ): > > EventImpl.__init__( self ) > > > > def Notify(self): > > print "Notify!" > > > > 2. I did small research for you. Read this post: > > http://aspn.activestate.com/ASPN/Mail/Message/cpp-sig/1331901 > > and take a look on Boost.Python unit tests: > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.cpp?view=markup > > > > http://boost.cvs.sourceforge.net/boost/boost/libs/python/test/auto_ptr.py?view=markup > > > > > > What I found is: > > The ownership is really transfered. You can check this using simple > > technique: > > Add new function to EventImpl: > > virtual std::string class_name() const { return "EventImpl"; } > > Add free function: > > std::string get_class_name( const std::auto_ptr& e > > ){ > > if( e.get() ){ > > return e->class_name(); > > } > > else{ > > return "no object"; > > } > > } > > You will get the answer "no object", after "Schedule" call. > > So, may be you don't have to delete the Python object. > > > > I will submit the bug to the Boost.Python mailing list, hope somebody > > will be able to help. > > > I found this wiki with a possible solution for the problem: > > http://wiki.python.org/moin/boost.python/HowTo#head-927c9493ac51c81b3f2484e486d85567ff316c8a > > Good news. That wiki entry didn't apply anymore probably due to changing boost::python interfaces, but it provided very useful clues. I managed to get it working 100% correctly using another hack. Here's the diff of the manual changes I made to the wrapper: --- ns3.cpp 2007-02-21 23:46:44.000000000 +0000 +++ ns3-working.cpp 2007-02-21 23:44:34.000000000 +0000 @@ -9,19 +9,32 @@ namespace bp = boost::python; struct EventImpl_wrapper : ns3::EventImpl, bp::wrapper< ns3::EventImpl > { + ~EventImpl_wrapper() { + if (this->pyobj) { + Py_DECREF(this->pyobj); + this->pyobj = 0; + } + + } EventImpl_wrapper() : ns3::EventImpl() - , bp::wrapper< ns3::EventImpl >(){ - // null constructor + , bp::wrapper< ns3::EventImpl > (), pyobj(0) { } virtual void Notify( ){ + if (!this->pyobj) { + this->pyobj = bp::detail::wrapper_base_::get_owner(*this); + Py_INCREF(this->pyobj); + } bp::override func_Notify = this->get_override( "Notify" ); func_Notify( ); } +protected: + PyObject *pyobj; + }; static void Schedule_b8544467c482930a621aca2e7ac87dca( std::auto_ptr< ::ns3::EventImpl > event ){ Now my question, especially to any boost_python maintainers out there, can you please do something about this? I shouldn't have to make these kinds of hacks to get it working; any chance this INCREF/DECREF of the PyObject can make it upstream to the standard boost distribution? -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." -------------- next part -------------- An HTML attachment was scrubbed... URL: From kanand at qualcomm.com Thu Feb 22 04:06:04 2007 From: kanand at qualcomm.com (Anand, Kumar) Date: Wed, 21 Feb 2007 19:06:04 -0800 Subject: [C++-sig] Py++: Memory Ownership Passing In-Reply-To: Message-ID: Thanks! Registering the implicit converter worked. I am now able to transfer the ownership of Derived class object from python to C++ via an interface that takes a Base class pointer. Gustavo, please see the following complete code snippet. 1) Exposed class 'Base' as follows: bp::class_< Base, std::auto_ptr< Base > > ("Base" ) .def( bp::init< >() ); 2) Exposed class 'Derived' as follows: bp::class_< Derived, bp::bases< Base >, std::auto_ptr > ("Derived" ) .def( bp::init< >() ); 3) Register the implicit converter boost::python::implicitly_convertible< std::auto_ptr< Derived >, std::auto_ptr< Base > >(); 4) Now assuming you have a 'func' function that takes a 'Base*' as argument and takes ownership of the object passed. And you want to expose this to python. i.e. void func (Base* ptr); Exposing the above function as it is, would not work because the object referred by ptr would be deleted twice (once in C++ inside 'func' and finally by Python Interpreter again). To pass the memory ownership from python to C++ and avoid double deletion, create the func_wrapper as follows and expose it to python as 'func' void func_wrapper (std::auto_ptr b) { func.(b.get()); b.release() // IMPORTANT !!! } Thanks Kumar ________________________________ From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On Behalf Of Gustavo Carneiro Sent: Wednesday, February 21, 2007 2:45 PM To: Development of Python/C++ integration Subject: Re: [C++-sig] Py++: Memory Ownership Passing On 2/21/07, Anand, Kumar wrote: Ok, I have tried the following but it doesn't work. 1) Exposed class 'Base' as follows: bp::class_< Base, std::auto_ptr< Base > > ("Base" ) .def( bp::init< >() ); 1) Exposed class 'Derived' as follows: bp::class_< Derived, bp::bases< Base >, std::auto_ptr< Derived > > ("Derived" ) .def( bp::init< >() ); 2) Created the func_wrapper as follows and exposed it to python as 'func' Void func_wrapper (std::auto_ptr b) { func.(b.get()); b.release() } Now In Python when I do this: import Boost_Test d = Boost_Test.Derived() Boost_Test.func(d); Above code throws an error because of C++ signature mismatch. I am trying to pass a std::auto_ptrto a std::auto_ptr. How to solve this problem? In Py++ code I think it's something like this: mb.class_('Base').add_registration_code( "boost::python::implicitly_convertible<" " std::auto_ptr< Derived >," " std::auto_ptr< Base > >();", False) However, if you have the same problem as I do then you will find out that all these std::auto_ptr hacks will not solve the memory error in the end. I have been trying to solve the exact same problem for a few days now... :-( -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." -------------- next part -------------- An HTML attachment was scrubbed... URL: From gjcarneiro at gmail.com Thu Feb 22 11:50:56 2007 From: gjcarneiro at gmail.com (Gustavo Carneiro) Date: Thu, 22 Feb 2007 10:50:56 +0000 Subject: [C++-sig] Py++: Memory Ownership Passing In-Reply-To: References: Message-ID: On 2/22/07, Anand, Kumar wrote: > > Thanks! Registering the implicit converter worked. I am now able to > transfer the ownership of Derived class object from python to C++ via an > interface that takes a Base class pointer. > Well, it doesn't work if you transfer ownership _and_ call a C++ method wich then calls a virtual method on your object that is realized in Python. Here, check for yourself by compiling the module in attachment with: g++ -shared -fPIC -DPIC -I /usr/include/python2.5/ -lboost_python ns3.cpp -o ns3.so Then run the test program; you should get: $ python test-schedule.py Notify! Segmentation fault (core dumped) The solution appears to be to INCREF the PyObject*. I posted yesterday one possible, albeit hackish, way to do it with boost 1.33. -- Gustavo J. A. M. Carneiro "The universe is always one step beyond logic." -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: ns3.cpp Type: text/x-c++src Size: 1703 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: simulator.hpp Type: text/x-c++hdr Size: 513 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: test-schedule.py Type: text/x-python Size: 192 bytes Desc: not available URL: From ovchinnikovv at rustest.ru Thu Feb 22 12:36:14 2007 From: ovchinnikovv at rustest.ru (=?koi8-r?B?98/M0SDv197Jzs7Jy8/X?=) Date: Thu, 22 Feb 2007 14:36:14 +0300 Subject: [C++-sig] import module from string Message-ID: Hi all. Sorry for my English. In my c++ code I need to run a function from python module, but I have only a string with module body. Of course, I can save the module body into temporary file, use PyImport_Import, get the dictionary, get the function and run it. But I don't want to do it. Is the another way exist? -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Thu Feb 22 13:27:46 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 22 Feb 2007 07:27:46 -0500 Subject: [C++-sig] import module from string In-Reply-To: References: Message-ID: <45DD8C42.60303@sympatico.ca> ???? ?????????? wrote: > Hi all. > > > > Sorry for my English. > > > > In my c++ code I need to run a function from python module, but I have > only a string with module body. > > Of course, I can save the module body into temporary file, use > PyImport_Import, get the dictionary, get the function and run it. > > But I don?t want to do it. Is the another way exist? If I understand what you want correctly, the following (untested !) code should work: bpl::object module = bpl::import("your_module"); bpl::dict dict(module.attr("__dict__")); bpl::object function = dict["your_function"]; function(); HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From hans_meine at gmx.net Thu Feb 22 13:39:18 2007 From: hans_meine at gmx.net (Hans Meine) Date: Thu, 22 Feb 2007 13:39:18 +0100 Subject: [C++-sig] import module from string In-Reply-To: <45DD8C42.60303@sympatico.ca> References: <45DD8C42.60303@sympatico.ca> Message-ID: <200702221339.23426.hans_meine@gmx.net> On Thursday 22 February 2007, Stefan Seefeld wrote: > > In my c++ code I need to run a function from python module, but I have > > only a string with module body. > > > > Of course, I can save the module body into temporary file, use > > PyImport_Import, [...] > > bpl::object module = bpl::import("your_module"); > bpl::dict dict(module.attr("__dict__")); > bpl::object function = dict["your_function"]; > function(); If I understood the question correctly, he does not want to import a module, but he wants to execute code from a string which defines a function, *without* writing that string to disk for the above to work. Ciao, / / .o. /--/ ..o / / ANS ooo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From ypodpruzhnikov at mcode.ru Thu Feb 22 14:09:19 2007 From: ypodpruzhnikov at mcode.ru (Podpruzhnikov Yuri) Date: Thu, 22 Feb 2007 16:09:19 +0300 Subject: [C++-sig] import module from string Message-ID: Its "clear"-python (without boost) decision: Variables: psBufferWithScript - Buffer with Script text psFileName - FileName new module ("__file__") psModuleName - Name new module // Create CodeObject PyObject* CodeObject = Py_CompileString( psBufferWithScript, psFileName, Py_file_input); if (CodeObject == NULL) return false; // Import Python script if (PyImport_ExecCodeModule (psModuleName, CodeObject) == NULL) return false; From seefeld at sympatico.ca Thu Feb 22 14:43:00 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 22 Feb 2007 08:43:00 -0500 Subject: [C++-sig] import module from string In-Reply-To: <200702221339.23426.hans_meine@gmx.net> References: <45DD8C42.60303@sympatico.ca> <200702221339.23426.hans_meine@gmx.net> Message-ID: <45DD9DE4.5010205@sympatico.ca> Hans Meine wrote: > On Thursday 22 February 2007, Stefan Seefeld wrote: >>> In my c++ code I need to run a function from python module, but I have >>> only a string with module body. >>> >>> Of course, I can save the module body into temporary file, use >>> PyImport_Import, [...] >> bpl::object module = bpl::import("your_module"); >> bpl::dict dict(module.attr("__dict__")); >> bpl::object function = dict["your_function"]; >> function(); > > If I understood the question correctly, he does not want to import a module, > but he wants to execute code from a string which defines a function, > *without* writing that string to disk for the above to work. Ah, so I was misled by the use of 'module' in the OP. In that case, boost::python::exec() should do the job. (Sorry, can't paste a link to an example, as sourceforge appears to be down right now :-( ) HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From ndbecker2 at gmail.com Thu Feb 22 15:16:20 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 22 Feb 2007 09:16:20 -0500 Subject: [C++-sig] design question Message-ID: I'm interested in any ideas/opinions on the following. I am building c++ objects that are compositions of pieces. The composition is done from python. For example, class D has a member of type A, where A's behavior is tuned through polymorphism (traditional OO design). Let's say B and C are derived from A. Then, I can control this from python by: b = B() c = C() d1 = D (b) d2 = D (c) So this can be exposed as: ------------------------------- #include struct A { virtual void doit () = 0; }; struct B : public A { virtual void doit (); }; struct C { C (boost::shared_ptr _a) : a (_a) {} void doit() { a->doit(); } boost::shared_ptr a; }; BOOST_PYTHON_MODULE (test) { class_, boost::noncopyable> ("A", no_init); class_ > ("B"...); class_ ("C", init >); } ------------------------------ What I'm wondering is, is this a reasonable design? Could it be made significantly more efficient? From meine at informatik.uni-hamburg.de Thu Feb 22 15:43:43 2007 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Thu, 22 Feb 2007 15:43:43 +0100 Subject: [C++-sig] design question In-Reply-To: References: Message-ID: <200702221543.43524.meine@informatik.uni-hamburg.de> Am Donnerstag, 22. Februar 2007 15:16 schrieb Neal Becker: > I'm interested in any ideas/opinions on the following. I am building c++ > objects that are compositions of pieces. The composition is done from > python. > [...] > What I'm wondering is, is this a reasonable design? Could it be made > significantly more efficient? Looks OK to me - what exactly are you thinking about? -- Ciao, / / /--/ / / ANS From seefeld at sympatico.ca Thu Feb 22 15:50:51 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Thu, 22 Feb 2007 09:50:51 -0500 Subject: [C++-sig] design question In-Reply-To: References: Message-ID: <45DDADCB.6030907@sympatico.ca> Neal Becker wrote: > I'm interested in any ideas/opinions on the following. I am building c++ > objects that are compositions of pieces. The composition is done from > python. > > For example, class D has a member of type A, where A's behavior is tuned > through polymorphism (traditional OO design). Let's say B and C are > derived from A. Then, I can control this from python by: > > b = B() > c = C() > d1 = D (b) > d2 = D (c) Yes, that's certainly sensible. However, just to get this level of polymorphism you only need an abstract factory from python. The holding type 'D' doesn't need to be exposed to python for this to work. In fact, it doesn't have to know anything about python itself. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From ndbecker2 at gmail.com Thu Feb 22 17:51:50 2007 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 22 Feb 2007 11:51:50 -0500 Subject: [C++-sig] design question References: <200702221543.43524.meine@informatik.uni-hamburg.de> Message-ID: Hans Meine wrote: > Am Donnerstag, 22. Februar 2007 15:16 schrieb Neal Becker: >> I'm interested in any ideas/opinions on the following. I am building c++ >> objects that are compositions of pieces. The composition is done from >> python. >> [...] >> What I'm wondering is, is this a reasonable design? Could it be made >> significantly more efficient? > > Looks OK to me - what exactly are you thinking about? > I should have mentioned that both the pieces (a,b) and the larger object that composes them (D) need to be in c++. Without getting into too much detail, the use is a = algorithm_a() # both of these are algorithms written in c++ b = algorithm_b() d1 = D (a) # two D objects with different algorithms d2 = D (b) do_something_with (d1) do_something_with (d2) I guess I was wondering if the use of boost::shared_ptr would add even more overhead to the virtual function calls, and if there was a more efficient (but still easy) approach. From hans_meine at gmx.net Thu Feb 22 21:52:21 2007 From: hans_meine at gmx.net (Hans Meine) Date: Thu, 22 Feb 2007 21:52:21 +0100 Subject: [C++-sig] design question In-Reply-To: References: <200702221543.43524.meine@informatik.uni-hamburg.de> Message-ID: <200702222152.27178.hans_meine@gmx.net> On Thursday 22 February 2007, Neal Becker wrote: > I guess I was wondering if the use of boost::shared_ptr would add even more > overhead to the virtual function calls, and if there was a more efficient > (but still easy) approach. AFAICS it is worth using a shared_ptr<> just for the sake of easy refcounting and memory handling. If need calls to virtual functions at maximum speed, you could still store an /additional/ raw pointer. That *may* be worth it depending on what you algorithms do (e.g. if both just do "return 0;" or "return 42;") - IIRC shared_ptr::operator-> contains an assert that the pointer is != NULL. In case of -DNDEBUG I think it's "just" an additional indirection, which should be neglectable for most functions that contain non-trivial algorithms. Ciao, / / .o. /--/ ..o / / ANS ooo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available URL: From kanand at qualcomm.com Fri Feb 23 07:33:04 2007 From: kanand at qualcomm.com (Anand, Kumar) Date: Thu, 22 Feb 2007 22:33:04 -0800 Subject: [C++-sig] Py++: Exposing complex pointer members In-Reply-To: Message-ID: PY++ exposes class attributes that are 'pointers to complex types' automatically. But I see that it doesn't expose the 'setter' and only exposes the 'getter'. Why? Is their a way to control it and have it expose the setter as well? Right now I am manually adding the following registration code to expose both the setter and getter: .add_property("payload",bp::make_getter(&Pkt::payload, bp::return_internal_reference<1> ()), bp::make_setter(&Pkt::payload, bp::return_internal_reference<1> ())) where 'payload' is a pointer to some complex type inside the 'Pkt' class. Thanks Kumar ________________________________ -------------- next part -------------- An HTML attachment was scrubbed... URL: From pk at cs.tut.fi Fri Feb 23 13:55:42 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Fri, 23 Feb 2007 14:55:42 +0200 Subject: [C++-sig] Error when importing Boost.Python exposed module into embedded Python Message-ID: <45DEE44E.7020305@cs.tut.fi> I am trying to import a module containing exposed C++ classes into an embedded Python interpreter as follows: /* Initialize the Python interpreter */ Py_Initialize(); /* Execute some Python statements (in module __main__) */ PyRun_SimpleString("print 'Running Python'\n"); PyRun_SimpleString("import platform\n"); PyRun_SimpleString("print platform.python_version()\n"); PyRun_SimpleString("import TPEF\n"); This results in: Running Python 2.4.4 Fatal Python error: Interpreter not initialized (version mismatch?) The same module imports fine into a standalone Python: Python 2.4.4 (#3, Dec 21 2006, 12:46:16) [GCC 4.1.1] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import platform >>> print platform.python_version() 2.4.4 >>> import TPEF Any ideas? Is there something simple that I am missing? -- Pertti From pk at cs.tut.fi Fri Feb 23 14:48:53 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Fri, 23 Feb 2007 15:48:53 +0200 Subject: [C++-sig] Error when importing Boost.Python exposed module into embedded Python In-Reply-To: <45DEE44E.7020305@cs.tut.fi> References: <45DEE44E.7020305@cs.tut.fi> Message-ID: <45DEF0C5.9080408@cs.tut.fi> Pertti Kellom?ki kirjoitti: > Fatal Python error: Interpreter not initialized (version mismatch?) Never mind, turns out I had two copies of libpython2.4.a in my system. The Apple framework stuff gets me every time... -- Pertti From roman.yakovenko at gmail.com Fri Feb 23 19:15:01 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Fri, 23 Feb 2007 20:15:01 +0200 Subject: [C++-sig] Py++: Exposing complex pointer members In-Reply-To: References: Message-ID: <7465b6170702231015r17a6622as6713ea9fefdd8d67@mail.gmail.com> On 2/23/07, Anand, Kumar wrote: > PY++ exposes class attributes that are 'pointers to complex types' > automatically. But I see that it doesn't expose the 'setter' and only > exposes the 'getter'. Why? Is their a way to control it and have it expose > the setter as well? > > Right now I am manually adding the following registration code to expose > both the setter and getter: > > .add_property("payload",bp::make_getter(&Pkt::payload, > bp::return_internal_reference<1> ()), > > bp::make_setter(&Pkt::payload, > bp::return_internal_reference<1> ())) > > where 'payload' is a pointer to some complex type inside the 'Pkt' class. May be the generated code will compile and even work in **some** situations. But it definitely does not solve the general case. I think you need to read one more time call policies tutorials: http://boost.org/libs/python/doc/tutorial/doc/html/python/functions.html#python.call_policies -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From zzhao at laika.com Wed Feb 28 03:22:12 2007 From: zzhao at laika.com (ZiZi Zhao) Date: Tue, 27 Feb 2007 18:22:12 -0800 Subject: [C++-sig] make tuple of tuples in embedding python? Message-ID: In Python/C API PyTuple can have different types of items. For example, pTuple = PyTuple_New(3); PyTuple_SetItem(pTuple, 0, pString1); PyTuple_SetItem(pTuple, 1, pString2); PyTuple_SetItem(pTuple, 2, pDict); I would like to know if I can make tuple of tuples for embedding Python in C++. For example, pTuple0 = PyTuple_New(3); pTuple1 = PyTuple_New(3); pTuple2 = PyTuple_New(3); pTupleOfTuple = PyTuple_New(3); PyTuple_SetItem(pTupleOfTuple, 0, pTuple0); PyTuple_SetItem(pTupleOfTuple, 1, pTuple1); PyTuple_SetItem(pTupleOfTuple, 2, pTuple2); It seems the code can be compiled. But, it would crash as long as it starts running without any output info. So, I could not know what is wrong. Thanks in Advance, ZZ -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Wed Feb 28 03:59:53 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Tue, 27 Feb 2007 21:59:53 -0500 Subject: [C++-sig] make tuple of tuples in embedding python? In-Reply-To: References: Message-ID: <45E4F029.1080606@sympatico.ca> ZiZi Zhao wrote: > In Python/C API > PyTuple can have different types of items. For example, > > pTuple = PyTuple_New(3); > PyTuple_SetItem(pTuple, 0, pString1); > PyTuple_SetItem(pTuple, 1, pString2); > PyTuple_SetItem(pTuple, 2, pDict); > > I would like to know if I can make tuple of tuples for embedding Python > in C++. For example, > > pTuple0 = PyTuple_New(3); > pTuple1 = PyTuple_New(3); > pTuple2 = PyTuple_New(3); > > pTupleOfTuple = PyTuple_New(3); > > PyTuple_SetItem(pTupleOfTuple, 0, pTuple0); > PyTuple_SetItem(pTupleOfTuple, 1, pTuple1); > PyTuple_SetItem(pTupleOfTuple, 2, pTuple2); > > It seems the code can be compiled. But, it would crash as long as it > starts running without any output info. So, I could not know what is wrong. I'm not sure this answers your question, but since you ask on this particular list, here is how you do the above with boost.python: namespace bpl = boost::python; bpl::tuple t0 = bpl::make_tuple("hello", "world", bpl::dict()); bpl::tuple t1 = bpl::make_tuple("hi !", t0); HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From pk at cs.tut.fi Wed Feb 28 16:05:02 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Wed, 28 Feb 2007 17:05:02 +0200 Subject: [C++-sig] Importing into embedded Python Message-ID: <45E59A1E.4070105@cs.tut.fi> I'm having problems importing modules containing Boost.Python produced bindings into an embedded Python interpreter. The following compiles into a module that loads fine into a standalone Python: testing.hh: ------------------ class A { }; ------------------ testing.cpp ------------------ #include #include "testing.hh" using namespace boost::python; BOOST_PYTHON_MODULE(testing) { class_("A", init<>()) ; } ------------------- However, I get problems when I try to import the module into an embedded Python interpreter as follows: Py_Initialize(); PyRun_SimpleString("print 'Running Python'\n" "import testing\n" "print 'imported testing'\n" "a = testing.A() \n" "print 'a=', a \n"); The program outputs: Running Python imported testing Traceback (most recent call last): File "", line 4, in ? AttributeError: 'module' object has no attribute 'A' I've googled around and found several pages describing similar problems, but so far no solutions. My setup is OS X 10.4, Python 2.4.4 and GCC 4.1.1 if that is of any help. -- Pertti From mw8329 at yahoo.com.au Wed Feb 28 16:10:19 2007 From: mw8329 at yahoo.com.au (Martin Wille) Date: Wed, 28 Feb 2007 16:10:19 +0100 Subject: [C++-sig] Importing into embedded Python In-Reply-To: <45E59A1E.4070105@cs.tut.fi> References: <45E59A1E.4070105@cs.tut.fi> Message-ID: <45E59B5B.5060508@yahoo.com.au> Pertti Kellom?ki wrote: > I'm having problems importing modules containing > Boost.Python produced bindings into an embedded Python > interpreter. Incidently, I ran into the same problem yesterday. I solved it by calling inittesting() after Py_Initialize(). HTH, m Send instant messages to your online friends http://au.messenger.yahoo.com From seefeld at sympatico.ca Wed Feb 28 16:31:39 2007 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Wed, 28 Feb 2007 10:31:39 -0500 Subject: [C++-sig] Importing into embedded Python In-Reply-To: <45E59A1E.4070105@cs.tut.fi> References: <45E59A1E.4070105@cs.tut.fi> Message-ID: <45E5A05B.70902@sympatico.ca> Pertti Kellom?ki wrote: > I'm having problems importing modules containing > Boost.Python produced bindings into an embedded Python > interpreter. > > The following compiles into a module that loads fine > into a standalone Python: > > testing.hh: > ------------------ > class A { > }; > ------------------ > > testing.cpp > ------------------ > #include > #include "testing.hh" > > using namespace boost::python; > > BOOST_PYTHON_MODULE(testing) { > class_("A", init<>()) > ; > } > ------------------- > > However, I get problems when I try to import the module into > an embedded Python interpreter as follows: > > Py_Initialize(); > PyRun_SimpleString("print 'Running Python'\n" > "import testing\n" > "print 'imported testing'\n" > "a = testing.A() \n" > "print 'a=', a \n"); You seem to be missing a call to PyImport_AppendInittab("testing", inittesting); before the call to PyRun_SimpleString. (Also note that the soon-to-be boost 1.34 has an enhanced API for the above, boost::python::exec() and boost::python::exec_file().) HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From zzhao at laika.com Wed Feb 28 17:51:49 2007 From: zzhao at laika.com (ZiZi Zhao) Date: Wed, 28 Feb 2007 08:51:49 -0800 Subject: [C++-sig] make tuple of tuples in embedding python? References: <45E4F029.1080606@sympatico.ca> Message-ID: Stefan, thank you for your reply that does answer my question, although I used python/c++ API and you are using boost:python. plus, my application may go more complex like: tuple of tuple of strings tuple of integers tuple of dicts tuple of tuples if boost-python is more flexible & stable, I may try it alos. but, I don't see many sample codes of embedding python using boost-python. there is only one sampel in their document. THANKS, ZZ -----Original Message----- From: c++-sig-bounces at python.org on behalf of Stefan Seefeld Sent: Tue 2/27/2007 6:59 PM To: Development of Python/C++ integration Subject: Re: [C++-sig] make tuple of tuples in embedding python? ZiZi Zhao wrote: > In Python/C API > PyTuple can have different types of items. For example, > > pTuple = PyTuple_New(3); > PyTuple_SetItem(pTuple, 0, pString1); > PyTuple_SetItem(pTuple, 1, pString2); > PyTuple_SetItem(pTuple, 2, pDict); > > I would like to know if I can make tuple of tuples for embedding Python > in C++. For example, > > pTuple0 = PyTuple_New(3); > pTuple1 = PyTuple_New(3); > pTuple2 = PyTuple_New(3); > > pTupleOfTuple = PyTuple_New(3); > > PyTuple_SetItem(pTupleOfTuple, 0, pTuple0); > PyTuple_SetItem(pTupleOfTuple, 1, pTuple1); > PyTuple_SetItem(pTupleOfTuple, 2, pTuple2); > > It seems the code can be compiled. But, it would crash as long as it > starts running without any output info. So, I could not know what is wrong. I'm not sure this answers your question, but since you ask on this particular list, here is how you do the above with boost.python: namespace bpl = boost::python; bpl::tuple t0 = bpl::make_tuple("hello", "world", bpl::dict()); bpl::tuple t1 = bpl::make_tuple("hi !", t0); HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... _______________________________________________ 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 Wed Feb 28 19:18:47 2007 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 28 Feb 2007 20:18:47 +0200 Subject: [C++-sig] make tuple of tuples in embedding python? In-Reply-To: References: <45E4F029.1080606@sympatico.ca> Message-ID: <7465b6170702281018k3db3428di5cae72c20d36ef54@mail.gmail.com> On 2/28/07, ZiZi Zhao wrote: > > > > Stefan, > > thank you for your reply that does answer my question, although I used > python/c++ API and you are using boost:python. plus, my application may go > more complex like: > > tuple of > tuple of strings > tuple of integers > tuple of dicts > tuple of tuples > > if boost-python is more flexible & stable, I may try it alos. but, I don't > see many sample codes of embedding python using boost-python. there is only > one sampel in their document. There is a lot of examples. Take a look on this for example: http://svn.python.org/view/stackless/sandbox/examples/embedding/watchdog-cpp/main.cpp?rev=52182&view=markup Also if you search this mailing list, I am sure you will find dozen of them. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From zzhao at laika.com Wed Feb 28 19:42:32 2007 From: zzhao at laika.com (ZiZi Zhao) Date: Wed, 28 Feb 2007 10:42:32 -0800 Subject: [C++-sig] make tuple of tuples in embedding python? References: <45E4F029.1080606@sympatico.ca> <7465b6170702281018k3db3428di5cae72c20d36ef54@mail.gmail.com> Message-ID: Thanks a lot! ZZ -----Original Message----- From: c++-sig-bounces at python.org on behalf of Roman Yakovenko Sent: Wed 2/28/2007 10:18 AM To: Development of Python/C++ integration Subject: Re: [C++-sig] make tuple of tuples in embedding python? On 2/28/07, ZiZi Zhao wrote: > > > > Stefan, > > thank you for your reply that does answer my question, although I used > python/c++ API and you are using boost:python. plus, my application may go > more complex like: > > tuple of > tuple of strings > tuple of integers > tuple of dicts > tuple of tuples > > if boost-python is more flexible & stable, I may try it alos. but, I don't > see many sample codes of embedding python using boost-python. there is only > one sampel in their document. There is a lot of examples. Take a look on this for example: http://svn.python.org/view/stackless/sandbox/examples/embedding/watchdog-cpp/main.cpp?rev=52182&view=markup Also if you search this mailing list, I am sure you will find dozen of them. -- 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 -------------- A non-text attachment was scrubbed... Name: not available Type: application/ms-tnef Size: 3380 bytes Desc: not available URL: From pk at cs.tut.fi Wed Feb 28 20:10:30 2007 From: pk at cs.tut.fi (=?ISO-8859-1?Q?Pertti_Kellom=E4ki?=) Date: Wed, 28 Feb 2007 21:10:30 +0200 Subject: [C++-sig] Importing into embedded Python In-Reply-To: <45E5A05B.70902@sympatico.ca> References: <45E59A1E.4070105@cs.tut.fi> <45E5A05B.70902@sympatico.ca> Message-ID: <45E5D3A6.9080401@cs.tut.fi> Stefan Seefeld wrote: > You seem to be missing a call to > > PyImport_AppendInittab("testing", inittesting); > > before the call to PyRun_SimpleString. Thanks, that indeed allows me to use stuff in the testing module. It is not quite what I was hoping for, as the Python code will come from a user-written file, and ideally I would like the Python code to be able to load arbitrary modules. However, the set of Boost.Python produced modules is fairly small, so in a pinch I can simply import all of them using PyImport_AppendInittab. A tad too brute force to my taste, but I can live with it. > (Also note that the soon-to-be boost 1.34 has an enhanced > API for the above, boost::python::exec() and boost::python::exec_file().) I'm looking forward for 1.34 to come out officially. -- Pertti