From kwiecm at lunainnovations.com Wed Jul 2 23:52:07 2008 From: kwiecm at lunainnovations.com (Matthew Kwiec) Date: Wed, 2 Jul 2008 17:52:07 -0400 Subject: [C++-sig] Boost Python smart pointers (shared_ptr) Message-ID: <6AC0CCE02D1B684BBC8351F15E8F781B0C45531EE5@e2k7.fsdomain> I am currently running Boost Python on a Debian system, and I am running into an error with smart pointers. I have no problems with regular C++ pointers. There were issues with installing Boost Python 1.35, so we rolled it back to one that worked on the system (1.33). So this may be an issue with the version or the OS, I am not sure. After attempting much more complicated stuff that is more related to what I am attempting to do, I am now following the simple example that I have found online at http://wiki.python.org/moin/boost.python/PointersAndSmartPointers: #include using namespace boost; struct A { shared_ptr create () { return shared_ptr(new A); } std::string hello () { return "Just nod if you can hear me!"; } }; BOOST_PYTHON_MODULE(shared_ptr) { class_("A",init<>()) .def("create",&A::create,return_value_policy()) .staticmethod("create") .def("hello",&A::hello) ; class_< shared_ptr >("A_ptr", init& >()) .def("__pos__",&boost::shared_ptr::get,return_internal_reference<>()) ; } Running the following python commands: from shared_ptr import * an_A = A_ptr.create() I keep getting the same error from the last line. Traceback (most recent call last): File "", line 1, in ? AttributeError: type object 'A_ptr' has no attribute 'create' This makes sense to me because A_ptr doesn't have a create attribute(calling A.create() does not work either), but this is the way the tutorial says to do it. Any help here would be appreciated. Thanks, Matt -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boostpro.com Thu Jul 3 01:28:05 2008 From: dave at boostpro.com (David Abrahams) Date: Wed, 02 Jul 2008 19:28:05 -0400 Subject: [C++-sig] Boost Python smart pointers (shared_ptr) In-Reply-To: <6AC0CCE02D1B684BBC8351F15E8F781B0C45531EE5@e2k7.fsdomain> References: <6AC0CCE02D1B684BBC8351F15E8F781B0C45531EE5@e2k7.fsdomain> Message-ID: <486C0F05.20209@boostpro.com> Matthew Kwiec wrote: > I am currently running Boost Python on a Debian system, and I am > running into an error with smart pointers. I have no problems > with regular C++ pointers. > > > > There were issues with installing Boost Python 1.35, so we rolled > it back to one that worked on the system (1.33). So this may be an > issue with the version or the OS, I am not sure. Hi Matthew, First, I suggest you do something about your mailer; it isn't wrapping long lines. > After attempting much more complicated stuff that is more related to > what I am attempting to do, I am now following the simple example that I > have found online at > http://wiki.python.org/moin/boost.python/PointersAndSmartPointers: > > > > #include > > using namespace boost; > > > > struct A { > > shared_ptr create () { return shared_ptr(new A); } > > std::string hello () { return "Just nod if you can hear me!"; } > > }; > > > > BOOST_PYTHON_MODULE(shared_ptr) > > { > > class_("A",init<>()) > > .def("create",&A::create,return_value_policy()) > > .staticmethod("create") > > .def("hello",&A::hello) > > ; > > > > class_< shared_ptr >("A_ptr", init& >()) Don't ever wrap a shared_ptr directly; they're handled by Boost.Python automatically. I don't know why the wiki suggests that you do it to support (+ptr).create(); the library will give you ptr.create() automatically. In fact, a non-NULL shared_ptr that gets returned to Python looks pretty much just like an A from the Python side. > > .def("__pos__",&boost::shared_ptr::get,return_internal_reference<>()) > > ; > > } > > > > Running the following python commands: > > > > from shared_ptr import * > > an_A = A_ptr.create() > > > > I keep getting the same error from the last line. > > > > Traceback (most recent call last): > > File "", line 1, in ? > > AttributeError: type object 'A_ptr' has no attribute 'create' Well, yeah. The syntax would be a_ptr = A.create() (+a_ptr).hello() but it seems to me that a = A.create() a.hello() would be much cleaner. > This makes sense to me because A_ptr doesn?t have a create > attribute(calling A.create() does not work either), but this > is the way the tutorial says to do it. Well, not really; that isn't the tutorial; it's just something some anonymous person wrote. The tutorial is http://www.boost.org/doc/libs/1_35_0/libs/python/doc/tutorial/doc/html/index.html I would really appreciate it if someone could fix up that wiki page so no further confusion ensues. HTH, -- Dave Abrahams BoostPro Computing http://www.boostpro.com From Robin.K.Friedrich at usa-spaceops.com Thu Jul 3 20:16:56 2008 From: Robin.K.Friedrich at usa-spaceops.com (Friedrich, Robin K) Date: Thu, 3 Jul 2008 13:16:56 -0500 Subject: [C++-sig] ANN: PyUblas -- Numpy+Boost.Ublas = happy Message-ID: Andreas, We are very interested in PyUblas. Thanks so much for doing this interface. I'm having trouble building it though. Is it known to work with gcc 3.2.3? We are stuck on that version but are working fine with boost. Robin Friedrich Flight Design & Dynamics Houston Texas -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at informa.tiker.net Fri Jul 4 16:30:08 2008 From: lists at informa.tiker.net (Andreas =?utf-8?q?Kl=C3=B6ckner?=) Date: Fri, 4 Jul 2008 10:30:08 -0400 Subject: [C++-sig] ANN: PyUblas -- Numpy+Boost.Ublas = happy In-Reply-To: References: Message-ID: <200807041030.10202.lists@informa.tiker.net> On Donnerstag 03 Juli 2008, Friedrich, Robin K wrote: > Andreas, > We are very interested in PyUblas. Thanks so much for doing this interface. > I'm having trouble building it though. Is it known to work with gcc 3.2.3? > We are stuck on that version but are working fine with boost. I don't see why gcc 3 should not work, even though it will use a fair bit more time and memory during compilation. If you post the error message, I may be able to help you. Also, I've crossposted this answer to the (new) PyUblas mailing list. You can subscribe at [1]. Andreas [1] http://tiker.net/mailman/listinfo/pyublas_tiker.net -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: This is a digitally signed message part. URL: From Charles.Lesire at onera.fr Thu Jul 10 09:32:57 2008 From: Charles.Lesire at onera.fr (Charles Lesire-Cabaniols) Date: Thu, 10 Jul 2008 09:32:57 +0200 Subject: [C++-sig] Hello World Tutorial using Pyste does not work! Message-ID: <4875BB29.7000202@onera.fr> Hi folks. I have some troubles using pyste to wrap the Hello World sample. Here are the files I use: // world.h struct World { std::string msg; void set(std::string msg) {this->msg = msg;} std::string get() {return msg;} } ## world.pyste Class('World', 'world.h') When launching > pyste --module=hello world.pyste I get the following error coming from gccxml: world.h:3: error: 'string' undeclared in namespace 'std' ... ... If I had a #include to world.h, I get the error: In file included from /usr/include/c++/4.2/string:45, from world.h:1: /usr/include/c++/4.2/i486-linux-gnu/bits/c++config.h:149: error: syntax error before '__attribute__' with at the end a CppParserError 'Error executing gccxml' My configuration: - Ubuntu 8.04(hardy) - python 2.5.2 - pyste 0.9.30 - gccxml 0.7.0 - g++ 4.2.3 Thanks for your help! Charles. -------------- next part -------------- A non-text attachment was scrubbed... Name: Charles_Lesire.vcf Type: text/x-vcard Size: 339 bytes Desc: not available URL: From foxmulder900 at yahoo.com Thu Jul 10 23:52:18 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Thu, 10 Jul 2008 14:52:18 -0700 (PDT) Subject: [C++-sig] helloworld example compiles and passes test but wont run on its own Message-ID: <18392648.post@talk.nabble.com> Hello, I have gotten the Boost-Python helloworld example to compile with no errors and it even passes the test. However I am confused as to where to go from here because the example hello.py will not run on its own because there is no hello_ext module. There is a hello_ext.lib .exp .obj etc, but how would I actually get python's import statement to recognize these? Any help is much appreciated! -- View this message in context: http://www.nabble.com/helloworld-example-compiles-and-passes-test-but-wont-run-on-its-own-tp18392648p18392648.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From grant.tang at gmail.com Fri Jul 11 01:30:40 2008 From: grant.tang at gmail.com (Grant) Date: Thu, 10 Jul 2008 18:30:40 -0500 Subject: [C++-sig] Strange about the C++ exception in Python Message-ID: Hi, We have exception classees which is inherited from std::exception class. I implemented the what() function always return the exception class's name and description string. When the exception is throwed in C++ code, python interpreter could catch it as RuntimeError. Then I print out the first word of this RuntimeError object's args[0], it should be the c++ exception class's name. Now the problem is this method works some times. Since I put try/except in the unit test phrase, compare the exception name with a string. Some times it works fine, but sometimes exception name is just ''. I don't understand why it work the way so randomly. I use unittest module and test_support of test module for my unit test framework. Does it have anything with the unit test, or it's a boost.python issue, or the Python interpreter just misses to catch c++ exception sometime? I tried to use boost.python's translator, but it does not help. How do you guys handle the exception throwed in C++? Thanks for your suggestion, Grant From dave at boostpro.com Fri Jul 11 02:24:22 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 10 Jul 2008 20:24:22 -0400 Subject: [C++-sig] helloworld example compiles and passes test but wont run on its own In-Reply-To: <18392648.post@talk.nabble.com> (FoxMulder's message of "Thu, 10 Jul 2008 14:52:18 -0700 (PDT)") References: <18392648.post@talk.nabble.com> Message-ID: <87od55p8sp.fsf@mcbain.luannocracy.com> on Thu Jul 10 2008, FoxMulder900 wrote: > Hello, I have gotten the Boost-Python helloworld example to compile with no > errors and it even passes the test. However I am confused as to where to go > from here because the example hello.py will not run on its own because there > is no hello_ext module. There is a hello_ext.lib .exp .obj etc, but how > would I actually get python's import statement to recognize these? Any help > is much appreciated! The extension module was probably deleted when the test passed. Try passing "-a --preserve-test-targets" next time you invoke bjam (you can drop the -a thereafter). -- Dave Abrahams BoostPro Computing http://www.boostpro.com From foxmulder900 at yahoo.com Fri Jul 11 04:54:55 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Thu, 10 Jul 2008 19:54:55 -0700 (PDT) Subject: [C++-sig] helloworld example compiles and passes test but wont run on its own In-Reply-To: <87od55p8sp.fsf@mcbain.luannocracy.com> References: <18392648.post@talk.nabble.com> <87od55p8sp.fsf@mcbain.luannocracy.com> Message-ID: <18395853.post@talk.nabble.com> David Abrahams-3 wrote: > > > The extension module was probably deleted when the test passed. Try > passing "-a --preserve-test-targets" next time you invoke bjam (you can > drop the -a thereafter). > > Ok thats a step closer - thank you - however now I am getting an error when it trys to import hello_ext: ImportError: DLL load failed: The specified module could not be found. I copied hello.py into the folder with the .pyd, .lib, .manifest etc... but there are no DLLs -- View this message in context: http://www.nabble.com/helloworld-example-compiles-and-passes-test-but-wont-run-on-its-own-tp18392648p18395853.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From alkis at evlogimenos.com Fri Jul 11 08:39:53 2008 From: alkis at evlogimenos.com (=?UTF-8?Q?Alkis_Evlogimenos_(?= =?UTF-8?Q?'=CE=91=CE=BB=CE=BA=CE=B7=CF=82_=CE=95=CF=85?= =?UTF-8?Q?=CE=BB=CE=BF=CE=B3=CE=B7=CE=BC=CE=AD=CE=BD=CE=BF=CF=82)?=) Date: Fri, 11 Jul 2008 08:39:53 +0200 Subject: [C++-sig] returning a list of extension types Message-ID: <82738b150807102339j30528272lc43b1c9c4fd91cff@mail.gmail.com> I have a class I want to expose to python, which has a method that returns a list of instances of itself. What I did was to define a function: list MakeListOfFoo(Foo* foo) { list foos; foos.append(new Foo()); foos.append(new Foo()); return foos; } and in the module definition: BOOST_PYTHON_MODULE(Bar) { class_("Foo") .def("MakeListOfFoo", &MakeListOfFoo); } The above while it returns a list, it doesn't convert Foo* to a python Foo object. How do I go about doing that? Thanks, -- Alkis -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boostpro.com Fri Jul 11 17:06:14 2008 From: dave at boostpro.com (David Abrahams) Date: Fri, 11 Jul 2008 11:06:14 -0400 Subject: [C++-sig] helloworld example compiles and passes test but wont run on its own In-Reply-To: <18395853.post@talk.nabble.com> (FoxMulder's message of "Thu, 10 Jul 2008 19:54:55 -0700 (PDT)") References: <18392648.post@talk.nabble.com> <87od55p8sp.fsf@mcbain.luannocracy.com> <18395853.post@talk.nabble.com> Message-ID: <87tzew5ul5.fsf@mcbain.luannocracy.com> on Thu Jul 10 2008, FoxMulder900 wrote: > David Abrahams-3 wrote: >> >> >> The extension module was probably deleted when the test passed. Try >> passing "-a --preserve-test-targets" next time you invoke bjam (you can >> drop the -a thereafter). >> >> > > Ok thats a step closer - thank you - however now I am getting an error when > it trys to import hello_ext: > > ImportError: DLL load failed: The specified module could not be found. > > I copied hello.py into the folder with the .pyd, .lib, .manifest etc... but > there are no DLLs OK, you probably need to set up your PYTHONPATH. I suggest you run bjam with "-n -a", capture the output, and see what commands are being issued to run the test. HTH, -- Dave Abrahams BoostPro Computing http://www.boostpro.com From dave at boostpro.com Fri Jul 11 17:18:17 2008 From: dave at boostpro.com (David Abrahams) Date: Fri, 11 Jul 2008 11:18:17 -0400 Subject: [C++-sig] returning a list of extension types In-Reply-To: <82738b150807102339j30528272lc43b1c9c4fd91cff@mail.gmail.com> ("\"\"Alkis Evlogimenos =?utf-8?B?KCfOkc67zrrOt8+CIM6Vz4XOu86/zrPOt868?= =?utf-8?B?zq3Ovc6/z4IpXCJcIiIncw==?= message of "Fri, 11 Jul 2008 08:39:53 +0200") References: <82738b150807102339j30528272lc43b1c9c4fd91cff@mail.gmail.com> Message-ID: <87hcaw5u12.fsf@mcbain.luannocracy.com> on Fri Jul 11 2008, ""Alkis Evlogimenos ('????? ???????????)"" wrote: > I have a class I want to expose to python, which has a method that returns a list of instances > of itself. What I did was to define a function: > > list MakeListOfFoo(Foo* foo) { > list foos; > foos.append(new Foo()); > foos.append(new Foo()); > return foos; > } > > and in the module definition: > > BOOST_PYTHON_MODULE(Bar) { > class_("Foo") > .def("MakeListOfFoo", &MakeListOfFoo); > } > > The above while it returns a list, it doesn't convert Foo* to a python > Foo object. How do I go about doing that? What type is "list," really? Is there a reason not to do something like boost::python::list MakeListOfFoo(Foo* foo) { boost::python::list foos; foos.append(Foo()); // No "new" foos.append(Foo()); return foos; } ? If you really need reference semantics, use boost::shared_ptr: boost::python::list MakeListOfFoo(Foo* foo) { boost::python::list foos; foos.append(boost::shared_ptr(new Foo)); foos.append(boost::shared_ptr(new Foo)); return foos; } If your list is boost::python::list, what you've done above would leak the things you are trying to append, and store a copy in the list. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From foxmulder900 at yahoo.com Fri Jul 11 17:39:48 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Fri, 11 Jul 2008 08:39:48 -0700 (PDT) Subject: [C++-sig] helloworld example compiles and passes test but wont run on its own In-Reply-To: <87tzew5ul5.fsf@mcbain.luannocracy.com> References: <18392648.post@talk.nabble.com> <87od55p8sp.fsf@mcbain.luannocracy.com> <18395853.post@talk.nabble.com> <87tzew5ul5.fsf@mcbain.luannocracy.com> Message-ID: <18406703.post@talk.nabble.com> David Abrahams-3 wrote: > > > OK, you probably need to set up your PYTHONPATH. I suggest you run bjam > with "-n -a", capture the output, and see what commands are being issued > to run the test. > > Thank you greatly! I was able to see what paths were being set, once i set them as permanent environment variables, I am able to run the script from anywhere! -- View this message in context: http://www.nabble.com/helloworld-example-compiles-and-passes-test-but-wont-run-on-its-own-tp18392648p18406703.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From alkis at evlogimenos.com Fri Jul 11 18:09:28 2008 From: alkis at evlogimenos.com (=?UTF-8?Q?Alkis_Evlogimenos_(?= =?UTF-8?Q?'=CE=91=CE=BB=CE=BA=CE=B7=CF=82_=CE=95=CF=85?= =?UTF-8?Q?=CE=BB=CE=BF=CE=B3=CE=B7=CE=BC=CE=AD=CE=BD=CE=BF=CF=82)?=) Date: Fri, 11 Jul 2008 18:09:28 +0200 Subject: [C++-sig] returning a list of extension types In-Reply-To: <87hcaw5u12.fsf@mcbain.luannocracy.com> References: <82738b150807102339j30528272lc43b1c9c4fd91cff@mail.gmail.com> <87hcaw5u12.fsf@mcbain.luannocracy.com> Message-ID: <82738b150807110909w15f4122ex4b92bd832636f35@mail.gmail.com> Thanks for the fas reply! list is boost::python::list, sorry for not being explicit on that. Foo is a pretty heavy object so I will need reference semantics. Will a std::auto_ptr work as well as a boost::shared_ptr here? Or are there any gotchas in using std::auto_ptr with boost::python::list? The problem with appending new Foo() to the list (apart from the leak) is that when I try that I get an exception: TypeError: No to_python (by-value) converter found for C++ type: Foo Trying your suggestion above makes the exception: TypeError: No to_python (by-value) converter found for C++ type: boost::shared_ptr How to do register a converter to make this a python object? On Fri, Jul 11, 2008 at 5:18 PM, David Abrahams wrote: > > on Fri Jul 11 2008, ""Alkis Evlogimenos ('????? ???????????)"" > wrote: > > > I have a class I want to expose to python, which has a method that > returns a list of instances > > of itself. What I did was to define a function: > > > > list MakeListOfFoo(Foo* foo) { > > list foos; > > foos.append(new Foo()); > > foos.append(new Foo()); > > return foos; > > } > > > > and in the module definition: > > > > BOOST_PYTHON_MODULE(Bar) { > > class_("Foo") > > .def("MakeListOfFoo", &MakeListOfFoo); > > } > > > > The above while it returns a list, it doesn't convert Foo* to a python > > Foo object. How do I go about doing that? > > What type is "list," really? Is there a reason not to do something like > > boost::python::list MakeListOfFoo(Foo* foo) { > boost::python::list foos; > foos.append(Foo()); // No "new" > foos.append(Foo()); > return foos; > } > > ? > > If you really need reference semantics, use boost::shared_ptr: > > boost::python::list MakeListOfFoo(Foo* foo) { > boost::python::list foos; > > foos.append(boost::shared_ptr(new Foo)); > foos.append(boost::shared_ptr(new Foo)); > > return foos; > } > > If your list is boost::python::list, what you've done above would leak > the things you are trying to append, and store a copy in the list. > > -- > Dave Abrahams > BoostPro Computing > http://www.boostpro.com > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Alkis -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boostpro.com Fri Jul 11 18:32:10 2008 From: dave at boostpro.com (David Abrahams) Date: Fri, 11 Jul 2008 12:32:10 -0400 Subject: [C++-sig] returning a list of extension types In-Reply-To: <82738b150807110909w15f4122ex4b92bd832636f35@mail.gmail.com> ("\"\"Alkis Evlogimenos =?utf-8?B?KCfOkc67zrrOt8+CIM6Vz4XOu86/zrPOt868?= =?utf-8?B?zq3Ovc6/z4IpXCJcIiIncw==?= message of "Fri, 11 Jul 2008 18:09:28 +0200") References: <82738b150807102339j30528272lc43b1c9c4fd91cff@mail.gmail.com> <87hcaw5u12.fsf@mcbain.luannocracy.com> <82738b150807110909w15f4122ex4b92bd832636f35@mail.gmail.com> Message-ID: <87tzew2xh1.fsf@mcbain.luannocracy.com> on Fri Jul 11 2008, ""Alkis Evlogimenos ('????? ???????????)"" wrote: > Thanks for the fas reply! > > list is boost::python::list, sorry for not being explicit on that. Foo > is a pretty heavy object so I will need reference semantics. Will a > std::auto_ptr work as well as a boost::shared_ptr here? Or are there > any gotchas in using std::auto_ptr with boost::python::list? I don't remember, frankly, whether auto_ptr will work out-of-the box. shared_ptr *will* work. > The problem with appending new Foo() to the list (apart from the leak) > is that when I try that I get an exception: > > TypeError: No to_python (by-value) converter found for C++ type: Foo > > Trying your suggestion above makes the exception: > > TypeError: No to_python (by-value) converter found for C++ type: > boost::shared_ptr > > How to do register a converter to make this a python object? That's taken care of when you load the Bar python module. You can't convert a class to Python until its class_<...> wrapper has been executed. > On Fri, Jul 11, 2008 at 5:18 PM, David Abrahams wrote: > > on Fri Jul 11 2008, ""Alkis Evlogimenos ('????? ???????????)"" > wrote: > > > I have a class I want to expose to python, which has a method that returns a list of > instances > > of itself. What I did was to define a function: > > > > list MakeListOfFoo(Foo* foo) { > > list foos; > > foos.append(new Foo()); > > foos.append(new Foo()); > > return foos; > > } > > > > and in the module definition: > > > > BOOST_PYTHON_MODULE(Bar) { > > class_("Foo") > > .def("MakeListOfFoo", &MakeListOfFoo); > > } > > > > The above while it returns a list, it doesn't convert Foo* to a python > > Foo object. How do I go about doing that? -- Dave Abrahams BoostPro Computing http://www.boostpro.com From goldberg at coredp.com Fri Jul 11 20:19:42 2008 From: goldberg at coredp.com (Moe Goldberg) Date: Fri, 11 Jul 2008 14:19:42 -0400 Subject: [C++-sig] importing C++ module fails, but module is still in sys.modules Message-ID: <4877A43E.4000507@coredp.com> I'm not sure if this is just a quirk in python, of if I am doing something wrong. If a C++ extension module throws an exception while it's initializing, the module is still stored in sys.modules (as opposed to a python module, which is not stored in sys.modules if it errors while being imported). For example: pymodule.py: raise RuntimeError("This python module fails.") cppmodule.cpp: #include #include BOOST_PYTHON_MODULE(cppmodule) { throw std::runtime_error("This C++ module fails."); } >>> import pymodule Traceback (most recent call last): File "", line 1, in ? File "pymodule.py", line 2, in ? raise RuntimeError("This python module fails.") RuntimeError: This python module fails. >>> import cppmodule Traceback (most recent call last): File "", line 1, in ? RuntimeError: This C++ module fails. >>> include sys >>> 'pymodule' in sys.modules False >>> 'cppmodule' in sys.modules True Is there a sane way to prevent pymodule from being added to sys.modules if importing it fails? Thanks From grant.tang at gmail.com Fri Jul 11 21:15:59 2008 From: grant.tang at gmail.com (Grant) Date: Fri, 11 Jul 2008 14:15:59 -0500 Subject: [C++-sig] Strange about the C++ exception in Python References: Message-ID: By googling I found this comment: "Many platforms and compilers are not able to consistently catch exceptions thrown across shared library boundaries." Does that mean my problem is unsolvable? I am really curious how you guys deal with c++ exceptions in Python? Grant "Grant" wrote in message news:g5662v$rkg$1 at ger.gmane.org... > Hi, > > We have exception classees which is inherited from std::exception class. I > implemented the what() function always return the exception class's name > and description string. When the exception is throwed in C++ code, python > interpreter could catch it as RuntimeError. Then I print out the first > word of this RuntimeError object's args[0], it should be the c++ exception > class's name. > > Now the problem is this method works some times. Since I put try/except in > the unit test phrase, compare the exception name with a string. Some times > it works fine, but sometimes exception name is just ''. I don't understand > why it work the way so randomly. > > I use unittest module and test_support of test module for my unit test > framework. Does it have anything with the unit test, or it's a > boost.python issue, or the Python interpreter just misses to catch c++ > exception sometime? > > I tried to use boost.python's translator, but it does not help. > > How do you guys handle the exception throwed in C++? > > Thanks for your suggestion, > Grant From foxmulder900 at yahoo.com Fri Jul 11 22:51:49 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Fri, 11 Jul 2008 13:51:49 -0700 (PDT) Subject: [C++-sig] leaving out functions when exposing a class Message-ID: <18412325.post@talk.nabble.com> Hello, i am just starting to use boost python in my project. I am wrapping one of my rather large classes that I want to be available in script. However, there is only a small number of functions that I need to be available in python, it was my understanding that I would not have to wrap every function. Is this correct? When I run bjam, it gives me unresolved external errors on the functions I did not wrap. If it is possible to leave out functions, is there something extra I have to do? I also have a second, slightly less significant question, How exactly do I wrap deconstructors? I have the following code and it does not wrap correctly. BOOST_PYTHON_MODULE(pyGameObject) { class_("GameObject", no_init) .def("~GameObject", &GameObject::~GameObject) .def("update", &GameObject::update) .def("translate", &GameObject::translate) .def("rotate", &NPC::rotate) .def("scale", &NPC::scale) .def("showBoundingBox", &NPC::showBoundingBox) .def("addChild", &NPC::addChild) ; } Thanks in advance! -- View this message in context: http://www.nabble.com/leaving-out-functions-when-exposing-a-class-tp18412325p18412325.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From dave at boostpro.com Sat Jul 12 01:23:57 2008 From: dave at boostpro.com (David Abrahams) Date: Fri, 11 Jul 2008 19:23:57 -0400 Subject: [C++-sig] Strange about the C++ exception in Python In-Reply-To: (Grant's message of "Fri, 11 Jul 2008 14:15:59 -0500") References: Message-ID: <87d4lk0zua.fsf@mcbain.luannocracy.com> on Fri Jul 11 2008, "Grant" wrote: > By googling I found this comment: > > "Many platforms and compilers are not able to consistently catch exceptions > thrown across shared library boundaries." I think that's probably an outdated statement. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From nat at lindenlab.com Sat Jul 12 15:19:36 2008 From: nat at lindenlab.com (Nat Goodspeed) Date: Sat, 12 Jul 2008 09:19:36 -0400 Subject: [C++-sig] helloworld example compiles and passes test but wont run on its own In-Reply-To: <18395853.post@talk.nabble.com> References: <18392648.post@talk.nabble.com> <87od55p8sp.fsf@mcbain.luannocracy.com> <18395853.post@talk.nabble.com> Message-ID: <4878AF68.8080105@lindenlab.com> FoxMulder900 wrote: > I am getting an error when > it trys to import hello_ext: > > ImportError: DLL load failed: The specified module could not be found. > > I copied hello.py into the folder with the .pyd, .lib, .manifest etc... but > there are no DLLs I'm glad your problem has been solved. FWIW, the .pyd IS the .dll. As of Python 2.5, the interpreter no longer attempts to load plain .dlls; when you build a Python extension module, you must rename it to .pyd instead of .dll. From roman.yakovenko at gmail.com Sun Jul 13 07:35:42 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 13 Jul 2008 08:35:42 +0300 Subject: [C++-sig] Strange about the C++ exception in Python In-Reply-To: References: Message-ID: <7465b6170807122235s65cbeb87l56be5aec8d47876f@mail.gmail.com> On Fri, Jul 11, 2008 at 10:15 PM, Grant wrote: > By googling I found this comment: > > "Many platforms and compilers are not able to consistently catch exceptions > thrown across shared library boundaries." It works fine for me on Windows and on Linux. > Does that mean my problem is unsolvable? > I am really curious how you guys deal with c++ exceptions in Python? This is what I am doing: http://language-binding.net/pyplusplus/troubleshooting_guide/exceptions/exceptions.html By the way you can find scons script there, so you can compare what is going on when you build your modules. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Sun Jul 13 09:40:09 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 13 Jul 2008 10:40:09 +0300 Subject: [C++-sig] leaving out functions when exposing a class In-Reply-To: <18412325.post@talk.nabble.com> References: <18412325.post@talk.nabble.com> Message-ID: <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> On Fri, Jul 11, 2008 at 11:51 PM, FoxMulder900 wrote: > > Hello, i am just starting to use boost python in my project. I am wrapping > one of my rather large classes that I want to be available in script. > However, there is only a small number of functions that I need to be > available in python, it was my understanding that I would not have to wrap > every function. Is this correct? Yes > When I run bjam, it gives me unresolved > external errors on the functions I did not wrap. If it is possible to leave > out functions, is there something extra I have to do? Yes, modify the link line - you should link your module with the library, that defines that functions > I also have a second, slightly less significant question, How exactly do I > wrap deconstructors? You don't. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Sun Jul 13 09:59:10 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 13 Jul 2008 10:59:10 +0300 Subject: [C++-sig] importing C++ module fails, but module is still in sys.modules In-Reply-To: <4877A43E.4000507@coredp.com> References: <4877A43E.4000507@coredp.com> Message-ID: <7465b6170807130059q1ff723bfm6a6de0c3deeb888f@mail.gmail.com> On Fri, Jul 11, 2008 at 9:19 PM, Moe Goldberg wrote: > I'm not sure if this is just a quirk in python, of if I am doing something > wrong. > If a C++ extension module throws an exception while it's initializing, the > module is still stored in sys.modules (as opposed to a python module, which > is not stored in sys.modules if it errors while being imported). > > For example: > > pymodule.py: > raise RuntimeError("This python module fails.") > > cppmodule.cpp: > #include > #include > BOOST_PYTHON_MODULE(cppmodule) > { > throw std::runtime_error("This C++ module fails."); > } > >>>> import pymodule > Traceback (most recent call last): > File "", line 1, in ? > File "pymodule.py", line 2, in ? > raise RuntimeError("This python module fails.") > RuntimeError: This python module fails. > >>>> import cppmodule > Traceback (most recent call last): > File "", line 1, in ? > RuntimeError: This C++ module fails. > >>>> include sys >>>> 'pymodule' in sys.modules > False >>>> 'cppmodule' in sys.modules > True > > Is there a sane way to prevent pymodule from being added to sys.modules if > importing it fails? It has nothing to do with boost.python. Same thing will happen with pure Python module too. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Sun Jul 13 11:04:00 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 13 Jul 2008 12:04:00 +0300 Subject: [C++-sig] Hello World Tutorial using Pyste does not work! In-Reply-To: <4875BB29.7000202@onera.fr> References: <4875BB29.7000202@onera.fr> Message-ID: <7465b6170807130204v31704aabge0c24a4e3af59bc6@mail.gmail.com> 2008/7/10 Charles Lesire-Cabaniols : > Hi folks. > > I have some troubles using pyste to wrap the Hello World sample. > > Here are the files I use: > > // world.h > struct World { > std::string msg; > void set(std::string msg) {this->msg = msg;} > std::string get() {return msg;} > } > > ## world.pyste > Class('World', 'world.h') > > > When launching >> pyste --module=hello world.pyste > I get the following error coming from gccxml: > > world.h:3: error: 'string' undeclared in namespace 'std' > ... > ... > > If I had a > #include > to world.h, I get the error: > > In file included from /usr/include/c++/4.2/string:45, > from world.h:1: > /usr/include/c++/4.2/i486-linux-gnu/bits/c++config.h:149: error: syntax > error before '__attribute__' > > with at the end a CppParserError 'Error executing gccxml' > > My configuration: > - Ubuntu 8.04(hardy) > - python 2.5.2 > - pyste 0.9.30 This tool is not maintained. > - gccxml 0.7.0 This release is also pretty old and not supported. I suggest you to try Py++ and CVS version of gccxml -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From foxmulder900 at yahoo.com Mon Jul 14 17:26:08 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Mon, 14 Jul 2008 08:26:08 -0700 (PDT) Subject: [C++-sig] leaving out functions when exposing a class In-Reply-To: <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> References: <18412325.post@talk.nabble.com> <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> Message-ID: <18446355.post@talk.nabble.com> Roman Yakovenko wrote: > > > Yes, modify the link line - you should link your module with the > library, that defines that functions > > Thanks! That greatly narrowed my problems, and gave me a better understanding of what is going on. My only problem now is that I am getting 2 remaining unresolved external symbol errors, from separate libraries, the libraries are definitely getting linked. Both functions are using the __imp__ calling convention, not sure if that is significant or not. I know these libraries are ok because they link fine when i build my project in visual C++ without boost. Thanks again! -- View this message in context: http://www.nabble.com/leaving-out-functions-when-exposing-a-class-tp18412325p18446355.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From roman.yakovenko at gmail.com Mon Jul 14 20:09:58 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 14 Jul 2008 21:09:58 +0300 Subject: [C++-sig] leaving out functions when exposing a class In-Reply-To: <18446355.post@talk.nabble.com> References: <18412325.post@talk.nabble.com> <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> <18446355.post@talk.nabble.com> Message-ID: <7465b6170807141109r5b4ea237n1dc4849cbec76564@mail.gmail.com> On Mon, Jul 14, 2008 at 6:26 PM, FoxMulder900 wrote: > Roman Yakovenko wrote: >> Yes, modify the link line - you should link your module with the >> library, that defines that functions > > Thanks! That greatly narrowed my problems, and gave me a better > understanding of what is going on. My only problem now is that I am getting > 2 remaining unresolved external symbol errors, from separate libraries, the > libraries are definitely getting linked. Good, because you can compare link and compile lines. > Both functions are using the > __imp__ calling convention, not sure if that is significant or not. I know > these libraries are ok because they link fine when i build my project in > visual C++ without boost. You are going to find out. What does happen if you replace the calling convention? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From Maxi.Matthe at web.de Mon Jul 14 21:04:53 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Mon, 14 Jul 2008 21:04:53 +0200 Subject: [C++-sig] [boost.python] Exposing abstract derived classes Message-ID: Hi! I have a problem with exposing derived classes to python: class Base { public: virtual void f() = 0; } class Derived : public Base { public: virtual void g() = 0; } // here's how to wrap and expose Base: class BaseWrap : public Base, public wrapper { public: void f() { this->get_override("f")(); } } BOOST_PYTHON_MODULE(a) { class_("Base") .def(f, pure_virtual(&BaseWrap::f)) ; } // How should I wrap and expose Derived? // It is also pure virtual, but if I create a wrapper that // derives from Derived and wrapper and create the method // g(), f() is still not implmented, thus it does not compile. I do not feel comfortable by deriving DerivedWrapper from BaseWrapper, Derived and wrapper, which could even not work because of same base classes and so on. So what is the right implementation for my problem? Regards, Max From roman.yakovenko at gmail.com Mon Jul 14 21:29:50 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 14 Jul 2008 22:29:50 +0300 Subject: [C++-sig] [boost.python] Exposing abstract derived classes In-Reply-To: References: Message-ID: <7465b6170807141229r6cc5bb48xeeb883b0011f40db@mail.gmail.com> On Mon, Jul 14, 2008 at 10:04 PM, Maximilian Matthe wrote: > Hi! > > I have a problem with exposing derived classes to python: > > class Base > { > public: > virtual void f() = 0; > } > > class Derived : public Base > { > public: > virtual void g() = 0; > } > > // here's how to wrap and expose Base: > class BaseWrap : public Base, public wrapper > { > public: > void f() > { > this->get_override("f")(); > } > } > BOOST_PYTHON_MODULE(a) > { > class_("Base") > .def(f, pure_virtual(&BaseWrap::f)) ; > } > > // How should I wrap and expose Derived? > // It is also pure virtual, but if I create a wrapper that > // derives from Derived and wrapper and create the method > // g(), f() is still not implmented, thus it does not compile. > > > I do not feel comfortable by deriving DerivedWrapper from BaseWrapper, > Derived and wrapper, which could even not work because of > same base classes and so on. > So what is the right implementation for my problem? To use Py++ :-) Next piece of code was generated by Py++: #include "boost/python.hpp" #include "1.h" namespace bp = boost::python; struct Base_wrapper : Base, bp::wrapper< Base > { Base_wrapper() : Base() , bp::wrapper< Base >(){ // null constructor } virtual void f( ){ bp::override func_f = this->get_override( "f" ); func_f( ); } }; struct Derived_wrapper : Derived, bp::wrapper< Derived > { Derived_wrapper() : Derived() , bp::wrapper< Derived >(){ // null constructor } virtual void g( ){ bp::override func_g = this->get_override( "g" ); func_g( ); } virtual void f( ){ bp::override func_f = this->get_override( "f" ); func_f( ); } }; BOOST_PYTHON_MODULE(pyplusplus){ bp::class_< Base_wrapper, boost::noncopyable >( "Base" ) .def( "f" , bp::pure_virtual( (void ( ::Base::* )( ) )(&::Base::f) ) ); bp::class_< Derived_wrapper, bp::bases< Base >, boost::noncopyable >( "Derived" ) .def( "g" , bp::pure_virtual( (void ( ::Derived::* )( ) )(&::Derived::g) ) ) .def( "f" , bp::pure_virtual( (void ( ::Base::* )( ) )(&::Base::f) ) ); } -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From Maxi.Matthe at web.de Mon Jul 14 21:35:20 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Mon, 14 Jul 2008 21:35:20 +0200 Subject: [C++-sig] [boost.python] Exposing abstract derived classes In-Reply-To: <7465b6170807141229r6cc5bb48xeeb883b0011f40db@mail.gmail.com> References: <7465b6170807141229r6cc5bb48xeeb883b0011f40db@mail.gmail.com> Message-ID: Roman Yakovenko schrieb: > On Mon, Jul 14, 2008 at 10:04 PM, Maximilian Matthe wrote: >> Hi! >> >> I have a problem with exposing derived classes to python: >> >> class Base >> { >> public: >> virtual void f() = 0; >> } >> >> class Derived : public Base >> { >> public: >> virtual void g() = 0; >> } >> >> // here's how to wrap and expose Base: >> class BaseWrap : public Base, public wrapper >> { >> public: >> void f() >> { >> this->get_override("f")(); >> } >> } >> BOOST_PYTHON_MODULE(a) >> { >> class_("Base") >> .def(f, pure_virtual(&BaseWrap::f)) ; >> } >> >> // How should I wrap and expose Derived? >> // It is also pure virtual, but if I create a wrapper that >> // derives from Derived and wrapper and create the method >> // g(), f() is still not implmented, thus it does not compile. >> >> >> I do not feel comfortable by deriving DerivedWrapper from BaseWrapper, >> Derived and wrapper, which could even not work because of >> same base classes and so on. >> So what is the right implementation for my problem? > > To use Py++ :-) > > Next piece of code was generated by Py++: > > #include "boost/python.hpp" > > #include "1.h" > > namespace bp = boost::python; > > struct Base_wrapper : Base, bp::wrapper< Base > { > > Base_wrapper() > : Base() > , bp::wrapper< Base >(){ > // null constructor > > } > > virtual void f( ){ > bp::override func_f = this->get_override( "f" ); > func_f( ); > } > > }; > > struct Derived_wrapper : Derived, bp::wrapper< Derived > { > > Derived_wrapper() > : Derived() > , bp::wrapper< Derived >(){ > // null constructor > > } > > virtual void g( ){ > bp::override func_g = this->get_override( "g" ); > func_g( ); > } > > virtual void f( ){ > bp::override func_f = this->get_override( "f" ); > func_f( ); > } > > }; > > BOOST_PYTHON_MODULE(pyplusplus){ > bp::class_< Base_wrapper, boost::noncopyable >( "Base" ) > .def( > "f" > , bp::pure_virtual( (void ( ::Base::* )( ) )(&::Base::f) ) ); > > bp::class_< Derived_wrapper, bp::bases< Base >, boost::noncopyable >> ( "Derived" ) > .def( > "g" > , bp::pure_virtual( (void ( ::Derived::* )( ) > )(&::Derived::g) ) ) > .def( > "f" > , bp::pure_virtual( (void ( ::Base::* )( ) )(&::Base::f) ) ); > } > > Ah I see, so the solution that Py++ uses is implementing all abstract methods in the derivedWrapper class and in the basewrapper. This seems to be redundant, are you sure that this is the best solution? I mean, is py++ the standard in python wrapping? :-) From roman.yakovenko at gmail.com Mon Jul 14 21:43:30 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 14 Jul 2008 22:43:30 +0300 Subject: [C++-sig] [boost.python] Exposing abstract derived classes In-Reply-To: References: <7465b6170807141229r6cc5bb48xeeb883b0011f40db@mail.gmail.com> Message-ID: <7465b6170807141243p23d78c58gfd5e01574a8e4eba@mail.gmail.com> On Mon, Jul 14, 2008 at 10:35 PM, Maximilian Matthe wrote: > Ah I see, so the solution that Py++ uses is implementing all abstract > methods in the derivedWrapper class and in the basewrapper. This > seems to be redundant, are you sure that this is the best solution? Definitely. Take a look on this file and explanation: http://pygccxml.svn.sourceforge.net/viewvc/pygccxml/pyplusplus_dev/docs/history/history.rest?view=markup > I mean, is py++ the standard in python wrapping? :-) No, not at all, but it was tested with few big( huge ) projects with untrivial hierarchies: http://language-binding.net/pyplusplus/quotes.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From mathieu.malaterre at gmail.com Tue Jul 15 00:18:37 2008 From: mathieu.malaterre at gmail.com (Mathieu Malaterre) Date: Tue, 15 Jul 2008 00:18:37 +0200 Subject: [C++-sig] Strange about the C++ exception in Python In-Reply-To: <87d4lk0zua.fsf@mcbain.luannocracy.com> References: <87d4lk0zua.fsf@mcbain.luannocracy.com> Message-ID: On Sat, Jul 12, 2008 at 1:23 AM, David Abrahams wrote: > > on Fri Jul 11 2008, "Grant" wrote: > >> By googling I found this comment: >> >> "Many platforms and compilers are not able to consistently catch exceptions >> thrown across shared library boundaries." > > I think that's probably an outdated statement. Isn't it related to the rtti support in gcc ? http://wiki.python.org/moin/boost.python/CrossExtensionModuleDependencies where you have to load C++ python module with RTLD_GLOBAL ... 2 cents, -- Mathieu From foxmulder900 at yahoo.com Tue Jul 15 03:14:15 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Mon, 14 Jul 2008 18:14:15 -0700 (PDT) Subject: [C++-sig] leaving out functions when exposing a class In-Reply-To: <7465b6170807141109r5b4ea237n1dc4849cbec76564@mail.gmail.com> References: <18412325.post@talk.nabble.com> <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> <18446355.post@talk.nabble.com> <7465b6170807141109r5b4ea237n1dc4849cbec76564@mail.gmail.com> Message-ID: <18456336.post@talk.nabble.com> Roman Yakovenko wrote: > > > You are going to find out. What does happen if you replace the calling > convention? > > hmm, i am unable to do that because the functions are in an external library i am using in my project, i do not wish to wrap the external library and have it exposed in python, i had to link to it because my project uses it. -- View this message in context: http://www.nabble.com/leaving-out-functions-when-exposing-a-class-tp18412325p18456336.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From david.philp at anu.edu.au Tue Jul 15 05:11:37 2008 From: david.philp at anu.edu.au (David Philp) Date: Tue, 15 Jul 2008 13:11:37 +1000 Subject: [C++-sig] question about vectors of pointers (boost python) Message-ID: <0262E8C9-0DAE-4CCE-9AD0-2B6062803F0A@anu.edu.au> Hi This is very much a newbie question... but I can't find the answer anywhere in the boost python documentation or elsewhere. Please feel free to give a URL instead of an answer. I have a vector of pointers in C++, and am trying to expose them to python. In particular I want to be able to iterate through them using e.g. for item in my_vec: print item.i This always fails with the following: TypeError: No to_python (by-value) converter found for C++ type: my_struct* (In every other way it works as expected.) The error seems reasonable: I have told Python about my_struct, but not what to do with my_struct*. I want Python to treat my_struct* as though it were a my_struct, but I can't figure out what I need to do. Do I need to use pointer_wrapper? Is there an example? Some context that may be important: it's not apparent from this example, but I intend for the vector to be owned by a C++ class that will be in existence for the lifetime of the Python program. So I am not overly concerned about details of memory management (unless they are more important than I thought.) Many thanks in advance! David -----------------Relevant C++ code----------------- struct my_struct { int i_; bool operator==(my_struct const& m) const {return i_ == m.i_;} }; BOOST_PYTHON_MODULE(pye) { class_("my_struct") .def_readwrite("i", &my_struct::i_) ; class_ >("my_struct_vector") .def(vector_indexing_suite >()) ; }; -----------------Relevant Python code----------------- from pye import * q = my_struct() q.i = 3 my_vec = my_struct_vector() my_vec.append(q) len(my_vec) print my_vec[0].i for item in my_vec : print item.i From roman.yakovenko at gmail.com Tue Jul 15 07:22:57 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 15 Jul 2008 08:22:57 +0300 Subject: [C++-sig] question about vectors of pointers (boost python) In-Reply-To: <0262E8C9-0DAE-4CCE-9AD0-2B6062803F0A@anu.edu.au> References: <0262E8C9-0DAE-4CCE-9AD0-2B6062803F0A@anu.edu.au> Message-ID: <7465b6170807142222h203c0184v7b3bdbb660cd3e0b@mail.gmail.com> On Tue, Jul 15, 2008 at 6:11 AM, David Philp wrote: > > Hi > > This is very much a newbie question... but I can't find the answer anywhere > in the boost python documentation or elsewhere. Please feel free to give a > URL instead of an answer. > > I have a vector of pointers in C++, and am trying to expose them to python. > In particular I want to be able to iterate through them using e.g. > > for item in my_vec: > print item.i > > This always fails with the following: > TypeError: No to_python (by-value) converter found for C++ type: my_struct* > (In every other way it works as expected.) > > The error seems reasonable: I have told Python about my_struct, but not > what to do with my_struct*. I want Python to treat my_struct* as though it > were a my_struct, but I can't figure out what I need to do. Do I need to > use pointer_wrapper? Is there an example? > > Some context that may be important: it's not apparent from this example, but > I intend for the vector to be owned by a C++ class that will be in existence > for the lifetime of the Python program. So I am not overly concerned about > details of memory management (unless they are more important than I > thought.) > > Many thanks in advance! > > David > > -----------------Relevant C++ code----------------- > > struct my_struct > { > int i_; > bool operator==(my_struct const& m) const {return i_ == m.i_;} > }; > > BOOST_PYTHON_MODULE(pye) > { > class_("my_struct") > .def_readwrite("i", &my_struct::i_) > ; > > class_ >("my_struct_vector") > .def(vector_indexing_suite >()) > ; > }; > > > -----------------Relevant Python code----------------- > > from pye import * > q = my_struct() > q.i = 3 > > my_vec = my_struct_vector() > my_vec.append(q) > > len(my_vec) > print my_vec[0].i > > for item in my_vec : > print item.i I think you should use NoProxy parameter and set it to true: http://www.boost.org/doc/libs/1_35_0/libs/python/doc/v2/indexing.html class_ >("my_struct_vector") .def(vector_indexing_suite, true >()) -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From david.philp at anu.edu.au Tue Jul 15 07:37:55 2008 From: david.philp at anu.edu.au (David Philp) Date: Tue, 15 Jul 2008 15:37:55 +1000 Subject: [C++-sig] question about vectors of pointers (boost python) In-Reply-To: <7465b6170807142222h203c0184v7b3bdbb660cd3e0b@mail.gmail.com> References: <0262E8C9-0DAE-4CCE-9AD0-2B6062803F0A@anu.edu.au> <7465b6170807142222h203c0184v7b3bdbb660cd3e0b@mail.gmail.com> Message-ID: On 15/07/2008, at 3:22 PM, Roman Yakovenko wrote: > On Tue, Jul 15, 2008 at 6:11 AM, David Philp > wrote: >> >> Hi >> >> This is very much a newbie question... but I can't find the answer >> anywhere >> in the boost python documentation or elsewhere. Please feel free >> to give a >> URL instead of an answer. >> >> I have a vector of pointers in C++, and am trying to expose them to >> python. >> In particular I want to be able to iterate through them using e.g. >> >> for item in my_vec: >> print item.i >> >> This always fails with the following: >> TypeError: No to_python (by-value) converter found for C++ type: >> my_struct* >> (In every other way it works as expected.) >> >> The error seems reasonable: I have told Python about my_struct, >> but not >> what to do with my_struct*. I want Python to treat my_struct* as >> though it >> were a my_struct, but I can't figure out what I need to do. Do I >> need to >> use pointer_wrapper? Is there an example? >> >> Some context that may be important: it's not apparent from this >> example, but >> I intend for the vector to be owned by a C++ class that will be in >> existence >> for the lifetime of the Python program. So I am not overly >> concerned about >> details of memory management (unless they are more important than I >> thought.) >> >> Many thanks in advance! >> >> David >> >> -----------------Relevant C++ code----------------- >> >> struct my_struct >> { >> int i_; >> bool operator==(my_struct const& m) const {return i_ == m.i_;} >> }; >> >> BOOST_PYTHON_MODULE(pye) >> { >> class_("my_struct") >> .def_readwrite("i", &my_struct::i_) >> ; >> >> class_ >("my_struct_vector") >> .def(vector_indexing_suite >()) >> ; >> }; >> >> >> -----------------Relevant Python code----------------- >> >> from pye import * >> q = my_struct() >> q.i = 3 >> >> my_vec = my_struct_vector() >> my_vec.append(q) >> >> len(my_vec) >> print my_vec[0].i >> >> for item in my_vec : >> print item.i > > I think you should use NoProxy parameter and set it to true: > http://www.boost.org/doc/libs/1_35_0/libs/python/doc/v2/indexing.html > > class_ >("my_struct_vector") > .def(vector_indexing_suite, true >()) I tried that (it looks likely) but fails with the same error. (No to_python (by-value) converter found for C++ type: my_struct*). Thanks, though I'm hoping for more answers... D From Charles.Lesire at onera.fr Tue Jul 15 08:03:15 2008 From: Charles.Lesire at onera.fr (Charles Lesire-Cabaniols) Date: Tue, 15 Jul 2008 08:03:15 +0200 Subject: [C++-sig] Downloading Gcc-Xml for Ubuntu Message-ID: <487C3DA3.6080908@onera.fr> Hi folks, I'm ame trying to use Py++ but I have a problem when parsing using gccxml. I have gccxml v0.7.0 installed, which it appers to be not up-to-date. I am using Ubuntu, avec version 0.7.0 seems to be the only one package available. How to install a more recent version ? Thanks Charles. -------------- next part -------------- A non-text attachment was scrubbed... Name: Charles_Lesire.vcf Type: text/x-vcard Size: 339 bytes Desc: not available URL: From roman.yakovenko at gmail.com Tue Jul 15 08:15:02 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 15 Jul 2008 09:15:02 +0300 Subject: [C++-sig] Downloading Gcc-Xml for Ubuntu In-Reply-To: <487C3DA3.6080908@onera.fr> References: <487C3DA3.6080908@onera.fr> Message-ID: <7465b6170807142315n4f614fecp7ef4c4e6df3f0a35@mail.gmail.com> 2008/7/15 Charles Lesire-Cabaniols : > Hi folks, > > I'm ame trying to use Py++ but I have a problem when parsing using gccxml. > > I have gccxml v0.7.0 installed, which it appers to be not up-to-date. I am > using Ubuntu, avec version 0.7.0 seems to be the only one package available. > > How to install a more recent version ? Just follow the instructions from: http://gccxml.org/HTML/Install.html It is really that simple. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From Charles.Lesire at onera.fr Tue Jul 15 08:18:13 2008 From: Charles.Lesire at onera.fr (Charles Lesire-Cabaniols) Date: Tue, 15 Jul 2008 08:18:13 +0200 Subject: [C++-sig] Downloading Gcc-Xml for Ubuntu In-Reply-To: <7465b6170807142315n4f614fecp7ef4c4e6df3f0a35@mail.gmail.com> References: <487C3DA3.6080908@onera.fr> <7465b6170807142315n4f614fecp7ef4c4e6df3f0a35@mail.gmail.com> Message-ID: <487C4125.9070706@onera.fr> Thanks. But the version available for download on the website is 0.6 while I am looking for version 0.9. Where could I find it ? Charles. Roman Yakovenko wrote: > 2008/7/15 Charles Lesire-Cabaniols : >> Hi folks, >> >> I'm ame trying to use Py++ but I have a problem when parsing using gccxml. >> >> I have gccxml v0.7.0 installed, which it appers to be not up-to-date. I am >> using Ubuntu, avec version 0.7.0 seems to be the only one package available. >> >> How to install a more recent version ? > > Just follow the instructions from: http://gccxml.org/HTML/Install.html > > It is really that simple. > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: Charles_Lesire.vcf Type: text/x-vcard Size: 339 bytes Desc: not available URL: From roman.yakovenko at gmail.com Tue Jul 15 08:29:41 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 15 Jul 2008 09:29:41 +0300 Subject: [C++-sig] Downloading Gcc-Xml for Ubuntu In-Reply-To: <487C4125.9070706@onera.fr> References: <487C3DA3.6080908@onera.fr> <7465b6170807142315n4f614fecp7ef4c4e6df3f0a35@mail.gmail.com> <487C4125.9070706@onera.fr> Message-ID: <7465b6170807142329wc2bf1cai9f7e9cedd2ffc0f0@mail.gmail.com> 2008/7/15 Charles Lesire-Cabaniols : > Thanks. > > But the version available for download on the website is 0.6 while I am > looking for version 0.9. > > Where could I find it ? You have to take it from CVS: http://gccxml.org/HTML/Download.html -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From foxmulder900 at yahoo.com Tue Jul 15 19:06:16 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Tue, 15 Jul 2008 10:06:16 -0700 (PDT) Subject: [C++-sig] leaving out functions when exposing a class In-Reply-To: <18456336.post@talk.nabble.com> References: <18412325.post@talk.nabble.com> <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> <18446355.post@talk.nabble.com> <7465b6170807141109r5b4ea237n1dc4849cbec76564@mail.gmail.com> <18456336.post@talk.nabble.com> Message-ID: <18470284.post@talk.nabble.com> Here is a better description of my problem... I am working on a game using the OGRE graphics library, I have a "GameObject" class that I want to expose to python so that it can be scripted. The game object uses classes and functions from OGRE so I had to add the OGRE includes to my jamroot file (the external ogre library gave me no problems). However my class #incudes a few other classes, some of which use a GUI library called Navi. So I added Navi to my jamroot file, and that is where i am getting the unresolved externals. I know that it is finding all the files it needs because there are many functions in Navi, and only 2 of them are unresolved. Like I said before I do not wish to directly access Navi from script, however my understanding is that I still have to link it since it is indirectly included by the class I do wish to wrap. Kinda lost on where to go next, any help would be much appreciated! -- View this message in context: http://www.nabble.com/leaving-out-functions-when-exposing-a-class-tp18412325p18470284.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From goldberg at coredp.com Tue Jul 15 19:17:03 2008 From: goldberg at coredp.com (Moe Goldberg) Date: Tue, 15 Jul 2008 13:17:03 -0400 Subject: [C++-sig] importing C++ module fails, but module is still in sys.modules In-Reply-To: <7465b6170807130059q1ff723bfm6a6de0c3deeb888f@mail.gmail.com> References: <4877A43E.4000507@coredp.com> <7465b6170807130059q1ff723bfm6a6de0c3deeb888f@mail.gmail.com> Message-ID: <487CDB8F.8040206@coredp.com> Roman Yakovenko wrote: > On Fri, Jul 11, 2008 at 9:19 PM, Moe Goldberg wrote: > >> I'm not sure if this is just a quirk in python, of if I am doing something >> wrong. >> If a C++ extension module throws an exception while it's initializing, the >> module is still stored in sys.modules (as opposed to a python module, which >> is not stored in sys.modules if it errors while being imported). >> >> For example: >> >> pymodule.py: >> raise RuntimeError("This python module fails.") >> >> cppmodule.cpp: >> #include >> #include >> BOOST_PYTHON_MODULE(cppmodule) >> { >> throw std::runtime_error("This C++ module fails."); >> } >> >> >>>>> import pymodule >>>>> >> Traceback (most recent call last): >> File "", line 1, in ? >> File "pymodule.py", line 2, in ? >> raise RuntimeError("This python module fails.") >> RuntimeError: This python module fails. >> >> >>>>> import cppmodule >>>>> >> Traceback (most recent call last): >> File "", line 1, in ? >> RuntimeError: This C++ module fails. >> >> >>>>> include sys >>>>> 'pymodule' in sys.modules >>>>> >> False >> >>>>> 'cppmodule' in sys.modules >>>>> >> True >> >> Is there a sane way to prevent pymodule from being added to sys.modules if >> importing it fails? >> > > It has nothing to do with boost.python. Same thing will happen with > pure Python module too. > > It does not happen with a pure python module (as my example above indicates). Do you mean that it happens with a regular C extension module that doesn't use boost.python? From roman.yakovenko at gmail.com Tue Jul 15 21:15:53 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Tue, 15 Jul 2008 22:15:53 +0300 Subject: [C++-sig] leaving out functions when exposing a class In-Reply-To: <18470284.post@talk.nabble.com> References: <18412325.post@talk.nabble.com> <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> <18446355.post@talk.nabble.com> <7465b6170807141109r5b4ea237n1dc4849cbec76564@mail.gmail.com> <18456336.post@talk.nabble.com> <18470284.post@talk.nabble.com> Message-ID: <7465b6170807151215t13e2be46x67c8b6402f42f1a8@mail.gmail.com> On Tue, Jul 15, 2008 at 8:06 PM, FoxMulder900 wrote: > > Here is a better description of my problem... It is still incomplete. > I am working on a game using the OGRE graphics library, I have a > "GameObject" class that I want to expose to python so that it can be > scripted. The game object uses classes and functions from OGRE so I had to > add the OGRE includes to my jamroot file (the external ogre library gave me > no problems). However my class #incudes a few other classes, some of which > use a GUI library called Navi. So I added Navi to my jamroot file, and that > is where i am getting the unresolved externals. I know that it is finding > all the files it needs because there are many functions in Navi, and only 2 > of them are unresolved. Like I said before I do not wish to directly access > Navi from script, however my understanding is that I still have to link it > since it is indirectly included by the class I do wish to wrap. Kinda lost > on where to go next, any help would be much appreciated! You didn't specified error message, compiler, platform. I also suggest you to try python-ogre mailing list: http://python-ogre.org/ If I remember right, the developers use and exposed to Python both libraries. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From rogeeff at gmail.com Wed Jul 16 00:39:33 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Tue, 15 Jul 2008 22:39:33 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ Message-ID: Hi, Trivial question (I hope) Let's say I have class A, which I export; class A { ... }; class_( "A" ); In python I wrote another class inherited from B: class B(A): pass Now I've got the function in C++: void foo( A& obj ) { // ?? question is what to do here } which is exported def( "foo", &foo ); and is called from python liek this: o = B() foo( o ) The question: How can I set object attribute inside the function foo implementation. More generally: how can I get access ot the underlying python object? essentially I want something like this: void foo( A& obj ) { boost::python::object o = get_py_object( obj ); o.attr( "field" ) = 1; } Please advide, Gennadiy From amohr at pixar.com Wed Jul 16 00:49:16 2008 From: amohr at pixar.com (Alex Mohr) Date: Tue, 15 Jul 2008 15:49:16 -0700 Subject: [C++-sig] set python attribute from C++ In-Reply-To: References: Message-ID: <487D296C.2060009@pixar.com> > essentially I want something like this: > > void foo( A& obj ) > { > boost::python::object o = get_py_object( obj ); > o.attr( "field" ) = 1; > } Maybe something like this: void foo(boost::python::object obj) { // Verify that obj can produce an A &. A &self = boost::python::extract(obj); obj.attr("field") = 1; } Alex From rwgk at yahoo.com Wed Jul 16 00:57:20 2008 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Tue, 15 Jul 2008 15:57:20 -0700 (PDT) Subject: [C++-sig] set python attribute from C++ Message-ID: <467430.79798.qm@web31101.mail.mud.yahoo.com> I'd rewrite foo (untested, rough): void foo( boost::python::object& obj ) { obj.attr( "field" ) = 1; A& a = boost::python::extract(obj); } I'm not sure if the extract call is correct, but I hope it is useful as a start. Ralf ----- Original Message ---- From: Gennadiy Rozental To: c++-sig at python.org Sent: Tuesday, July 15, 2008 3:39:33 PM Subject: [C++-sig] set python attribute from C++ Hi, Trivial question (I hope) Let's say I have class A, which I export; class A { ... }; class_( "A" ); In python I wrote another class inherited from B: class B(A): pass Now I've got the function in C++: void foo( A& obj ) { // ?? question is what to do here } which is exported def( "foo", &foo ); and is called from python liek this: o = B() foo( o ) The question: How can I set object attribute inside the function foo implementation. More generally: how can I get access ot the underlying python object? essentially I want something like this: void foo( A& obj ) { boost::python::object o = get_py_object( obj ); o.attr( "field" ) = 1; } Please advide, Gennadiy _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From dave at boostpro.com Wed Jul 16 01:37:03 2008 From: dave at boostpro.com (David Abrahams) Date: Tue, 15 Jul 2008 19:37:03 -0400 Subject: [C++-sig] set python attribute from C++ In-Reply-To: (Gennadiy Rozental's message of "Tue, 15 Jul 2008 22:39:33 +0000 (UTC)") References: Message-ID: <87skuahg80.fsf@mcbain.luannocracy.com> on Tue Jul 15 2008, Gennadiy Rozental wrote: > How can I set object attribute inside the function foo implementation. More > generally: how can I get access ot the underlying python object? > > essentially I want something like this: > > void foo( A& obj ) > { > boost::python::object o = get_py_object( obj ); > o.attr( "field" ) = 1; > } I think this works better than the other suggestions: void foo( boost::shared_ptr a ) { boost::python::object o(a); o.attr( "field" ) = 1; } Please let me know if it works out. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From Maxi.Matthe at web.de Wed Jul 16 11:12:23 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Wed, 16 Jul 2008 11:12:23 +0200 Subject: [C++-sig] [boost.python] Exposing interfaces to python Message-ID: Hello! I want to expose an abstract class to python: class abstract { public: virtual void f() = 0; }; Then I want to write a function in python that accepts pointers to abstract: def func(abs): abs.f() In c++ I want to derive a concrete class from abstract: class concrete : public abstract { public: virtual void f() { cout << "Hi" << endl; } } Then I want to call the python function func with a pointer to a concrete object, so that func prints out "Hi". How can I achieve this? I do not want that users of python can derive from abstract, I just want to give python the interface to my class and pass pointers of concrete classes to this function. Are there possibilities? From roman.yakovenko at gmail.com Wed Jul 16 11:18:59 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 16 Jul 2008 12:18:59 +0300 Subject: [C++-sig] [boost.python] Exposing interfaces to python In-Reply-To: References: Message-ID: <7465b6170807160218o64096a8raa61635f8cee3aea@mail.gmail.com> On Wed, Jul 16, 2008 at 12:12 PM, Maximilian Matthe wrote: > Hello! > > I want to expose an abstract class to python: > > class abstract > { > public: > virtual void f() = 0; > }; > > Then I want to write a function in python that accepts pointers > to abstract: > > def func(abs): > abs.f() > > In c++ I want to derive a concrete class from abstract: > class concrete : public abstract > { > public: > virtual void f() { cout << "Hi" << endl; } > } > > Then I want to call the python function func with a pointer to > a concrete object, so that func prints out "Hi". > > How can I achieve this? I do not want that users of python can derive > from abstract, I just want to give python the interface to my class > and pass pointers of concrete classes to this function. > > Are there possibilities? Yes, use "noncopyable" in class definition and no_init as class_< ... > constructor argument. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From rogeeff at gmail.com Wed Jul 16 21:48:13 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 16 Jul 2008 19:48:13 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <487D296C.2060009@pixar.com> Message-ID: Alex Mohr pixar.com> writes: > > > essentially I want something like this: > > > > void foo( A& obj ) > > { > > boost::python::object o = get_py_object( obj ); > > o.attr( "field" ) = 1; > > } > > Maybe something like this: > > void foo(boost::python::object obj) { This is really not an option. This function have to handle other types that are not python related From rogeeff at gmail.com Wed Jul 16 22:03:23 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 16 Jul 2008 20:03:23 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87skuahg80.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > > > on Tue Jul 15 2008, Gennadiy Rozental wrote: > > > How can I set object attribute inside the function foo implementation. More > > generally: how can I get access ot the underlying python object? > > > > essentially I want something like this: > > > > void foo( A& obj ) > > { > > boost::python::object o = get_py_object( obj ); > > o.attr( "field" ) = 1; > > } > > I think this works better than the other suggestions: > > void foo( boost::shared_ptr a ) > { > boost::python::object o(a); > o.attr( "field" ) = 1; > } > > Please let me know if it works out. This one does work. But if you switch to intrusive_ptr it;s not anymore ;(. And this is exactly the scenario I am using. Why is that?? What's more my problem is a bit more complicated. What I ma after is to initialize object A in it's init method (ideally would be in constructor, but this is obviously impossible - derived class constructor in python is not even called yet). So the usage scenario is something like this: // this may create objects based on pure C++ classes // or classes implemented in python. boost::intrusive_ptr obj = Factory::create(....); obj->init(); init is virtual void init() method of class Base Now let's say we have class PythonBase inherited from Base, that will serve as a base class to all python classes. Now inside PythonBase init implementation I need to do something like: void PythonBase::init() { m_object = ... // ?? what should go there } Inside init function I want to get a hold of actual python object and cache it. At the moment I jump through hoops do achieve this. 1. PythonBase is inherited from wrapper 2. m_object is assigned like this: bp::override o = this->get_override( "py_object" ); return bp::call( o.ptr() ); 3. During preprocessing phase i add mixin to all my python classes with method def py_object(s): return s It works. But it's quite cumbersome. Any recomendations? From rogeeff at gmail.com Wed Jul 16 22:12:28 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 16 Jul 2008 20:12:28 +0000 (UTC) Subject: [C++-sig] return object from factory function Message-ID: Hi, I've got factory function that logically looks like this (in reality it's pluggable factory - but this does not make difference for this question): Base* Factory::create( .... ) { .... case python_object: boost::python::object obj = m_python_type(); return boost::python::extract( obj )(); } Here PythonBase is inherited from Base and is exported to python so that python classes can inherit from it. m_python_type is pre-cached reference to the python type corresponding to the class inherited from exported PythonBase. I've noticed though that it does not work if written like above. python object is destroyed as soon as we leave create scope. what I am end up doing is adding this statement: Py_INCREF( obj.ptr() ); Is this right thing to do? Can I avoid C API somehow? Do I need matching DECREF somewhere? Thanks, Gennadiy From dave at boostpro.com Wed Jul 16 22:28:06 2008 From: dave at boostpro.com (David Abrahams) Date: Wed, 16 Jul 2008 16:28:06 -0400 Subject: [C++-sig] set python attribute from C++ In-Reply-To: (Gennadiy Rozental's message of "Wed, 16 Jul 2008 20:03:23 +0000 (UTC)") References: <87skuahg80.fsf@mcbain.luannocracy.com> Message-ID: <87k5fl1smh.fsf@mcbain.luannocracy.com> on Wed Jul 16 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: > >> >> >> on Tue Jul 15 2008, Gennadiy Rozental wrote: >> >> > How can I set object attribute inside the function foo implementation. More >> > generally: how can I get access ot the underlying python object? >> > >> > essentially I want something like this: >> > >> > void foo( A& obj ) >> > { >> > boost::python::object o = get_py_object( obj ); >> > o.attr( "field" ) = 1; >> > } >> >> I think this works better than the other suggestions: >> >> void foo( boost::shared_ptr a ) >> { >> boost::python::object o(a); >> o.attr( "field" ) = 1; >> } >> >> Please let me know if it works out. > > This one does work. But if you switch to intrusive_ptr it;s not anymore ;(. And > this is exactly the scenario I am using. Why is that?? shared_ptr is special. Custom deleters allow us to do some magical things, by maintaining ownership of the Python object that wraps the C++ object. Why do you want to use intrusive_ptr here? > What's more my problem is a bit more complicated. What I ma after is to > initialize object A in it's init method (ideally would be in constructor, but > this is obviously impossible - derived class constructor in python is not even > called yet). I don't understand what you're saying. All C++ class instances will be constructed with a real call to their constructor. > So the usage scenario is something like this: > > // this may create objects based on pure C++ classes > // or classes implemented in python. > boost::intrusive_ptr obj = Factory::create(....); This can't work for "classes implemented in Python." The intrusive_ptr will not be able to maintain Python's reference count. > obj->init(); > > init is virtual void init() method of class Base I don't understand its purpose. > Now let's say we have class PythonBase inherited from Base, that will serve as a > base class to all python classes. Now inside PythonBase init implementation I > need to do something like: > > void > PythonBase::init() > { > m_object = ... // ?? what should go there > } > > Inside init function I want to get a hold of actual python object and cache it. It sounds like you're trying to invert the natural ownership relationship. Python wrapper objects own their underlying C++ (sub)objects, not the other way around. > At the moment I jump through hoops do achieve this. > > 1. PythonBase is inherited from wrapper > 2. m_object is assigned like this: > bp::override o = this->get_override( "py_object" ); > return bp::call( o.ptr() ); Equivalent but cleaner: return this->get_override("py_object")(); > 3. During preprocessing phase i add mixin to all my python classes with method > def py_object(s): > return s > > It works. But it's quite cumbersome. > > Any recomendations? First, I would consider whether this scheme is a good idea. It sounds pretty contorted. There's usually a fairly clean way to get what you want, which doesn't involve cacheing the identity of the Python wrapper. Using shared_ptr is a good way to get there. Any python object wrapping a C++ object of type T can be converted to a shared_ptr called x, and object(x) will always get you back to the original wrapping Python object. If there's a better way, you can skip the rest of these: Second, I would store a python WeakRef in m_object. You don't want to dereference a dangling pointer. Finally, I would replace PythonBase::init with a _static_ member function void PythonBase::init( boost::shared_ptr s ) { s->m_object = WhateverYouNeedToCreateAWeakRef(bp::object(s)) } HTH, -- Dave Abrahams BoostPro Computing http://www.boostpro.com From dave at boostpro.com Wed Jul 16 22:29:38 2008 From: dave at boostpro.com (David Abrahams) Date: Wed, 16 Jul 2008 16:29:38 -0400 Subject: [C++-sig] return object from factory function In-Reply-To: (Gennadiy Rozental's message of "Wed, 16 Jul 2008 20:12:28 +0000 (UTC)") References: Message-ID: <87fxq91sjx.fsf@mcbain.luannocracy.com> on Wed Jul 16 2008, Gennadiy Rozental wrote: > what I am end up doing is adding > this statement: > > Py_INCREF( obj.ptr() ); > > Is this right thing to do? Almost never > Can I avoid C API somehow? Usually. Unfortunately I don't understand what you're doing well enough yet to be able to advise. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From rogeeff at gmail.com Wed Jul 16 23:13:10 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 16 Jul 2008 21:13:10 +0000 (UTC) Subject: [C++-sig] return object from factory function References: <87fxq91sjx.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > Unfortunately I don't understand what you're doing well enough yet to be > able to advise. Let me try again. Here is my create function implementation: Base* Factory::create( .... ) { .... case python_object: boost::python::object obj = m_python_type(); return boost::python::extract( obj )(); } As you can see obj is automatic variable, which gets destructed as we leave the function create scope. Reference counter is decreased and underlying python object is destroyed in turn. What I need is to prevent it, because I want to return pointer to it from this function. It should work the same way as if I would write new DerivedFromBase(...) Gennadiy From dave at boostpro.com Wed Jul 16 23:22:35 2008 From: dave at boostpro.com (David Abrahams) Date: Wed, 16 Jul 2008 17:22:35 -0400 Subject: [C++-sig] return object from factory function In-Reply-To: (Gennadiy Rozental's message of "Wed, 16 Jul 2008 21:13:10 +0000 (UTC)") References: <87fxq91sjx.fsf@mcbain.luannocracy.com> Message-ID: <87y741zfqc.fsf@mcbain.luannocracy.com> on Wed Jul 16 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: >> Unfortunately I don't understand what you're doing well enough yet to be >> able to advise. > > Let me try again. Here is my create function implementation: > > Base* > Factory::create( .... ) > { > .... > case python_object: > boost::python::object obj = m_python_type(); > > return boost::python::extract( obj )(); > } > > As you can see obj is automatic variable, which gets destructed as we leave the > function create scope. Reference counter is decreased and underlying python > object is destroyed in turn. What I need is to prevent it, because I want to > return pointer to it from this function. It should work the same way as if I > would write > new DerivedFromBase(...) So extract and return a shared_ptr. That will maintain ownership of the Python object for you. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From rogeeff at gmail.com Wed Jul 16 23:51:35 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 16 Jul 2008 21:51:35 +0000 (UTC) Subject: [C++-sig] differencein memory management Message-ID: Hi David, I plan to reply to your other post, but before I do that can't you explain to me difference in memory/ownership/lifecycle management in between following export statements: class_,... class_,... class_ (Gennadiy Rozental's message of "Wed, 16 Jul 2008 21:51:35 +0000 (UTC)") References: Message-ID: <87tzepzbcy.fsf@mcbain.luannocracy.com> on Wed Jul 16 2008, Gennadiy Rozental wrote: > Hi David, > > I plan to reply to your other post, but before I do that can't you explain to me > difference in memory/ownership/lifecycle management in between following export > statements: > > class_,... > class_,... > class_ Hello! I know, this question is somehow often asked, but I did not find the solution for my problem. I managed to implement a simple to_python converter for any wxObject: template struct convert_wxObject { static PyObject* convert(Obj const& o) { PyObject* arg = wxPyMake_wxObject(const_cast(&o), false); if(!arg) throw python_error("Object is not convertible to wxPython!"); return arg; } }; This struct works for any wxWidgets object. At least if I want to pass them from c++ to python. What does not work is the following: // c++: wxWindow* getWindow(); // python: getWindow().Hide() I get the following error: Traceback (most recent call last): File "test.py", line 31, in testit getWindow().Hide() TypeError: No Python class registered for C++ class class wxWindow. How can I tell boost.python to use my conversion above? Practically it seems to be the same to me, if I convert a return value from a c++-function to python or convert a c++-parameter for a python function. Both is converting from c++ to python. so why does that not work? I appreciate any help :-) Max From rwgk at yahoo.com Thu Jul 17 02:50:15 2008 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Wed, 16 Jul 2008 17:50:15 -0700 (PDT) Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python Message-ID: <220147.76485.qm@web31104.mail.mud.yahoo.com> That looks interesting... Do you have a long list of boost::python::to_python_converter<> instantiations? Ralf ----- Original Message ---- From: Maximilian Matthe To: c++-sig at python.org Sent: Wednesday, July 16, 2008 4:11:02 PM Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python Hello! I know, this question is somehow often asked, but I did not find the solution for my problem. I managed to implement a simple to_python converter for any wxObject: template struct convert_wxObject { static PyObject* convert(Obj const& o) { PyObject* arg = wxPyMake_wxObject(const_cast(&o), false); if(!arg) throw python_error("Object is not convertible to wxPython!"); return arg; } }; This struct works for any wxWidgets object. At least if I want to pass them from c++ to python. What does not work is the following: // c++: wxWindow* getWindow(); // python: getWindow().Hide() I get the following error: Traceback (most recent call last): File "test.py", line 31, in testit getWindow().Hide() TypeError: No Python class registered for C++ class class wxWindow. How can I tell boost.python to use my conversion above? Practically it seems to be the same to me, if I convert a return value from a c++-function to python or convert a c++-parameter for a python function. Both is converting from c++ to python. so why does that not work? I appreciate any help :-) Max _______________________________________________ C++-sig mailing list C++-sig at python.org http://mail.python.org/mailman/listinfo/c++-sig From Maxi.Matthe at web.de Thu Jul 17 08:57:36 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Thu, 17 Jul 2008 08:57:36 +0200 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: <220147.76485.qm@web31104.mail.mud.yahoo.com> References: <220147.76485.qm@web31104.mail.mud.yahoo.com> Message-ID: Ralf W. Grosse-Kunstleve schrieb: > That looks interesting... > Do you have a long list of boost::python::to_python_converter<> instantiations? > Ralf > > Yes, i instantiate a lot of bp::to_python_converter with this struct in the BOOST_PYTHON_MODULE-Scope with every class I want to pass to python and that was registered by swig. But that does not answer my question :-) > > > ----- Original Message ---- > From: Maximilian Matthe > To: c++-sig at python.org > Sent: Wednesday, July 16, 2008 4:11:02 PM > Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python > > Hello! > > I know, this question is somehow often asked, but I did not find the > solution for my problem. > > I managed to implement a simple to_python converter for any wxObject: > > template > struct convert_wxObject > { > static PyObject* convert(Obj const& o) > { > PyObject* arg = wxPyMake_wxObject(const_cast(&o), false); > if(!arg) > throw python_error("Object is not convertible to wxPython!"); > return arg; > } > }; > > This struct works for any wxWidgets object. At least if I want to > pass them from c++ to python. > > What does not work is the following: > > // c++: > wxWindow* getWindow(); > > // python: > getWindow().Hide() > > I get the following error: > Traceback (most recent call last): > File "test.py", line 31, in testit > getWindow().Hide() > TypeError: No Python class registered for C++ class class wxWindow. > > How can I tell boost.python to use my conversion above? Practically it > seems to be the same to me, if I convert a return value from a > c++-function to python or convert a c++-parameter for a python function. > Both is converting from c++ to python. so why does that not work? > > I appreciate any help :-) > Max > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From rogeeff at gmail.com Thu Jul 17 09:04:14 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 07:04:14 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > > This one does work. But if you switch to intrusive_ptr it;s not > > anymore ;(. And this is exactly the scenario I am using. Why > > is that?? > > shared_ptr is special. Custom deleters allow us to do some magical > things, by maintaining ownership of the Python object that wraps > the C++ object. Why is that by the way? It seems to me that intrusive_ptr is treated like distant relative to shared_ptr, while the only real difference is in storage policy for the counter. > Why do you want to use intrusive_ptr here? It's not even intrusive_ptr, but rather our own home grown smart pointer with properties similar to intrusive_ptr. This is forced on me by the framework I am working in. > > What's more my problem is a bit more complicated. What I ma after is to > > initialize object A in it's init method (ideally would be in > > constructor, but > > this is obviously impossible - derived class constructor in > > python is not even called yet). > > I don't understand what you're saying. All C++ class instances will be > constructed with a real call to their constructor. I mean I can't do what I am doing inside init function inside A constructor, because constructor of derived class in not called yet. > > So the usage scenario is something like this: > > > > // this may create objects based on pure C++ classes > > // or classes implemented in python. > > boost::intrusive_ptr obj = Factory::create(....); > > This can't work for "classes implemented in Python." The intrusive_ptr > will not be able to maintain Python's reference count. This is really out of my hands. All our objects are memory managed through these intrusive_ptr like smart pointer. I guess what I need is to prevent Boost.Python from managing the C++ objects and manually sync lifetime of C++ anf python object. > It sounds like you're trying to invert the natural ownership > relationship. Python wrapper objects own their underlying C++ > (sub)objects, not the other way around. Ok. Here is my latest attempt schematically: class Base { // this one is intrusively reference counted // any framework object is required to inherit from it .... }; class_,noncopyable)( "Base" ) .... ; class PythonBase : public Base { public: .... void init( bp::object const& o ) { m_object = o; } void set_field( std::string const& field, intrusive_ptr value ) { // here I am using global conversion registry I maintain m_object.attr( field ) = convert_to_python_object( value ) } private: bp::object m_object; }; class_( "PythonBase" ) .... ; Base* PythonFactory::create(...) { bp::object obj = m_py_type(); PythonBase* ptr = bp::extract( obj ); ptr->init( obj ); return ptr; } On python side I've can now derive from PythonBase: class Derived(PythonBase): pass Now i am seems to be able to create instances of Derived class and set their field from c++. Does this solution make sence? Gennadiy From rogeeff at gmail.com Thu Jul 17 09:06:35 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 07:06:35 +0000 (UTC) Subject: [C++-sig] differencein memory management References: <87tzepzbcy.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > > class_,... > > class_,... > > class_ > The first two are identical. The third one leaks a C++ A when the > corresponding Python A loses its last reference. I guess I need the later - I want to manage C++ object lifecycle myself. But in this case I can't get from A* back to the python object, right? Gennadiy From rogeeff at gmail.com Thu Jul 17 09:11:18 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 07:11:18 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> Message-ID: Gennadiy Rozental gmail.com> writes: Forgot to mention two critical bits of info > class PythonBase : public Base { > public: // release python object ~PythonBase() { bp::decref( m_object ) } ... > Base* > PythonFactory::create(...) > { > bp::object obj = m_py_type(); > PythonBase* ptr = bp::extract( obj ); > > ptr->init( obj ); // make sure python object is not destroyed once we leave this scope bp::incref( obj ); > return ptr; > } Gennadiy From rogeeff at gmail.com Thu Jul 17 09:08:07 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 07:08:07 +0000 (UTC) Subject: [C++-sig] return object from factory function References: <87fxq91sjx.fsf@mcbain.luannocracy.com> <87y741zfqc.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > So extract and return a shared_ptr. That will maintain ownership > of the Python object for you. Can't do. Factory methods are required to produce Base*. Plus in am forces to use intrusive ref counting From meine at informatik.uni-hamburg.de Thu Jul 17 10:43:13 2008 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Thu, 17 Jul 2008 10:43:13 +0200 Subject: [C++-sig] set python attribute from C++ In-Reply-To: References: <87k5fl1smh.fsf@mcbain.luannocracy.com> Message-ID: <200807171043.13660.meine@informatik.uni-hamburg.de> On Donnerstag 17 Juli 2008, Gennadiy Rozental wrote: > > > So the usage scenario is something like this: > > > > > > // this may create objects based on pure C++ classes > > > // or classes implemented in python. > > > boost::intrusive_ptr obj = Factory::create(....); > > > > This can't work for "classes implemented in Python." The intrusive_ptr > > will not be able to maintain Python's reference count. > > This is really out of my hands. All our objects are memory managed through > these intrusive_ptr like smart pointer. I guess what I need is to prevent > Boost.Python from managing the C++ objects and manually sync lifetime of > C++ anf python object. AFAIK, this is what SIP does, since Qt also manages the lifetime itself. However, that means that you have to check in every operation whether the underlying C++ object has been deleted (and throw a corresponding Python exception). Alternatively, you risk crashes and call that usage errors. (Depending on the actual object lifetimes, this may be practically feasible.) Ciao, / / .o. /--/ ..o / / ANS ooo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. URL: From rogeeff at gmail.com Thu Jul 17 17:28:45 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 15:28:45 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87k5fl1smh.fsf@mcbain.luannocracy.com> <200807171043.13660.meine@informatik.uni-hamburg.de> Message-ID: Hans Meine informatik.uni-hamburg.de> writes: > AFAIK, this is what SIP does, since Qt also manages the lifetime itself. > However, that means that you have to check in every operation whether the > underlying C++ object has been deleted (and throw a corresponding Python > exception). How can I do this? > Alternatively, you risk crashes and call that usage errors. > (Depending on the actual object lifetimes, this may be practically feasible.) I am calling incref on python object when it was constructed and calling decref in C++ object destructor. It seems decref should cause python object ot be immediately destroyed. Do u believe it'll be safe in this environment? From dave at boostpro.com Thu Jul 17 17:54:07 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 11:54:07 -0400 Subject: [C++-sig] set python attribute from C++ In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 07:04:14 +0000 (UTC)") References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> Message-ID: <874p6o7bhc.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: >> > This one does work. But if you switch to intrusive_ptr it;s not >> > anymore ;(. And this is exactly the scenario I am using. Why >> > is that?? >> >> shared_ptr is special. Custom deleters allow us to do some magical >> things, by maintaining ownership of the Python object that wraps >> the C++ object. > > Why is that by the way? It seems to me that intrusive_ptr is treated like > distant relative to shared_ptr, while the only real difference is in storage > policy for the counter. It doesn't have a deleter. > >> Why do you want to use intrusive_ptr here? > > It's not even intrusive_ptr, but rather our own home grown smart > pointer with properties similar to intrusive_ptr. This is forced on me > by the framework I am working in. I'm not entirely convinced that you need your own home grown smart pointer in the particular code we're discussing. Any wrapped T is convertible to shared_ptr, no matter what method is used to "hold" the T in the class_ declaration. >> > What's more my problem is a bit more complicated. What I ma after is to >> > initialize object A in it's init method (ideally would be in >> > constructor, but >> > this is obviously impossible - derived class constructor in >> > python is not even called yet). >> >> I don't understand what you're saying. All C++ class instances will be >> constructed with a real call to their constructor. > > I mean I can't do what I am doing inside init function inside A > constructor, because constructor of derived class in not called yet. Hm. >> > So the usage scenario is something like this: >> > >> > // this may create objects based on pure C++ classes >> > // or classes implemented in python. >> > boost::intrusive_ptr obj = Factory::create(....); >> >> This can't work for "classes implemented in Python." The intrusive_ptr >> will not be able to maintain Python's reference count. > > This is really out of my hands. All our objects are memory managed > through these intrusive_ptr like smart pointer. I guess what I need is > to prevent Boost.Python from managing the C++ objects and manually > sync lifetime of C++ anf python object. > >> It sounds like you're trying to invert the natural ownership >> relationship. Python wrapper objects own their underlying C++ >> (sub)objects, not the other way around. > > Ok. Here is my latest attempt schematically: > > class Base { > // this one is intrusively reference counted > // any framework object is required to inherit from it > > .... > }; > > class_,noncopyable)( "Base" ) ^^^^^^^^^^^^^^^^^^^ This automatically ensures that you can convert Python objects derived from the Python Base into an intrusive_ptr. Converting in the other direction works too, but it produces a new Python object. > .... > ; > > class PythonBase : public Base { > public: > .... > void init( bp::object const& o ) { m_object = o; } > > void set_field( std::string const& field, intrusive_ptr value ) > { > // here I am using global conversion registry I maintain > m_object.attr( field ) = convert_to_python_object( value ) I don't fully understand, but does it matter? > } > > private: > bp::object m_object; > }; > > class_( "PythonBase" ) ^^^^^^^^^^^ Very dangerous; could lead to leaks of C++ objects. However if you want the C++ object to own a Python object, it seems like an option. > .... > ; > > Base* > PythonFactory::create(...) > { > bp::object obj = m_py_type(); If m_py_type is the PythonBase Python class, there is nothing managing the C++ PythonBase object's lifetime. The fact that PythonBase is derived from Base and base is held by an intrusive_ptr makes no difference. OTOH, If m_py_type is the "Base" python class, the following extract should fail. > PythonBase* ptr = bp::extract( obj ); > > ptr->init( obj ); Now obj /and/ the unmanaged C++ PythonBase object are both managing the lifetime of the python object > return ptr; So I guess if you capture the Base* with an intrusive_ptr here, you're OK (so far). However, you haven'd dealt with the possibility of an exception during create(). > } > On python side I've can now derive from PythonBase: > > class Derived(PythonBase): > pass > > Now i am seems to be able to create instances of Derived class and set their > field from c++. Does this solution make sence? I'm not 100% certain, but it looks like it will leak C++ PythonBase instances. You might try putting some tracing statements in the ctors and dtors to see if they are actually going away when they should. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From dave at boostpro.com Thu Jul 17 17:55:49 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 11:55:49 -0400 Subject: [C++-sig] set python attribute from C++ In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 07:11:18 +0000 (UTC)") References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> Message-ID: <87zlog5wu2.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > Gennadiy Rozental gmail.com> writes: > > Forgot to mention two critical bits of info > >> class PythonBase : public Base { >> public: > // release python object > ~PythonBase() { bp::decref( m_object ) } > ... That looks like a recipe for double-deletion. When the bp::object m_object goes out of scope, it will take care of that part. >> Base* >> PythonFactory::create(...) >> { >> bp::object obj = m_py_type(); >> PythonBase* ptr = bp::extract( obj ); >> >> ptr->init( obj ); > > // make sure python object is not destroyed once we leave this scope > bp::incref( obj ); Oh, well in that case, it adds nothing. You may as well leave the incref/decref out. >> return ptr; >> } > > Gennadiy > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Dave Abrahams BoostPro Computing http://www.boostpro.com From dave at boostpro.com Thu Jul 17 17:56:52 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 11:56:52 -0400 Subject: [C++-sig] differencein memory management In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 07:06:35 +0000 (UTC)") References: <87tzepzbcy.fsf@mcbain.luannocracy.com> Message-ID: <87vdz45wsb.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: > >> > class_,... >> > class_,... >> > class_> >> The first two are identical. The third one leaks a C++ A when the >> corresponding Python A loses its last reference. > > I guess I need the later - I want to manage C++ object lifecycle myself. But in > this case I can't get from A* back to the python object, right? Not unless you add some machinery to do so explicitly. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From rogeeff at gmail.com Thu Jul 17 18:19:05 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 16:19:05 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <87zlog5wu2.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > >> Base* > >> PythonFactory::create(...) > >> { > >> bp::object obj = m_py_type(); > >> PythonBase* ptr = bp::extract( obj ); > >> > >> ptr->init( obj ); > > > > // make sure python object is not destroyed once we leave this scope > > bp::incref( obj ); > > Oh, well in that case, it adds nothing. You may as well leave the > incref/decref out. No. I can't (or at least it does not work for me). Without it python object is destroyed immediately once we leave create function scope and ptr become dangling pointer. Gennadiy From Mark.English at rbccm.com Thu Jul 17 18:04:57 2008 From: Mark.English at rbccm.com (English, Mark) Date: Thu, 17 Jul 2008 17:04:57 +0100 Subject: [C++-sig] set python attribute from C++ Message-ID: <75EF75D50F2523408605799EE2DD030E1DA0DD@SXLP-002.fg.rbc.com> > -----Original Message----- > From: c++-sig-bounces at python.org > [mailto:c++-sig-bounces at python.org] On Behalf Of Gennadiy Rozental > Sent: 17 July 2008 08:04 > To: c++-sig at python.org > Subject: Re: [C++-sig] set python attribute from C++ > > > On python side I've can now derive from PythonBase: > > class Derived(PythonBase): > pass > > Now i am seems to be able to create instances of Derived > class and set their field from c++. Does this solution make sence? I've had similar problems being forced to use other 3rd party shared pointers. There's a sample somewhere using smart_ptr somewhere which is a good starting point for discovering the issues. >From memory since I don't have the code handy, my last effort was storing a back_reference (using has_back_reference) to the Python object. As I think Mr Abrahams says, this is the wrong way round since the Python object is supposed to manage the C++ object's lifetime. It does however have the advantage of preserving Python object identity, leading to behaviour like that you describe where exposing the held type as my_smart_ptr , and holding some kind of reference to the PyObject, allows Python polymorhpism to work. However, the scenario I never got passed was this: Python code derives a class "PyFoo" from exposed C++ class "Foo". Python code creates an instance of "PyFoo" and passes it to C++ code which expects a my_smart_ptr. C++ code stores my_smart_ptr in a container for later retrieval. Python code deletes its reference to the "PyFoo" instance. "PyFoo" object reference count falls to 0 and object is no longer used on Python side. ...Time passes... Python code calls into C++ code to retrieve object stored in C++ collection of my_smart_ptr. Internally cached PyObject is returned who's reference count was decremented to 0 above. Nothing works. Alternatively a new PyObject wrapper for the C++ "Foo" instance originally contained within the "PyFoo" instance can be returned, but it will only appear as a "Foo", and not a "PyFoo". Following this route requires some mechanism to say from the C++ side that the PyObject needs to remain valid despite no references to it from Python. This then leads to issues of how to manage that additional lifetime information. All in all the holding a PyObject approach looked promising for a while, but I suspect it was a mistake. Before that I tried exposing boost::shared_ptr > as my held_type which I never really got off the ground because of the difficulty in exposing inheritance relationships with that level of indirection, so I wouldn't advocate that route either. I'm sorry that I haven't got any example code handy. I'll try to knock some up if that doesn't make enough sense, the next time I'm near a compiler. I think a better solution is a custom_deleter for your my_smart_ptr, assuming it supports custom deleters. Perhaps one that extends the one provided by boost::python. Also, we're veering away from the topic of how to set python attributes in C++. Good luck ! _______________________________________________________________________ This email is intended only for the use of the individual(s) to whom it is addressed and may be privileged and confidential. Unauthorised use or disclosure is prohibited. If you receive this e-mail in error, please advise immediately and delete the original message without copying, using, or telling anyone about its contents. This message may have been altered without your or our knowledge and the sender does not accept any liability for any errors or omissions in the message. This message does not create or change any contract. Royal Bank of Canada and its subsidiaries accept no responsibility for damage caused by any viruses contained in this email or its attachments. Emails may be monitored. RBC Capital Markets is a business name used by branches and subsidiaries of Royal Bank of Canada, including Royal Bank of Canada, London branch and Royal Bank of Canada Europe Limited. In accordance with English law requirements, details regarding Royal Bank of Canada Europe Limited are set out below: ROYAL BANK OF CANADA EUROPE LIMITED Registered in England and Wales 995939 Registered Address: 71 Queen Victoria Street, London, EC4V 4DE. Authorised and regulated by the Financial Service Authority. Member of the London Stock Exchange From rogeeff at gmail.com Thu Jul 17 18:20:29 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 16:20:29 +0000 (UTC) Subject: [C++-sig] differencein memory management References: <87tzepzbcy.fsf@mcbain.luannocracy.com> <87vdz45wsb.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > > I guess I need the later - I want to manage C++ object lifecycle myself. > > But in > > this case I can't get from A* back to the python object, right? > > Not unless you add some machinery to do so explicitly. > This is exactly what I did by storing bp:object inside A. Gennadiy From dave at boostpro.com Thu Jul 17 18:29:02 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 12:29:02 -0400 Subject: [C++-sig] differencein memory management In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 16:20:29 +0000 (UTC)") References: <87tzepzbcy.fsf@mcbain.luannocracy.com> <87vdz45wsb.fsf@mcbain.luannocracy.com> Message-ID: <877ibk5vap.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: >> > I guess I need the later - I want to manage C++ object lifecycle myself. >> > But in >> > this case I can't get from A* back to the python object, right? >> >> Not unless you add some machinery to do so explicitly. >> > > This is exactly what I did by storing bp:object inside A. Yes -- Dave Abrahams BoostPro Computing http://www.boostpro.com From dave at boostpro.com Thu Jul 17 18:30:51 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 12:30:51 -0400 Subject: [C++-sig] set python attribute from C++ In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 16:19:05 +0000 (UTC)") References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <87zlog5wu2.fsf@mcbain.luannocracy.com> Message-ID: <873am85v7o.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: >> >> Base* >> >> PythonFactory::create(...) >> >> { >> >> bp::object obj = m_py_type(); >> >> PythonBase* ptr = bp::extract( obj ); >> >> >> >> ptr->init( obj ); >> > >> > // make sure python object is not destroyed once we leave this scope >> > bp::incref( obj ); >> >> Oh, well in that case, it adds nothing. You may as well leave the >> incref/decref out. > > No. I can't (or at least it does not work for me). Without it python object is > destroyed immediately once we leave create function scope and ptr become > dangling pointer. Then m_object is a raw pointer and not a bp::object as you've described in your code examples. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From amohr at pixar.com Thu Jul 17 18:46:06 2008 From: amohr at pixar.com (Alex Mohr) Date: Thu, 17 Jul 2008 09:46:06 -0700 Subject: [C++-sig] differencein memory management In-Reply-To: References: <87tzepzbcy.fsf@mcbain.luannocracy.com> <87vdz45wsb.fsf@mcbain.luannocracy.com> Message-ID: <487F774E.4090407@pixar.com> >>> this case I can't get from A* back to the python object, right? >> Not unless you add some machinery to do so explicitly. > > This is exactly what I did by storing bp:object inside A. But then the problem is when you return a custom_ptr to python, boost::python won't know about the python object stored inside A, so it creates a new python object, which will cause havoc for you later. (You now have multiple python objects representing the same C++ object.) One thing required to really solve this, in my experience, is to (quite grossly) replace the to-python conversion that boost.python creates when you say class_<...>() with one that attempts to find your associated python object first (in your case, inside the A instance) and if it's there, return it. If it's not there, invoke the boost.python-generated to-python conversion to produce it, then store it inside the A instance for later. Alex From rogeeff at gmail.com Thu Jul 17 18:54:28 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 16:54:28 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <874p6o7bhc.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > > Why is that by the way? It seems to me that > > intrusive_ptr is treated like > > distant relative to shared_ptr, while the only real > > difference is in storage policy for the counter. > > It doesn't have a deleter. Is there some some strong underlying reason why it's can't be designed to support it? > >> Why do you want to use intrusive_ptr here? > > > > It's not even intrusive_ptr, but rather our own home > > grown smart pointer with properties similar to > > intrusive_ptr. This is forced on me by the framework > > I am working in. > > I'm not entirely convinced that you need your own home > grown smart pointer in the particular code we're > discussing. Any wrapped T is convertible to > shared_ptr, no matter what method is used to > "hold" the T in the class_ declaration. Not sure i understand what you mean here. Let's say I've exported my class like this: class,...> Now you are saying I can write the function foo like this: void foo( shared_ptr o ) { .... } What will happened with memory? Or custom deleter will somehow make it right? Tn any case it'll be quite confusing for unaware reader. > > Ok. Here is my latest attempt schematically: > > ... > > class_,noncopyable)( "Base" ) > ^^^^^^^^^^^^^^^^^^^ > > This automatically ensures that you can > convert Python objects derived from the Python > Base into an intrusive_ptr. Converting in > the other direction works too, but it produces > a new Python object. Yeah, it also produces object of wrong type. If I've got bp::object corresponding to the Python class Derived(PythonBase) bp::object constructed from pointer will hold different object of type PythonBase. > > class PythonBase : public Base { > > public: > > .... > > void set_field( std::string const& field, > > intrusive_ptr value ) > > { > > m_object.attr( field ) > > = convert_to_python_object( value ) > > I don't fully understand, but does it matter? Not really. It's just this function is primary target of this discussion: how to set python attributes from C++. This is where I am using the m_object, which I invest effort to get a hold to. > > } > > > > private: > > bp::object m_object; > > }; > > > > class_ ^^^^^^^^^^^ > Very dangerous; could lead to leaks of C++ > objects. However if you want the C++ object > to own a Python object, it seems like an option. > > > .... > > ; > > > > Base* > > PythonFactory::create(...) > > { > > bp::object obj = m_py_type(); > > If m_py_type is the PythonBase Python class, > there is nothing managing No. m_py_type is bp::object corresponding to the Derived type (there is whole registration phase which I omitted in this discussion) > the C++ PythonBase object's lifetime. C++ object lifetime is managed by my_intrusive_ptr it gets assigned to as a result of create function. Not really sure why create function have to return raw pointer instead of smart pointer - it predates me. > The fact that PythonBase is > derived from Base and base is held by an > intrusive_ptr makes no difference. OTOH, If > m_py_type is the "Base" python class, the following > extract should fail. > > > PythonBase* ptr = bp::extract( obj ); obj should be of type Derived. This extract should work fine. > > On python side I've can now derive from PythonBase: > > > > class Derived(PythonBase): > > pass > > > > Now i am seems to be able to create instances of > > Derived class and set their > > field from c++. Does this solution make sence? > > I'm not 100% certain, but it looks like it will leak > C++ PythonBase instances. You might try putting some > tracing statements in the ctors and dtors to see if > they are actually going away when they should. Did just that. Seems to be fine in my unit tests. Not very comprehensive yet though. Gennadiy From dave at boostpro.com Thu Jul 17 20:01:06 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 14:01:06 -0400 Subject: [C++-sig] set python attribute from C++ In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 16:54:28 +0000 (UTC)") References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <874p6o7bhc.fsf@mcbain.luannocracy.com> Message-ID: <87y7404cgt.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: >> > Why is that by the way? It seems to me that >> > intrusive_ptr is treated like >> > distant relative to shared_ptr, while the only real >> > difference is in storage policy for the counter. >> >> It doesn't have a deleter. > > Is there some some strong underlying reason why it's can't > be designed to support it? There are 2 "it"s in that sentence and I can't tell what either one refers to. >> I'm not entirely convinced that you need your own home >> grown smart pointer in the particular code we're >> discussing. Any wrapped T is convertible to >> shared_ptr, no matter what method is used to >> "hold" the T in the class_ declaration. > > Not sure i understand what you mean here. Let's say I've > exported my class like this: > > class,...> > > > Now you are saying I can write the function foo like this: > > void foo( shared_ptr o ) > { > .... > } Yes. > What will happened with memory? I don't understand the question. Could you be specific? > Or custom deleter will somehow make it right? It will be right. It Just Works (TM) > Tn any case it'll be quite confusing for unaware reader. What can I tell ya? Sometimes you need to add a few special C++ functions that will be wrapped solely for exposure to Python. Maybe that's what you should do here. >> > Ok. Here is my latest attempt schematically: >> > > ... >> > class_,noncopyable)( "Base" ) >> ^^^^^^^^^^^^^^^^^^^ >> >> This automatically ensures that you can >> convert Python objects derived from the Python >> Base into an intrusive_ptr. Converting in >> the other direction works too, but it produces >> a new Python object. > > Yeah, it also produces object of wrong type. If I've > got bp::object corresponding to the Python class > Derived(PythonBase) bp::object constructed from > pointer will hold different object of type PythonBase. Yes. I notice, by the way, that you didn't specify bases in your class_ >> > } >> > >> > private: >> > bp::object m_object; >> > }; >> > >> > class_> ^^^^^^^^^^^ >> Very dangerous; could lead to leaks of C++ >> objects. However if you want the C++ object >> to own a Python object, it seems like an option. >> >> > .... >> > ; >> > >> > Base* >> > PythonFactory::create(...) >> > { >> > bp::object obj = m_py_type(); >> >> If m_py_type is the PythonBase Python class, >> there is nothing managing > > No. m_py_type is bp::object corresponding to > the Derived type (there is whole registration > phase which I omitted in this discussion) Then I can't tell whether my statement below is true or not. >> the C++ PythonBase object's lifetime. > > C++ object lifetime is managed by my_intrusive_ptr > it gets assigned to as a result of create function. > Not really sure why create function have to return > raw pointer instead of smart pointer - it predates me. > >> The fact that PythonBase is >> derived from Base and base is held by an >> intrusive_ptr makes no difference. OTOH, If >> m_py_type is the "Base" python class, the following >> extract should fail. >> >> > PythonBase* ptr = bp::extract( obj ); > > obj should be of type Derived. This extract should work fine. OK >> > On python side I've can now derive from PythonBase: >> > >> > class Derived(PythonBase): >> > pass >> > >> > Now i am seems to be able to create instances of >> > Derived class and set their >> > field from c++. Does this solution make sence? >> >> I'm not 100% certain, but it looks like it will leak >> C++ PythonBase instances. You might try putting some >> tracing statements in the ctors and dtors to see if >> they are actually going away when they should. > > Did just that. Seems to be fine in my unit tests. > Not very comprehensive yet though. OK -- Dave Abrahams BoostPro Computing http://www.boostpro.com From rogeeff at gmail.com Thu Jul 17 20:08:13 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:08:13 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <87zlog5wu2.fsf@mcbain.luannocracy.com> <873am85v7o.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > on Thu Jul 17 2008, Gennadiy Rozental wrote: > > > David Abrahams boostpro.com> writes: > >> >> Base* > >> >> PythonFactory::create(...) > >> >> { > >> >> bp::object obj = m_py_type(); > >> >> PythonBase* ptr = bp::extract( obj ); > >> >> > >> >> ptr->init( obj ); > >> > > >> > // make sure python object is not destroyed once we leave > >> > // this scope > >> > bp::incref( obj ); > >> > >> Oh, well in that case, it adds nothing. You may as well leave > >> the incref/decref out. > > > > No. I can't (or at least it does not work for me). Without it > > python object is destroyed immediately once we leave create > > function scope and ptr become dangling pointer. > > Then m_object is a raw pointer and not a bp::object as you've > described in your code examples. Hmm. You right. I do not need it anymore. I used to need it because init method above was invoked later - after we left create function. Not anymore. I removed both incref/decref and everything works fine. Thanks Gennadiy From rogeeff at gmail.com Thu Jul 17 20:20:24 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:20:24 +0000 (UTC) Subject: [C++-sig] differencein memory management References: <87tzepzbcy.fsf@mcbain.luannocracy.com> <87vdz45wsb.fsf@mcbain.luannocracy.com> <487F774E.4090407@pixar.com> Message-ID: Alex Mohr pixar.com> writes: > > >>> this case I can't get from A* back to the python object, right? > >> Not unless you add some machinery to do so explicitly. > > > > This is exactly what I did by storing bp:object inside A. > > But then the problem is when you return a custom_ptr to python, I never do this. > boost::python won't know about the python object stored inside A, so it > creates a new python object, which will cause havoc for you later. (You > now have multiple python objects representing the same C++ object.) Yes. I've noticed this problem during development. > One thing required to really solve this, in my experience, is to (quite > grossly) replace the to-python conversion that boost.python creates when > you say class_<...>() with one that attempts to find your associated > python object first (in your case, inside the A instance) and if it's > there, return it. If it's not there, invoke the boost.python-generated > to-python conversion to produce it, then store it inside the A instance > for later. I've got similar global registry maintained in my library that knows how convert my custom_ptr to bp::object and back. I am using bp::object type as key in one direction and unique A::TYPE (owr reflection system provides one) in other. I never really thought about implementing it using boost.python to-value conversion mechanism. It might be possible. Gennadiy From rogeeff at gmail.com Thu Jul 17 20:31:37 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:31:37 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <874p6o7bhc.fsf@mcbain.luannocracy.com> <87y7404cgt.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > > Is there some some strong underlying reason why > > it's can't be designed to support it? > > There are 2 "it"s in that sentence and I can't > tell what either one refers to. Why can't intrusive_ptr be designed to support he same set of feature as shared_ptr? > > What will happened with memory? > > I don't understand the question. Could you be specific? > > > Or custom deleter will somehow make it right? > > It will be right. It Just Works (TM) So you are saying that if I export my class like this: class_ I can still write function foo like this: void foo( shared_ptr obj ) { bp::object pyobj( obj ); ... } And it will not call A destructor at the end of function, right? Plus pyobj will be of correct python type if obj type is actually one derived from A in python, right? Gennadiy From rogeeff at gmail.com Thu Jul 17 20:38:03 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:38:03 +0000 (UTC) Subject: [C++-sig] set python attribute from C++ References: <75EF75D50F2523408605799EE2DD030E1DA0DD@SXLP-002.fg.rbc.com> Message-ID: English, Mark rbccm.com> writes: > However, the scenario I never got passed was this: > > Python code derives a class "PyFoo" from exposed C++ class "Foo". > Python code creates an instance of "PyFoo" and passes it to C++ code > which expects a my_smart_ptr. > C++ code stores my_smart_ptr in a container for later retrieval. > Python code deletes its reference to the "PyFoo" instance. > "PyFoo" object reference count falls to 0 and object is no longer used It shouldn't be a problem in my case, since Foo instance holds reference back to the python object. Gennadiy From dave at boostpro.com Thu Jul 17 20:42:31 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 14:42:31 -0400 Subject: [C++-sig] set python attribute from C++ In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 18:31:37 +0000 (UTC)") References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <874p6o7bhc.fsf@mcbain.luannocracy.com> <87y7404cgt.fsf@mcbain.luannocracy.com> Message-ID: <87hcao4ajs.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: >> > Is there some some strong underlying reason why >> > it's can't be designed to support it? >> >> There are 2 "it"s in that sentence and I can't >> tell what either one refers to. > > Why can't intrusive_ptr be designed to support he > same set of feature as shared_ptr? You're asking the wrong person. It's not my baby. >> > What will happened with memory? >> >> I don't understand the question. Could you be specific? >> >> > Or custom deleter will somehow make it right? >> >> It will be right. It Just Works (TM) > > So you are saying that if I export my class like this: > > class_ > > I can still write function foo like this: > > void foo( shared_ptr obj ) > { > bp::object pyobj( obj ); > ... > } > > And it will not call A destructor at the end of > function, right? Not unless you've somehow deleted whatever was managing the lifetime of *obj before the function was called. > Plus pyobj will be of correct > python type if obj type is actually one derived > from A in python, right? correct. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From rogeeff at gmail.com Thu Jul 17 20:44:05 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:44:05 +0000 (UTC) Subject: [C++-sig] working with raw const pointers Message-ID: We having so much fun here, so I've decided to revive several questions I posted in boost lists, that never got any attention. Hi, In our system there are a lot of pointers to const objects flying around. I've got several problems in this regard. They can be exhibited by the following code snippet: a.cpp : class A{}; void boo1( A const* ) {} void boo2( A* ) {} A const* make_const_a() { return (A const*)0; } A* make_non_const_a() { return (A*)0; } std::vector make_vec() { return std::vector( 1 ); } .... class_( "A", bp::no_init ); class_ >( "AVec", bp::no_init ) .def( vector_indexing_suite >() ) ; def( "boo", &boo1 ); def( "boo", &boo2 ); def( "make_const_a", &make_const_a, return_value_policy() ); def( "make_non_const_a", &make_non_const_a, return_value_policy() ); def( "make_vec", &make_v ec ); Problem I. Access to mutable func Following python statement mymodule.boo( mymodule.make_non_const_a() ) seems to call incorrect function boo Problem II. Vector fails completely Following python statements vec = pytoolkit.make_vec(); for e in vec: pass produce TypeError: No to_python (by-value) converter found for C++ type: class A const * Any advise? Gennadiy From rogeeff at gmail.com Thu Jul 17 20:48:35 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:48:35 +0000 (UTC) Subject: [C++-sig] external constructors Message-ID: Hi, is there any way to register external constructor for C++ class? Specifically If I have class class A { ... }; I want to register constructor like this: class_(...) .def( "__init__", &make_A ) where make_A is defined something like: void make_A( A&, boost::python::list const& ); Doesn't seem to work like this. Gennadiy From meine at informatik.uni-hamburg.de Thu Jul 17 20:50:27 2008 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Thu, 17 Jul 2008 20:50:27 +0200 Subject: [C++-sig] set python attribute from C++ In-Reply-To: References: <200807171043.13660.meine@informatik.uni-hamburg.de> Message-ID: <200807172050.40528.meine@informatik.uni-hamburg.de> On Donnerstag 17 Juli 2008, Gennadiy Rozental wrote: > > Alternatively, you risk crashes and call that usage errors. > > (Depending on the actual object lifetimes, this may be practically > > feasible.) > > I am calling incref on python object when it was constructed and calling > decref in C++ object destructor. It seems decref should cause python object > ot be immediately destroyed. ..only if you did not create other references from Python! > Do u believe it'll be safe in this > environment? No, it is not safe. Whether it practically works, you must decide. Ciao, / / .o. /--/ ..o / / ANS ooo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. URL: From dave at boostpro.com Thu Jul 17 20:51:17 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 14:51:17 -0400 Subject: [C++-sig] working with raw const pointers In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 18:44:05 +0000 (UTC)") References: Message-ID: <878ww04a56.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > Problem I. Access to mutable func > > Following python statement > mymodule.boo( mymodule.make_non_const_a() ) > > seems to call incorrect function boo Python has no notion of "const", only immutability. Accordingly, Boost.Python has no notion of const either. Maybe it should, but it doesn't. > Problem II. Vector fails completely > > Following python statements > > vec = pytoolkit.make_vec(); > for e in vec: pass > > produce > > TypeError: No to_python (by-value) converter found for C++ type: class A const * This has something to do with the vector_indexing_suite. Probably we could add a remove_const somewhere and get it to work. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From rogeeff at gmail.com Thu Jul 17 20:46:21 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:46:21 +0000 (UTC) Subject: [C++-sig] frame corruption in python -> c++ -> python scenario Message-ID: Hi, I am experiencing strange issue I can't find solution for. Sorry I'll need a bit lengthy explanation to describe it. I am using boost python for both automation and embedding the same time. I wrote trivial unit test modules (can't use standard one). It has function check like this: def check( val ): check_impl( val ) def check_impl( val ): ... print "Error at line " + str(sys._getframe(2).f_lineno+1) ... ... This supposedly should produce error line location. And it does. Sometimes. test1.py: ... 8> check( False ) produces: Error in line 8: ... I've noticed though that in some cases line numbers are incorrect. I was able to narrow it down to the single function mymodule.foo() Before this function call line numbers are correct. After it incorrect. foo is a function implemented in c++ and exported using boost.python. I was able further to identify that the line at fault inside function foo implementation is the one invoking python function: void foo() { ... boost::python::object obj = ... obj(); ... } So. Finally the question: Is there way to fix/circumvent this somehow? Thanks, Gennadiy From rogeeff at gmail.com Thu Jul 17 20:59:19 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Thu, 17 Jul 2008 18:59:19 +0000 (UTC) Subject: [C++-sig] working with raw const pointers References: <878ww04a56.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams boostpro.com> writes: > > Problem II. Vector fails completely > > > > Following python statements > > > > vec = pytoolkit.make_vec(); > > for e in vec: pass > > > > produce > > > > TypeError: No to_python (by-value) converter found > > for C++ type: class A const * > > This has something to do with the vector_indexing_suite. > Probably we could add a remove_const somewhere and get > it to work. 1. Any workaround to make it work within bounds of boost 1.33.1? 2. Do I Need to submit bug report for this to be fixed in trunk? Gennadiy From dave at boostpro.com Thu Jul 17 21:13:36 2008 From: dave at boostpro.com (David Abrahams) Date: Thu, 17 Jul 2008 15:13:36 -0400 Subject: [C++-sig] working with raw const pointers In-Reply-To: (Gennadiy Rozental's message of "Thu, 17 Jul 2008 18:59:19 +0000 (UTC)") References: <878ww04a56.fsf@mcbain.luannocracy.com> Message-ID: <87zlog2ujj.fsf@mcbain.luannocracy.com> on Thu Jul 17 2008, Gennadiy Rozental wrote: > David Abrahams boostpro.com> writes: >> > Problem II. Vector fails completely >> > >> > Following python statements >> > >> > vec = pytoolkit.make_vec(); >> > for e in vec: pass >> > >> > produce >> > >> > TypeError: No to_python (by-value) converter found >> > for C++ type: class A const * >> >> This has something to do with the vector_indexing_suite. >> Probably we could add a remove_const somewhere and get >> it to work. > > 1. Any workaround to make it work within bounds of boost 1.33.1? I don't know, and don't have time to find out. > 2. Do I Need to submit bug report for this to be fixed in trunk? Probably. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From j.reid at mail.cryst.bbk.ac.uk Thu Jul 17 23:35:03 2008 From: j.reid at mail.cryst.bbk.ac.uk (John Reid) Date: Thu, 17 Jul 2008 22:35:03 +0100 Subject: [C++-sig] external constructors In-Reply-To: References: Message-ID: http://tinyurl.com/6zf9s6 e.g. class_< observed_data >( "ObservedData", "Observed data for gapped pssm model", no_init ) .def( "__init__", make_constructor( create_observed_data ) ) ; John. Gennadiy Rozental wrote: > Hi, > > is there any way to register external constructor for C++ class? > > Specifically If I have class > class A { > ... > }; > > I want to register constructor like this: > > class_(...) > .def( "__init__", &make_A ) > > where make_A is defined something like: > > void > make_A( A&, boost::python::list const& ); > > Doesn't seem to work like this. > > Gennadiy From jeff.webb at nta-inc.net Fri Jul 18 01:02:26 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Thu, 17 Jul 2008 18:02:26 -0500 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: References: Message-ID: <487FCF82.1000709@nta-inc.net> Since we're discussing the topic of shared_ptr, intrusive_ptr, and other custom smart pointers, I have a few observations and some related questions that I would like to share. I would love to hear some comments from the experts on these. (1) It seems that if you are designing a C++ library from the ground up to use with boost::python, it makes a lot of sense to use smart pointers internally in your C++ library. Python uses reference counting to manage objects, so if you use reference counting in your C++ library, you are laying the foundation for a seamless python interface instead of fighting Python's memory management. (2) The boost::python support for shared_ptr is fantastic, and if you make good use of shared_ptrs, many things will 'just work'. (3) If you decide to use smart pointers, there are two main reasons *not* to use shared_ptr: (a) your library uses a custom smart pointer internally (b) the memory usage of shared_ptr is not acceptable I have attempted to quantify the memory usage of shared_ptr vs. a simple intrusive_ptr implementation using the attached test program. I used valgrind to verify the dynamic memory usage. Here are the results: shared_ptr ---------- Each shared_ptr is the size of two raw pointers (one for the managed object, and one for the shared reference count): A total of 8 bytes on x86 or 16 bytes on x86_64 For each object that is managed by shared_ptrs, a shared reference count must be allocated. The memory usage for the shared reference count appears to be two integers and two pointers: A total of 16 bytes on x86 or 24 bytes on x86_64 When looking at the shared_ptr source code, I could only find one pointer in the shared reference count, but I cannot reconcile this with the memory usage reported by valgrind. I suppose it doesn't really matter, but the breakdown I found in the code is listed below. Maybe I am not looking at the right implementation for my system. sp_counted_impl_p: sp_counted_base: int use_count_; (4 bytes) int weak_count_; (4 bytes) X * (4 or 8 bytes) ??? (4 or 8 bytes) intrusive_ptr ------------- Each intrusive_ptr is the size of a raw pointer: A total of 4 bytes on x86 or 8 bytes on x86_64 For each object that is being managed by this intrusive_ptr implementation, an extra integer must be added to the object to hold the reference count: A total of 4 bytes on x86 or x86_64 (5) Summary: If you are wrapping a relatively small number of objects or you are wrapping very large objects, the overhead of shared_ptr is probably acceptable. If you are wrapping a large number of very small objects, then a custom intrusive_ptr solution is worth looking into. Any comments on these ideas? Is my summary of shared_ptr memory usage on target? Thanks, Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: shared_test.cpp Type: text/x-c++src Size: 1130 bytes Desc: not available URL: From rogeeff at gmail.com Fri Jul 18 07:52:26 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 18 Jul 2008 05:52:26 +0000 (UTC) Subject: [C++-sig] hasattr in c++ Message-ID: how do I have functionality similar to hasattr in c++ without any exception being throw/caught Gennadiy From rogeeff at gmail.com Fri Jul 18 08:03:39 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 18 Jul 2008 06:03:39 +0000 (UTC) Subject: [C++-sig] automating convertion y omy exception Message-ID: Hi, Boost.Python throws bp::error_already_set in case any error occurred. But I always need my own exception class to be thrown instead. In a result I've got tons oftry catch block like this: try { // do something boost python related } catch( bp::error_already_set & ) { throw MyException( __FUNCTION__, pyGetException() ); } (pyGetException uses Python C API to get details about error, though it's irrelevant to the question) Question: is there any way to "automate" it, so I can avoid all these try/catch blocks? From Maxi.Matthe at web.de Fri Jul 18 14:15:05 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Fri, 18 Jul 2008 14:15:05 +0200 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: References: Message-ID: Does nobody have an answer to that question? It must be possible, otherwise boost.python would not work with own classes. I foudn something about to_pythn_indirect but I dont know wether thats the right converter, or if I even have to write a new converter or something. Please help me... Greetings, Max Maximilian Matthe schrieb: > Hello! > > I know, this question is somehow often asked, but I did not find the > solution for my problem. > > I managed to implement a simple to_python converter for any wxObject: > > template > struct convert_wxObject > { > static PyObject* convert(Obj const& o) > { > PyObject* arg = wxPyMake_wxObject(const_cast(&o), false); > if(!arg) > throw python_error("Object is not convertible to wxPython!"); > return arg; > } > }; > > This struct works for any wxWidgets object. At least if I want to > pass them from c++ to python. > > What does not work is the following: > > // c++: > wxWindow* getWindow(); > > // python: > getWindow().Hide() > > I get the following error: > Traceback (most recent call last): > File "test.py", line 31, in testit > getWindow().Hide() > TypeError: No Python class registered for C++ class class wxWindow. > > How can I tell boost.python to use my conversion above? Practically it > seems to be the same to me, if I convert a return value from a > c++-function to python or convert a c++-parameter for a python function. > Both is converting from c++ to python. so why does that not work? > > I appreciate any help :-) > Max From shadowdog at sharkbyte.com Fri Jul 18 16:59:22 2008 From: shadowdog at sharkbyte.com (shadow_dog1) Date: Fri, 18 Jul 2008 07:59:22 -0700 (PDT) Subject: [C++-sig] [boost::python] Unable to call a python object Member Function Message-ID: <18531200.post@talk.nabble.com> I hope someone can help with this boost::python question. I create a python object and want to call a member function but it requires the 'self' reference to be passed in? Here is the python code: class config: def __init__(self, file): self._config = file def getfile(self, path): return path + self._config Here is c++ code: #include namespace python = boost::python; int _tmain(int argc, _TCHAR* argv[]) { Py_InitializeEx(0); python::object configMod = python::import("config_wrapper"); python::object config = configMod.attr("my.config"); config("tgx.config"); python::object val = config.attr("getfile")("c:\datadir\"); Py_Finalize(); } I get this exception when the code runs - "TypeError: unbound method getfile() must be called with config instance as first argument (got str instance instead)" I have tried passing the 'config' instance a the first param but still get the execption. The code works fine if i do not call a member function but instead call a normal function?? I'm stuck... -- View this message in context: http://www.nabble.com/-boost%3A%3Apython--Unable-to-call-a-python-object-Member-Function-tp18531200p18531200.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From amohr at pixar.com Fri Jul 18 18:07:19 2008 From: amohr at pixar.com (Alex Mohr) Date: Fri, 18 Jul 2008 09:07:19 -0700 Subject: [C++-sig] hasattr in c++ In-Reply-To: References: Message-ID: <4880BFB7.7080202@pixar.com> Gennadiy Rozental wrote: > how do I have functionality similar to hasattr in c++ without any exception > being throw/caught Something like this? bool hasattr(boost::python::object obj, std::string const &attrName) { return PyObject_HasAttrString(obj.ptr(), attrName.c_str()); } Alex From jeff.webb at nta-inc.net Fri Jul 18 18:53:35 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Fri, 18 Jul 2008 11:53:35 -0500 Subject: [C++-sig] set python attribute from C++ In-Reply-To: References: <87skuahg80.fsf@mcbain.luannocracy.com> <87k5fl1smh.fsf@mcbain.luannocracy.com> <874p6o7bhc.fsf@mcbain.luannocracy.com> <87y7404cgt.fsf@mcbain.luannocracy.com> Message-ID: <4880CA8F.2010701@nta-inc.net> Gennadiy Rozental wrote: > Why can't intrusive_ptr be designed to support he > same set of feature as shared_ptr? I think you can make intrusive_ptr work much like shared_ptr in boost::python, but you will have to add some extra code (and possibly data structures, depending on the features you desire). If you grep for shared_ptr in the boost::python code, you can see how the desired functionality is implemented and use that as a template. It may take a while to 'boostify' your mind in order to understand what is going on, however. I plan to post some intrusive_ptr examples over the next few days. I would like to get some input on my implementation, and it may prove useful to others as well. -Jeff From jeff.webb at nta-inc.net Fri Jul 18 19:13:06 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Fri, 18 Jul 2008 12:13:06 -0500 Subject: [C++-sig] set python attribute from C++ In-Reply-To: <75EF75D50F2523408605799EE2DD030E1DA0DD@SXLP-002.fg.rbc.com> References: <75EF75D50F2523408605799EE2DD030E1DA0DD@SXLP-002.fg.rbc.com> Message-ID: <4880CF22.1000105@nta-inc.net> English, Mark wrote: > However, the scenario I never got passed was this: > > Python code derives a class "PyFoo" from exposed C++ class "Foo". > Python code creates an instance of "PyFoo" and passes it to C++ code > which expects a my_smart_ptr. > C++ code stores my_smart_ptr in a container for later retrieval. > Python code deletes its reference to the "PyFoo" instance. > "PyFoo" object reference count falls to 0 and object is no longer used > on Python side. > ...Time passes... > Python code calls into C++ code to retrieve object stored in C++ > collection of my_smart_ptr. > Internally cached PyObject is returned who's reference count was > decremented to 0 above. > Nothing works. > > Alternatively a new PyObject wrapper for the C++ "Foo" instance > originally contained within the "PyFoo" instance can be returned, but it > will only appear as a "Foo", and not a "PyFoo". > > Following this route requires some mechanism to say from the C++ side > that the PyObject needs to remain valid despite no references to it from > Python. This then leads to issues of how to manage that additional > lifetime information. > > All in all the holding a PyObject approach looked promising for a while, > but I suspect it was a mistake. I did get this approach to work. In my implementation, I had two types of boost::python wrappers that I call persistent and non-persistent. Non-persistent python wrappers disappear when the python reference count goes to zero, which is often what you want when you are just exposing a C++ object. (No sense in keeping around wrappers that you may never use again.) If you are trying to extend a C++ object using python, then this behavior is not what you want. In this case, you need to use a persistent wrapper. Once a persistent python wrapper has been bound to a C++ object, it is not deleted until all references to the C++ object disappear. In other words, a persistent python wrapper is deleted at the same time as the underlying C++ object. Is this the behavior you are looking for? I hope to post some code to this list over the next few days. -Jeff From rogeeff at gmail.com Fri Jul 18 22:30:33 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 18 Jul 2008 20:30:33 +0000 (UTC) Subject: [C++-sig] accessing c++ attributes from python Message-ID: If I implement __getattr__ callback for C++ class, how do I report attribute "not found" condition so that KeyError is reported on python side? From amohr at pixar.com Fri Jul 18 23:18:14 2008 From: amohr at pixar.com (Alex Mohr) Date: Fri, 18 Jul 2008 14:18:14 -0700 Subject: [C++-sig] accessing c++ attributes from python In-Reply-To: References: Message-ID: <48810896.4050308@pixar.com> Gennadiy Rozental wrote: > If I implement __getattr__ callback for C++ class, how do I report attribute > "not found" condition so that KeyError is reported on python side? Something like this? PyErr_SetString(PyExc_KeyError, "your message"); boost::python::throw_error_already_set(); Alex From Maxi.Matthe at web.de Sun Jul 20 11:53:27 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Sun, 20 Jul 2008 11:53:27 +0200 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: <220147.76485.qm@web31104.mail.mud.yahoo.com> References: <220147.76485.qm@web31104.mail.mud.yahoo.com> Message-ID: Hi! I still have the problem, that I have described below. I found out, that the same problem appears with any class that is not registered with boost.python but only with a custom converter. Returning values of those custom objects works fine, but returning pointers to existing objects gives the conversion error. Traceback (most recent call last): File "test.py", line 31, in testit w = getWindow() TypeError: No Python class registered for C++ class class wxWindow. I read about to_python_indirect, and ResultConverterGenrator and so on, but the documentation remains unclear to me. I dont know, which operator/converter I have to add, that boost.python can convert pointers to existing objects, using the return value policiy reference_existing_object or something similar. Passing the pointers via shared_ptr also seems to work, but that is no possibility to me, cause my whole app is without shared_ptr and my functions only return pointers to always existing objects, like the main application window. It must be possible anyway... Max Ralf W. Grosse-Kunstleve schrieb: > That looks interesting... > Do you have a long list of boost::python::to_python_converter<> instantiations? > Ralf > > > > > ----- Original Message ---- > From: Maximilian Matthe > To: c++-sig at python.org > Sent: Wednesday, July 16, 2008 4:11:02 PM > Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python > > Hello! > > I know, this question is somehow often asked, but I did not find the > solution for my problem. > > I managed to implement a simple to_python converter for any wxObject: > > template > struct convert_wxObject > { > static PyObject* convert(Obj const& o) > { > PyObject* arg = wxPyMake_wxObject(const_cast(&o), false); > if(!arg) > throw python_error("Object is not convertible to wxPython!"); > return arg; > } > }; > > This struct works for any wxWidgets object. At least if I want to > pass them from c++ to python. > > What does not work is the following: > > // c++: > wxWindow* getWindow(); > > // python: > getWindow().Hide() > > I get the following error: > Traceback (most recent call last): > File "test.py", line 31, in testit > getWindow().Hide() > TypeError: No Python class registered for C++ class class wxWindow. > > How can I tell boost.python to use my conversion above? Practically it > seems to be the same to me, if I convert a return value from a > c++-function to python or convert a c++-parameter for a python function. > Both is converting from c++ to python. so why does that not work? > > I appreciate any help :-) > Max > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig From dave at boostpro.com Sun Jul 20 15:26:20 2008 From: dave at boostpro.com (David Abrahams) Date: Sun, 20 Jul 2008 09:26:20 -0400 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: (Maximilian Matthe's message of "Sun, 20 Jul 2008 11:53:27 +0200") References: <220147.76485.qm@web31104.mail.mud.yahoo.com> Message-ID: <87y73wadqb.fsf@mcbain.luannocracy.com> on Sun Jul 20 2008, Maximilian Matthe wrote: > Hi! > > I still have the problem, that I have described below. I found out, > that the same problem appears with any class that is not registered > with boost.python but only with a custom converter. Returning values > of those custom objects works fine, but returning pointers to existing > objects gives the conversion error. You probably need to register a converter for the pointer type (wxWindow*) as well as the class type. Actually I'd be a little surprised if you were actually returning wxWindow by value. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From Maxi.Matthe at web.de Sun Jul 20 15:36:43 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Sun, 20 Jul 2008 15:36:43 +0200 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: <87y73wadqb.fsf@mcbain.luannocracy.com> References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams schrieb: > on Sun Jul 20 2008, Maximilian Matthe wrote: > >> Hi! >> >> I still have the problem, that I have described below. I found out, >> that the same problem appears with any class that is not registered >> with boost.python but only with a custom converter. Returning values >> of those custom objects works fine, but returning pointers to existing >> objects gives the conversion error. > > You probably need to register a converter for the pointer type > (wxWindow*) as well as the class type. Actually I'd be a little > surprised if you were actually returning wxWindow by value. > I have already tried to add a converter for wxWindow*, but there were compiler errors that convert needs by value of const reference parameter. I dont want to return wxWindow by value, but by reference/adress. Thus the bp::reference_existing_object call policy. From dave at boostpro.com Sun Jul 20 15:42:31 2008 From: dave at boostpro.com (David Abrahams) Date: Sun, 20 Jul 2008 09:42:31 -0400 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: (Maximilian Matthe's message of "Sun, 20 Jul 2008 15:36:43 +0200") References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> Message-ID: <87ljzwaczc.fsf@mcbain.luannocracy.com> on Sun Jul 20 2008, Maximilian Matthe wrote: > David Abrahams schrieb: >> on Sun Jul 20 2008, Maximilian Matthe wrote: >> >>> Hi! >>> >>> I still have the problem, that I have described below. I found out, >>> that the same problem appears with any class that is not registered >>> with boost.python but only with a custom converter. Returning values >>> of those custom objects works fine, but returning pointers to existing >>> objects gives the conversion error. >> >> You probably need to register a converter for the pointer type >> (wxWindow*) as well as the class type. Actually I'd be a little >> surprised if you were actually returning wxWindow by value. >> > > I have already tried to add a converter for wxWindow*, but there were > compiler errors that convert needs by value of const reference > parameter. wxWindow* const& ? > I dont want to return wxWindow by value, but by reference/adress. Thus > the bp::reference_existing_object call policy. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From Maxi.Matthe at web.de Sun Jul 20 16:15:20 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Sun, 20 Jul 2008 16:15:20 +0200 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: <87ljzwaczc.fsf@mcbain.luannocracy.com> References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> <87ljzwaczc.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams schrieb: > on Sun Jul 20 2008, Maximilian Matthe wrote: > >> David Abrahams schrieb: >>> on Sun Jul 20 2008, Maximilian Matthe wrote: >>> >>>> Hi! >>>> >>>> I still have the problem, that I have described below. I found out, >>>> that the same problem appears with any class that is not registered >>>> with boost.python but only with a custom converter. Returning values >>>> of those custom objects works fine, but returning pointers to existing >>>> objects gives the conversion error. >>> You probably need to register a converter for the pointer type >>> (wxWindow*) as well as the class type. Actually I'd be a little >>> surprised if you were actually returning wxWindow by value. >>> >> I have already tried to add a converter for wxWindow*, but there were >> compiler errors that convert needs by value of const reference >> parameter. > > wxWindow* const& > > ? > >> I dont want to return wxWindow by value, but by reference/adress. Thus >> the bp::reference_existing_object call policy. > > Well, i checked that, but the problem remains: Heres the code: template struct convert_wxObjectPtr { static PyObject* convert(Ptr const& o) { PyObject* arg = wxPyMake_wxObject(const_cast(o), false); if(!arg) throw python_error("Object is not convertible to wxPython!"); return arg; } }; // code generated by Py++ struct IApp_wrapper : IApp, bp::wrapper< IApp > { virtual wxWindow * GetWndMain( ){ bp::override func_GetWndMain = this->get_override( "GetWndMain"); return func_GetWndMain( ); } }; // generated by Py++ BOOST_PYTHON_MODULE(ai) { bp::class_< IApp_wrapper, boost::noncopyable >( "IApp" ) .def("GetWndMain", bp::pure_virtual( (::wxWindow*(IApp::*)(())(&::IApp::GetWndMain) ), bp::return_value_policy< bp::reference_existing_object >() ); // provide custom converters. to_python_converter, false>(); to_python_converter, false>(); } ////// python: //////////////// # a is a pointer to IApp_wrapper a.GetWndMain().Hide() Traceback (most recent call last): File "PythonPlugin.py", line 34, in testit a.GetWndMain().Hide() TypeError: No Python class registered for C++ class class wxWindow From dave at boostpro.com Sun Jul 20 20:30:28 2008 From: dave at boostpro.com (David Abrahams) Date: Sun, 20 Jul 2008 14:30:28 -0400 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: (Maximilian Matthe's message of "Sun, 20 Jul 2008 16:15:20 +0200") References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> <87ljzwaczc.fsf@mcbain.luannocracy.com> Message-ID: <87prp8wgqj.fsf@mcbain.luannocracy.com> on Sun Jul 20 2008, Maximilian Matthe wrote: > David Abrahams schrieb: >> on Sun Jul 20 2008, Maximilian Matthe wrote: >> >>> David Abrahams schrieb: >>>> on Sun Jul 20 2008, Maximilian Matthe wrote: >>>> >>>>> Hi! >>>>> >>>>> I still have the problem, that I have described below. I found out, >>>>> that the same problem appears with any class that is not registered >>>>> with boost.python but only with a custom converter. Returning values >>>>> of those custom objects works fine, but returning pointers to existing >>>>> objects gives the conversion error. >>>> You probably need to register a converter for the pointer type >>>> (wxWindow*) as well as the class type. Actually I'd be a little >>>> surprised if you were actually returning wxWindow by value. >>>> >>> I have already tried to add a converter for wxWindow*, but there were >>> compiler errors that convert needs by value of const reference >>> parameter. >> >> wxWindow* const& >> >> ? >> >>> I dont want to return wxWindow by value, but by reference/adress. Thus >>> the bp::reference_existing_object call policy. You can't use that policy unless you're returning a Boost.Python-wrapped class. Its whole purpose in life is to make an instance of the class where the C++ object is held by raw pointer. I suggest you leave it out. > Well, i checked that, but the problem remains: > Heres the code: > > template > struct convert_wxObjectPtr > { > static PyObject* convert(Ptr const& o) > { > PyObject* arg = wxPyMake_wxObject(const_cast(o), false); I can't imagine what purpose that const_cast could serve. Surely wxPyMake_wxObject doesn't modify its first argument? I suggest you leave it out. > if(!arg) > throw python_error("Object is not convertible to wxPython!"); > return arg; > } > }; > // code generated by Py++ > struct IApp_wrapper : IApp, bp::wrapper< IApp > { > virtual wxWindow * GetWndMain( ){ > bp::override func_GetWndMain = this->get_override( "GetWndMain"); > return func_GetWndMain( ); > } > }; HTH, -- Dave Abrahams BoostPro Computing http://www.boostpro.com From rogeeff at gmail.com Sun Jul 20 20:44:18 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Sun, 20 Jul 2008 18:44:18 +0000 (UTC) Subject: [C++-sig] hasattr in c++ References: <4880BFB7.7080202@pixar.com> Message-ID: Alex Mohr pixar.com> writes: > > Gennadiy Rozental wrote: > > how do I have functionality similar to hasattr in c++ without any exception > > being throw/caught > > Something like this? > > bool hasattr(boost::python::object obj, std::string const &attrName) { > return PyObject_HasAttrString(obj.ptr(), attrName.c_str()); > } Thanks, this seems to work. Gennadiy From rogeeff at gmail.com Sun Jul 20 21:02:56 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Sun, 20 Jul 2008 19:02:56 +0000 (UTC) Subject: [C++-sig] accessing c++ attributes from python References: <48810896.4050308@pixar.com> Message-ID: Alex Mohr pixar.com> writes: > > Gennadiy Rozental wrote: > > If I implement __getattr__ callback for C++ class, how do I report attribute > > "not found" condition so that KeyError is reported on python side? > > Something like this? > > PyErr_SetString(PyExc_KeyError, "your message"); > boost::python::throw_error_already_set(); Thanks. This one works as well. But, why in a world Boost.Python does not provide nice C++ API? I should not be required to know anything about Python C API. In general I found this a common theme in Boost.Python. A lot of functionality is missing (sometimes most trivial) and some functionality that is implemented is only scarcely documented. In many cases asking help from experts is the only reliable way to make it work as desired. Gennadiy From rogeeff at gmail.com Mon Jul 21 04:01:58 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Mon, 21 Jul 2008 02:01:58 +0000 (UTC) Subject: [C++-sig] external constructors References: Message-ID: John Reid mail.cryst.bbk.ac.uk> writes: > > http://tinyurl.com/6zf9s6 Thanks. This worked out perfectly. Gennadiy From Maxi.Matthe at web.de Mon Jul 21 10:56:43 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Mon, 21 Jul 2008 10:56:43 +0200 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: <87prp8wgqj.fsf@mcbain.luannocracy.com> References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> <87ljzwaczc.fsf@mcbain.luannocracy.com> <87prp8wgqj.fsf@mcbain.luannocracy.com> Message-ID: David Abrahams schrieb: > on Sun Jul 20 2008, Maximilian Matthe wrote: > >> David Abrahams schrieb: >>> on Sun Jul 20 2008, Maximilian Matthe wrote: >>> >>>> on Sun Jul 20 2008, Maximilian Matthe wrote: >>>> I dont want to return wxWindow by value, but by reference/adress. Thus >>>> the bp::reference_existing_object call policy. > > You can't use that policy unless you're returning a Boost.Python-wrapped > class. Its whole purpose in life is to make an instance of the class > where the C++ object is held by raw pointer. I suggest you leave it out. > Uh, well, then this could be written into the documentation, couldn't it? Then I wouldn't have searched so long for a solution. > I can't imagine what purpose that const_cast could serve. Surely > wxPyMake_wxObject doesn't modify its first argument? I suggest you > leave it out. > No, the const_cast is needed. wxPyMake_wxObject wraps a PyObject around the passed wxObject (any wxWidgets-Class). This object is then passed to python (contains a pointer to the actual wx-object), which can be modified in python, thus the const_cast is needed. > > HTH, > I have found a solution after a very long search and with help from the irc-channel: Roman Yakovenko has created the return_value_policy return_pointee_value. Here's his announcement for that: http://mail.python.org/pipermail/c++-sig/2006-November/011568.html Maybe it would be good to have that in boost-python? He has already added it to his Py++ code generator. So my problem seems to be solved in this case... Thanks for your help! PS: I'm currently reading your MPL-Book and like it very much, although it's quite complicated to see through all the details after reading one chapter once :-) From dave at boostpro.com Mon Jul 21 14:09:17 2008 From: dave at boostpro.com (David Abrahams) Date: Mon, 21 Jul 2008 08:09:17 -0400 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> <87ljzwaczc.fsf@mcbain.luannocracy.com> <87prp8wgqj.fsf@mcbain.luannocracy.com> Message-ID: <452E5A36-5796-4DBD-8E16-9D9E1F389AD5@boostpro.com> -- Dave Abrahams Boostpro Computing http://boostpro.com On Jul 21, 2008, at 4:56 AM, Maximilian Matthe wrote: > David Abrahams schrieb: >> on Sun Jul 20 2008, Maximilian Matthe wrote: >>> David Abrahams schrieb: >>>> on Sun Jul 20 2008, Maximilian Matthe >>>> wrote: >>>> > >>>>> on Sun Jul 20 2008, Maximilian Matthe >>>>> wrote: >>>>> I dont want to return wxWindow by value, but by reference/ >>>>> adress. Thus >>>>> the bp::reference_existing_object call policy. >> You can't use that policy unless you're returning a Boost.Python- >> wrapped >> class. Its whole purpose in life is to make an instance of the class >> where the C++ object is held by raw pointer. I suggest you leave >> it out. > > Uh, well, then this could be written into the documentation, > couldn't it? Lots more could. Care to submit a patch? > Then I wouldn't have searched so long for a solution. Sorry > >> I can't imagine what purpose that const_cast could serve. Surely >> wxPyMake_wxObject doesn't modify its first argument? I suggest you >> leave it out. >> > No, the const_cast is needed. wxPyMake_wxObject wraps a PyObject > around the passed wxObject (any wxWidgets-Class). This object is > then passed to python (contains a pointer to the actual wx-object), > which can be modified in python, thus the const_cast is needed. I can't see the code any more, but it sure looked to me like you were adding or removing const from/to the pointer type rather than the pointee. > >> HTH, > > I have found a solution after a very long search and with help from > the irc-channel: Roman Yakovenko has created the return_value_policy > return_pointee_value. Here's his announcement for that: > http://mail.python.org/pipermail/c++-sig/2006-November/011568.html > Maybe it would be good to have that in boost-python? He has already > added it to his Py++ code generator. A patch with docs and tests would go as long way toward making that happen. > > So my problem seems to be solved in this case... > Thanks for your help! NO > PS: I'm currently reading your MPL-Book and like it very much, > although it's quite complicated to see through all the details after > reading one chapter once :-) Glad you're enjoying! From Maxi.Matthe at web.de Mon Jul 21 16:12:51 2008 From: Maxi.Matthe at web.de (Maximilian Matthe) Date: Mon, 21 Jul 2008 16:12:51 +0200 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: <452E5A36-5796-4DBD-8E16-9D9E1F389AD5@boostpro.com> References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> <87ljzwaczc.fsf@mcbain.luannocracy.com> <87prp8wgqj.fsf@mcbain.luannocracy.com> <452E5A36-5796-4DBD-8E16-9D9E1F389AD5@boostpro.com> Message-ID: David Abrahams schrieb: > > > -- > Dave Abrahams > Boostpro Computing > http://boostpro.com > > On Jul 21, 2008, at 4:56 AM, Maximilian Matthe wrote: > >> David Abrahams schrieb: >>> on Sun Jul 20 2008, Maximilian Matthe wrote: >>>> David Abrahams schrieb: >>>>> on Sun Jul 20 2008, Maximilian Matthe wrote: >>>>> >> >>>>>> on Sun Jul 20 2008, Maximilian Matthe wrote: >>>>>> I dont want to return wxWindow by value, but by reference/adress. >>>>>> Thus >>>>>> the bp::reference_existing_object call policy. >>> You can't use that policy unless you're returning a Boost.Python-wrapped >>> class. Its whole purpose in life is to make an instance of the class >>> where the C++ object is held by raw pointer. I suggest you leave it >>> out. >> >> Uh, well, then this could be written into the documentation, couldn't it? > > Lots more could. Care to submit a patch? > >> Then I wouldn't have searched so long for a solution. > > Sorry > >> >>> I can't imagine what purpose that const_cast could serve. Surely >>> wxPyMake_wxObject doesn't modify its first argument? I suggest you >>> leave it out. >>> >> No, the const_cast is needed. wxPyMake_wxObject wraps a PyObject >> around the passed wxObject (any wxWidgets-Class). This object is then >> passed to python (contains a pointer to the actual wx-object), which >> can be modified in python, thus the const_cast is needed. > > I can't see the code any more, but it sure looked to me like you were > adding or removing const from/to the pointer type rather than the pointee. Here's the code again: template struct convert_wxObjectPtr { static PyObject* convert(Ptr const& o) { PyObject* arg = wxPyMake_wxObject(const_cast(o), false); if(!arg) throw python_error("Object is not convertible to wxPython!"); return arg; } }; You're right, I tried to remove the const_cast from a converter that converted wx-objects instead of pointers to them, which lead to a compiler error. >> >>> HTH, >> >> I have found a solution after a very long search and with help from >> the irc-channel: Roman Yakovenko has created the return_value_policy >> return_pointee_value. Here's his announcement for that: >> http://mail.python.org/pipermail/c++-sig/2006-November/011568.html >> Maybe it would be good to have that in boost-python? He has already >> added it to his Py++ code generator. > > A patch with docs and tests would go as long way toward making that happen. > I can try to submit something like that, but I've never done something like this before. I'll read the documentation at boost.org. >> >> So my problem seems to be solved in this case... >> Thanks for your help! > > NO What does that mean? Is this an abbreviation or the word No? Isn't it solved? > >> PS: I'm currently reading your MPL-Book and like it very much, >> although it's quite complicated to see through all the details after >> reading one chapter once :-) > > > Glad you're enjoying! From jeff.webb at nta-inc.net Mon Jul 21 16:50:45 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Mon, 21 Jul 2008 09:50:45 -0500 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: <487FCF82.1000709@nta-inc.net> References: <487FCF82.1000709@nta-inc.net> Message-ID: <4884A245.5090309@nta-inc.net> Any comments? Surely someone has looked at the memory usage of shared_ptr. I'm not asking someone to verify the overhead down to the byte, but I would like to have confirmation that the numbers I posted are what one would generally expect, and that there is some motivation to pursue an alternative implementation in certain cases. If I am totally off-base here, or if no one else is interested in this issue, then I don't see any point in posting my proposed solution for review. Jeff Webb wrote: > Since we're discussing the topic of shared_ptr, intrusive_ptr, and other > custom smart pointers, I have a few observations and some related > questions that I would like to share. I would love to hear some > comments from the experts on these. > > (1) It seems that if you are designing a C++ library from the ground up > to use with boost::python, it makes a lot of sense to use smart pointers > internally in your C++ library. Python uses reference counting to > manage objects, so if you use reference counting in your C++ library, > you are laying the foundation for a seamless python interface instead of > fighting Python's memory management. > > (2) The boost::python support for shared_ptr is fantastic, and if you > make good use of shared_ptrs, many things will 'just work'. > > (3) If you decide to use smart pointers, there are two main reasons > *not* to use shared_ptr: (a) your library uses a custom smart pointer > internally > (b) the memory usage of shared_ptr is not acceptable > > I have attempted to quantify the memory usage of shared_ptr vs. a simple > intrusive_ptr implementation using the attached test program. I used > valgrind to verify the dynamic memory usage. Here are the results: > > shared_ptr > ---------- > > Each shared_ptr is the size of two raw pointers (one for the managed > object, and one for the shared reference count): > > A total of 8 bytes on x86 or 16 bytes on x86_64 > > For each object that is managed by shared_ptrs, a shared reference count > must be allocated. The memory usage for the shared reference count > appears to be two integers and two pointers: > > A total of 16 bytes on x86 > or 24 bytes on x86_64 > > When looking at the shared_ptr source code, I could only find one > pointer in the shared reference count, but I cannot reconcile this with > the memory usage reported by valgrind. I suppose it doesn't really > matter, but the breakdown I found in the code is listed below. Maybe I > am not looking at the right implementation for my system. > > sp_counted_impl_p: > sp_counted_base: > int use_count_; (4 bytes) > int weak_count_; (4 bytes) > X * (4 or 8 bytes) > ??? (4 or 8 bytes) > > intrusive_ptr > ------------- > > Each intrusive_ptr is the size of a raw pointer: > > A total of 4 bytes on x86 or 8 bytes on x86_64 > > For each object that is being managed by this intrusive_ptr > implementation, an extra integer must be added to the object to hold the > reference count: > > A total of 4 bytes on x86 or x86_64 > > (5) Summary: If you are wrapping a relatively small number of objects > or you are wrapping very large objects, the overhead of shared_ptr is > probably acceptable. If you are wrapping a large number of very small > objects, then a custom intrusive_ptr solution is worth looking into. > > Any comments on these ideas? Is my summary of shared_ptr memory usage > on target? > > Thanks, > > Jeff From foxmulder900 at yahoo.com Mon Jul 21 17:10:07 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Mon, 21 Jul 2008 08:10:07 -0700 (PDT) Subject: [C++-sig] leaving out functions when exposing a class In-Reply-To: <7465b6170807151215t13e2be46x67c8b6402f42f1a8@mail.gmail.com> References: <18412325.post@talk.nabble.com> <7465b6170807130040t2f5ac81fu668a9b0b54e56e17@mail.gmail.com> <18446355.post@talk.nabble.com> <7465b6170807141109r5b4ea237n1dc4849cbec76564@mail.gmail.com> <18456336.post@talk.nabble.com> <18470284.post@talk.nabble.com> <7465b6170807151215t13e2be46x67c8b6402f42f1a8@mail.gmail.com> Message-ID: <18570694.post@talk.nabble.com> I am using msvc on windows xp, but i was able to fix my problem, all i needed to do was link to user32.lib! Thanks for everyone's help -- View this message in context: http://www.nabble.com/leaving-out-functions-when-exposing-a-class-tp18412325p18570694.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From foxmulder900 at yahoo.com Mon Jul 21 17:20:23 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Mon, 21 Jul 2008 08:20:23 -0700 (PDT) Subject: [C++-sig] Embedded python, script has no effect Message-ID: <18570898.post@talk.nabble.com> Hello, I have embedded the python interpreter into my program and wrapped my main classes using boost. In my program i have called Py_Initialize() and when a key is pressed I am running the following code: cout << "attempting to run script" << endl; try { boost::python::object main_module = boost::python::import("pyYEI3D"); boost::python::exec_file("test.py"); } catch(boost::python::error_already_set const &) { PyErr_Print(); } and here are the contents of 'test.py' person = pyYEI3D.getGameObjectByName("person") person.translate(100,0,0) getGameObjectByName is a part of one of my main wrapped class, and it should return an instance of another one of my wrapped classes - my project is in OGRE 3D so the translate function should simply translate the returned object 100 units in 3D space. My problem is that nothing is happening at all, no errors are being returned and the object is not being translated, i know the code is running because this line is printing correctly: cout << "attempting to run script" << endl; Any suggestions would be much appreciated! -- View this message in context: http://www.nabble.com/Embedded-python%2C-script-has-no-effect-tp18570898p18570898.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From roman.yakovenko at gmail.com Mon Jul 21 20:11:25 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Mon, 21 Jul 2008 21:11:25 +0300 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: <487FCF82.1000709@nta-inc.net> References: <487FCF82.1000709@nta-inc.net> Message-ID: <7465b6170807211111l1289b8c6w48484c2615759338@mail.gmail.com> 2008/7/18 Jeff Webb : > Since we're discussing the topic of shared_ptr, intrusive_ptr, and other > custom smart pointers, I have a few observations and some related questions > that I would like to share. I would love to hear some comments from the > experts on these. > > (1) It seems that if you are designing a C++ library from the ground up to > use with boost::python, it makes a lot of sense to use smart pointers > internally in your C++ library. Python uses reference counting to manage > objects, so if you use reference counting in your C++ library, you are > laying the foundation for a seamless python interface instead of fighting > Python's memory management. No, but if you don't use smart pointers, you will have to pay a lot attention to call policies. > (2) The boost::python support for shared_ptr is fantastic, and if you make > good use of shared_ptrs, many things will 'just work'. This is true. > (3) If you decide to use smart pointers, there are two main reasons *not* to > use shared_ptr: (a) your library uses a custom smart pointer internally If it is "very similar" to shared_ptr, than you can make it work too: http://www.language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smart_ptrs.html > (b) the memory usage of shared_ptr is not acceptable > > I have attempted to quantify the memory usage of shared_ptr vs. a simple > intrusive_ptr implementation using the attached test program. I used > valgrind to verify the dynamic memory usage. Here are the results: > > shared_ptr > ---------- > > Each shared_ptr is the size of two raw pointers (one for the managed object, > and one for the shared reference count): > > A total of 8 bytes on x86 or 16 bytes on x86_64 > > For each object that is managed by shared_ptrs, a shared reference count > must be allocated. The memory usage for the shared reference count appears > to be two integers and two pointers: > > A total of 16 bytes on x86 > or 24 bytes on x86_64 > > When looking at the shared_ptr source code, I could only find one pointer in > the shared reference count, but I cannot reconcile this with the memory > usage reported by valgrind. I suppose it doesn't really matter, but the > breakdown I found in the code is listed below. Maybe I am not looking at > the right implementation for my system. > > sp_counted_impl_p: > sp_counted_base: > int use_count_; (4 bytes) > int weak_count_; (4 bytes) > X * (4 or 8 bytes) > ??? (4 or 8 bytes) > > intrusive_ptr > ------------- > > Each intrusive_ptr is the size of a raw pointer: > > A total of 4 bytes on x86 or 8 bytes on x86_64 > > For each object that is being managed by this intrusive_ptr implementation, > an extra integer must be added to the object to hold the reference count: > > A total of 4 bytes on x86 or x86_64 > > (5) Summary: If you are wrapping a relatively small number of objects or > you are wrapping very large objects, the overhead of shared_ptr is probably > acceptable. If you are wrapping a large number of very small objects, then > a custom intrusive_ptr solution is worth looking into. Not at all. Your memory management should be clear. For example you can take a look on Ogre and Python-Ogre library. Ogre has a lot of objects passed around but the ownership is very clear. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From lists_ravi at lavabit.com Mon Jul 21 22:00:44 2008 From: lists_ravi at lavabit.com (Ravi) Date: Mon, 21 Jul 2008 16:00:44 -0400 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: <4884A245.5090309@nta-inc.net> References: <487FCF82.1000709@nta-inc.net> <4884A245.5090309@nta-inc.net> Message-ID: <200807211600.45020.lists_ravi@lavabit.com> On Monday 21 July 2008 10:50:45 Jeff Webb wrote: > Any comments? ?Surely someone has looked at the memory usage of shared_ptr. > ?I'm not asking someone to verify the overhead down to the byte, but I > would like to have confirmation that the numbers I posted are what one > would generally expect, and that there is some motivation to pursue an > alternative implementation in certain cases. ?If I am totally off-base > here, or if no one else is interested in this issue, then I don't see any > point in posting my proposed solution for review. I am extremely interested in this. The numbers are what I'd expect as well. Even if you finally end up not posting a nice clean solution, I'd like to see some dirty version of it (even if only over private email); I suspect that many others hold similar views but do not reply on the foum as this sort of reply is sometimes considered mere noise (since merely expressing interest adds nothing to the discussion). Regards, Ravi -------------- next part -------------- An HTML attachment was scrubbed... URL: From meine at informatik.uni-hamburg.de Tue Jul 22 06:56:15 2008 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Tue, 22 Jul 2008 06:56:15 +0200 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: <487FCF82.1000709@nta-inc.net> References: <487FCF82.1000709@nta-inc.net> Message-ID: <200807220656.22034.meine@informatik.uni-hamburg.de> On Freitag 18 Juli 2008, Jeff Webb wrote: > When looking at the shared_ptr source code, I could only find one pointer > in the shared reference count, but I cannot reconcile this with the memory > usage reported by valgrind. I suppose it doesn't really matter, but the > breakdown I found in the code is listed below. Maybe I am not looking at > the right implementation for my system. > > sp_counted_impl_p: > sp_counted_base: > int use_count_; (4 bytes) > int weak_count_; (4 bytes) > X * (4 or 8 bytes) > ??? (4 or 8 bytes) I think the ??? may be the virtual method table pointer of sp_counted_base. Ciao, / / .o. /--/ ..o / / ANS ooo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. URL: From jeff.webb at nta-inc.net Tue Jul 22 16:24:13 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Tue, 22 Jul 2008 09:24:13 -0500 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: <200807220656.22034.meine@informatik.uni-hamburg.de> References: <487FCF82.1000709@nta-inc.net> <200807220656.22034.meine@informatik.uni-hamburg.de> Message-ID: <4885ED8D.6090804@nta-inc.net> Hans Meine wrote: >> sp_counted_impl_p: >> sp_counted_base: >> int use_count_; (4 bytes) >> int weak_count_; (4 bytes) >> X * (4 or 8 bytes) >> ??? (4 or 8 bytes) > > I think the ??? may be the virtual method table pointer of sp_counted_base. Oh yes, of course. Thanks for catching this! -Jeff From jeff.webb at nta-inc.net Tue Jul 22 17:44:16 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Tue, 22 Jul 2008 10:44:16 -0500 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: <7465b6170807211111l1289b8c6w48484c2615759338@mail.gmail.com> References: <487FCF82.1000709@nta-inc.net> <7465b6170807211111l1289b8c6w48484c2615759338@mail.gmail.com> Message-ID: <48860050.5050203@nta-inc.net> Thank you for sharing your thoughts on this, Roman. Roman Yakovenko wrote: >> (1) It seems that if you are designing a C++ library from the ground up to >> use with boost::python, it makes a lot of sense to use smart pointers >> internally in your C++ library. Python uses reference counting to manage >> objects, so if you use reference counting in your C++ library, you are >> laying the foundation for a seamless python interface instead of fighting >> Python's memory management. > > No, but if you don't use smart pointers, you will have to pay a lot > attention to call policies. By 'no', do you mean that it is *not* a good idea to use smart pointers internally when designing a C++ library to use with boost::python and/or that using smart pointers does *not* make integration with python easier? By no means am I implying that this is the only good way to do things, but it seems to be a straightforward and reasonable approach, does it not? > If it is "very similar" to shared_ptr, than you can make it work too: > http://www.language-binding.net/pyplusplus/troubleshooting_guide/smart_ptrs/smart_ptrs.html Thanks for providing the examples and documentation. I will take a closer look at this when I get a chance. >> (5) Summary: If you are wrapping a relatively small number of objects or >> you are wrapping very large objects, the overhead of shared_ptr is probably >> acceptable. If you are wrapping a large number of very small objects, then >> a custom intrusive_ptr solution is worth looking into. > > Not at all. Your memory management should be clear. For example you > can take a look on Ogre and Python-Ogre library. Ogre has a lot of > objects passed around but the ownership is very clear. What does your 'not at all' refer to? Are you saying that in the situation outlined above, a custom/intrusive_ptr is not even worth considering? If so, please explain why. (Again, I am not saying it is the best solution in all cases, but simply that it seems to provide a clean solution to the problem at hand.) In my limited experience, I have found that even some 'clear' memory management schemes are difficult to cleanly map to python. It seems that any management scheme where a wrapped object is not owned by python is potentially problematic because the object's owner could delete the wrapped object from C++, leaving an 'empty' python wrapper that is still referenced from python. I think that using reference counting internally will eliminate this problem. Of course, reference counting does have memory and execution overhead, so there is a trade off, of course. Thanks again for your input, Jeff From jsvachon at copernic.com Tue Jul 22 17:31:41 2008 From: jsvachon at copernic.com (jsvachon) Date: Tue, 22 Jul 2008 11:31:41 -0400 Subject: [C++-sig] Concurrency problem? Message-ID: <4885FD5D.7000801@copernic.com> Hi All, I am using Boost::Python to make our C++ application easier to extend. So far it has been working great but I just ran into a problem that could be thread related. Our application is basically a XMLRPC server waiting for connections and all the server does is to redirect each request to the proper web service. The web service can be coded in C++ or in Python. I've implemented a simple web service in Python that I can test with 'ab'. When I set the concurrency level to something greater than 1, the software sometimes crashes with the following stack. With a single thread everything is running smoothly. What is bugging me is that it will work with multiple threads from time to time. I hope someone can spot something in the frame stack below... The XmlRpcPythonValue class is a python wrapper over a C++ class that is a variant that can represent any value allowed by the XmlRpc standard. Let me know if you need more information. #0 0x83ed9271 in boost::python::objects::find_instance_impl () from /opt/boost/lib/libboost_python-gcc41-mt-1_35.so.1.35.0 #1 0x83ed4989 in boost::python::converter::rvalue_from_python_stage1 () from /opt/boost/lib/libboost_python-gcc41-mt-1_35.so.1.35.0 #2 0x83c6fba2 in arg_rvalue_from_python (this=0xb577474c, obj=0x0) at /opt/boost/include/boost-1_35/boost/python/converter/arg_from_python.hpp:299 #3 0x83c6fbf6 in arg_from_python (this=0xb577474c, source=0x0) at /opt/boost/include/boost-1_35/boost/python/arg_from_python.hpp:70 #4 0x83c6fcb7 in boost::python::detail::caller_arity<3u>::impl >::operator() (this=0x80d7fac, args_=0x83d0e8c4) at /opt/boost/include/boost-1_35/boost/preprocessor/iteration/detail/local.hpp:40 #5 0x83c6fe00 in boost::python::objects::caller_py_function_impl > >::operator() (this=0x80d7fa8, args=0x83d0e8c4, kw=0x0) at /opt/boost/include/boost-1_35/boost/python/object/py_function.hpp:38 #6 0x83ede7c6 in boost::python::objects::function::call () from /opt/boost/lib/libboost_python-gcc41-mt-1_35.so.1.35.0 #7 0x83edf787 in boost::detail::function::void_function_ref_invoker0::invoke () from /opt/boost/lib/libboost_python-gcc41-mt-1_35.so.1.35.0 #8 0xb7c1459a in boost::function0 >::operator() () from /opt/boost/lib/libboost_thread-gcc41-mt-1_35.so.1.35.0 #9 0x83ee4f3b in boost::python::handle_exception_impl () from /opt/boost/lib/libboost_python-gcc41-mt-1_35.so.1.35.0 #10 0x83ededf3 in boost::python::handle_exception () from /opt/boost/lib/libboost_python-gcc41-mt-1_35.so.1.35.0 #11 0x83edb95a in ?? () from /opt/boost/lib/libboost_python-gcc41-mt-1_35.so.1.35.0 #12 0x83d9cc17 in PyObject_Call () from /usr/lib/libpython2.5.so.1.0 #13 0x83e1c8cc in PyEval_EvalFrameEx () from /usr/lib/libpython2.5.so.1.0 #14 0x83e22734 in PyEval_EvalCodeEx () from /usr/lib/libpython2.5.so.1.0 #15 0x83dbfa4a in ?? () from /usr/lib/libpython2.5.so.1.0 #16 0x83cfef98 in ?? () #17 0x83d03bdc in ?? () #18 0x00000000 in ?? () -- _________________________ *Jean-Sebastien Vachon* Team Leader - Search Network Copernic 418-527-0528 1281 jsvachon at copernic.com www.copernic.com From foxmulder900 at yahoo.com Tue Jul 22 18:46:37 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Tue, 22 Jul 2008 09:46:37 -0700 (PDT) Subject: [C++-sig] Embedded python, script has no effect In-Reply-To: <18570898.post@talk.nabble.com> References: <18570898.post@talk.nabble.com> Message-ID: <18593675.post@talk.nabble.com> I am still having the same problem but I realized something else, the catch statement is always being caught but PyErr_Print() is not printing anything, when i comment out the catch statement it crashes giving me a std::invalid_argument error. I think it is crashing before it gets into my script because even if i comment everything out in the .py file, it still crashes. I have tried replacing the filename with the full path to make sure it is finding the script, but that didn't help either. I am still confused as to what i'm missing! -- View this message in context: http://www.nabble.com/Embedded-python%2C-script-has-no-effect-tp18570898p18593675.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From dave at boost-consulting.com Tue Jul 22 18:56:48 2008 From: dave at boost-consulting.com (David Abrahams) Date: Tue, 22 Jul 2008 09:56:48 -0700 Subject: [C++-sig] Embedded python, script has no effect In-Reply-To: <18593675.post@talk.nabble.com> References: <18570898.post@talk.nabble.com> <18593675.post@talk.nabble.com> Message-ID: On Tue, 22 Jul 2008 09:46:37 -0700 (PDT), FoxMulder900 wrote: > > I am still having the same problem but I realized something else, the > catch > statement is always being caught but PyErr_Print() is not printing > anything, > when i comment out the catch statement it crashes giving me a > std::invalid_argument error. > > I think it is crashing before it gets into my script because even if i > comment everything out in the .py file, it still crashes. I have tried > replacing the filename with the full path to make sure it > is finding the script, but that didn't help either. I am still confused as > to what i'm missing! Sounds very much like this exception is not the translation of a Python exception, but rather is being thrown by some ordinary C++ code. Most debuggers will let you breakpoint on throw; you might try to find out where it's coming from. -- David Abrahams Boost Consulting, Inc. http://www.boost-consulting.com From foxmulder900 at yahoo.com Tue Jul 22 20:39:12 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Tue, 22 Jul 2008 11:39:12 -0700 (PDT) Subject: [C++-sig] Embedded python, script has no effect In-Reply-To: References: <18570898.post@talk.nabble.com> <18593675.post@talk.nabble.com> Message-ID: <18595683.post@talk.nabble.com> > > Sounds very much like this exception is not the translation of a Python > exception, but rather is being thrown by some ordinary C++ code. Most > debuggers will let you breakpoint on throw; you might try to find out > where > > it's coming from. > > Alright, i did a little debugging and I realized it is throwing the following error: boost::python::error_already_set at memory location on this line: boost::python::object main_module = boost::python::import("C:\Documents and Settings\New user\Desktop\YEI3D\trunk\YEI3Dv2\pyYEI3D"); the original std::invalid_argument error must have been a fluke, because i am no longer getting that error -- View this message in context: http://www.nabble.com/Embedded-python%2C-script-has-no-effect-tp18570898p18595683.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From foxmulder900 at yahoo.com Tue Jul 22 20:45:13 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Tue, 22 Jul 2008 11:45:13 -0700 (PDT) Subject: [C++-sig] Embedded python, script has no effect Message-ID: <18595683.post@talk.nabble.com> > > Sounds very much like this exception is not the translation of a Python > exception, but rather is being thrown by some ordinary C++ code. Most > debuggers will let you breakpoint on throw; you might try to find out > where > > it's coming from. > > Alright, i did a little debugging and I realized it is throwing the following error: boost::python::error_already_set at memory location on this line: boost::python::object main_module = boost::python::import("C:\Documents and Settings\New user\Desktop\YEI3D\trunk\YEI3Dv2\pyYEI3D"); the std::invalid_argument error is coming from the next line: boost::python::exec_file("C:\Documents and Settings\New user\Desktop\YEI3D\trunk\YEI3Dv2\test.py"); -- View this message in context: http://www.nabble.com/Embedded-python%2C-script-has-no-effect-tp18570898p18595683.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From dave at boostpro.com Wed Jul 23 03:48:46 2008 From: dave at boostpro.com (David Abrahams) Date: Tue, 22 Jul 2008 21:48:46 -0400 Subject: [C++-sig] Embedded python, script has no effect In-Reply-To: <18595683.post@talk.nabble.com> (FoxMulder's message of "Tue, 22 Jul 2008 11:39:12 -0700 (PDT)") References: <18570898.post@talk.nabble.com> <18593675.post@talk.nabble.com> <18595683.post@talk.nabble.com> Message-ID: <87k5fdtloh.fsf@mcbain.luannocracy.com> on Tue Jul 22 2008, FoxMulder900 wrote: >> >> Sounds very much like this exception is not the translation of a Python >> exception, but rather is being thrown by some ordinary C++ code. Most >> debuggers will let you breakpoint on throw; you might try to find out >> where >> >> it's coming from. >> >> > > Alright, i did a little debugging and I realized it is throwing the > following error: > boost::python::error_already_set at memory location > on this line: > boost::python::object main_module = boost::python::import("C:\Documents and > Settings\New user\Desktop\YEI3D\trunk\YEI3Dv2\pyYEI3D"); > > the original std::invalid_argument error must have been a fluke, because i > am no longer getting that error Well, then, PyErr_Print should be giving you some output now (?) -- Dave Abrahams BoostPro Computing http://www.boostpro.com From dave at boostpro.com Wed Jul 23 03:58:22 2008 From: dave at boostpro.com (David Abrahams) Date: Tue, 22 Jul 2008 21:58:22 -0400 Subject: [C++-sig] [boost.python] convert swig-wrapped c++-return values to python with boost.python In-Reply-To: (Maximilian Matthe's message of "Mon, 21 Jul 2008 16:12:51 +0200") References: <220147.76485.qm@web31104.mail.mud.yahoo.com> <87y73wadqb.fsf@mcbain.luannocracy.com> <87ljzwaczc.fsf@mcbain.luannocracy.com> <87prp8wgqj.fsf@mcbain.luannocracy.com> <452E5A36-5796-4DBD-8E16-9D9E1F389AD5@boostpro.com> Message-ID: <877ibdtl8h.fsf@mcbain.luannocracy.com> on Mon Jul 21 2008, Maximilian Matthe wrote: >>> So my problem seems to be solved in this case... >>> Thanks for your help! >> >> NO > What does that mean? Is this an abbreviation or the word No? Isn't it > solved? I think it was random and not intended to mean anything. Sorry -- Dave Abrahams BoostPro Computing http://www.boostpro.com From meine at informatik.uni-hamburg.de Wed Jul 23 11:19:36 2008 From: meine at informatik.uni-hamburg.de (Hans Meine) Date: Wed, 23 Jul 2008 11:19:36 +0200 Subject: [C++-sig] shared_ptr vs. intrusive_ptr In-Reply-To: <4885ED8D.6090804@nta-inc.net> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> Message-ID: <200807231119.36451.meine@informatik.uni-hamburg.de> Am Dienstag, 22. Juli 2008 16:24:13 schrieb Jeff Webb: > Hans Meine wrote: > >> sp_counted_impl_p: > >> sp_counted_base: > >> int use_count_; (4 bytes) > >> int weak_count_; (4 bytes) > >> X * (4 or 8 bytes) > >> ??? (4 or 8 bytes) > > > > I think the ??? may be the virtual method table pointer of > > sp_counted_base. > > Oh yes, of course. Thanks for catching this! And of course this is needed exactly to support deleters; ATM I do not recall whether the "[why] do I need deleters" discussion was with you or with Gennadiy. (I.e. someone asked "can intrusive_ptr/my_smart_ptr be made to support the same set of features as shared_ptr?" - this pointer can not be saved if you want the same features.) -- Ciao, / / /--/ / / ANS From hohehohe2 at gmail.com Wed Jul 23 12:04:43 2008 From: hohehohe2 at gmail.com (Koichi Tamura) Date: Wed, 23 Jul 2008 19:04:43 +0900 Subject: [C++-sig] static/dynamic boost::python conflicts? Message-ID: Hello, I'm using boost::python and I've got a problem now. I'm writing a shared library(bundle, I'm using MacOSX10.5, and it's a plug-in for some application) where I have a code like this. //....on init.... if ( ! Py_IsInitialized()) { int a = PyImport_AppendInittab("MyModule", &initMyModule); Py_Initialize(); PyEval_InitThreads(); PyEval_ReleaseLock(); } //....somewhere else... PyGILState_STATE state = PyGILState_Ensure(); module = object(handle<>(PyModule_New(moduleName))); myMod = object(handle<>(PyImport_ImportModule("MyModule"))); module.attr("mymod") = myMod; PyGILState_Release(state); I statically linked boost::python, and it works fine. When imported, MyModule is filled with classes that boost::python has wrapped. But when I use another shared library(#) which dynamically links boost::python together with mine, PyImport_ImportModule("MyModule") returns a module which dict is empty but __doc__ and __name__. Instead of (#) I made a test shared library that does nothing but linking boost::python dynamically, and it still fails. Why does all statically linked boost::python and extension is affected by a dynamically linked boost::python? I'm really puzzled. I would really appreciate if anybody could help. -Koichi -------------- next part -------------- An HTML attachment was scrubbed... URL: From foxmulder900 at yahoo.com Wed Jul 23 16:18:08 2008 From: foxmulder900 at yahoo.com (FoxMulder900) Date: Wed, 23 Jul 2008 07:18:08 -0700 (PDT) Subject: [C++-sig] Embedded python, script has no effect In-Reply-To: <87k5fdtloh.fsf@mcbain.luannocracy.com> References: <18570898.post@talk.nabble.com> <18593675.post@talk.nabble.com> <18595683.post@talk.nabble.com> <87k5fdtloh.fsf@mcbain.luannocracy.com> Message-ID: <18611760.post@talk.nabble.com> > > Well, then, PyErr_Print should be giving you some output now (?) > > Actually no, there is no output, that's why i'm so confused. -- View this message in context: http://www.nabble.com/Embedded-python%2C-script-has-no-effect-tp18570898p18611760.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From rogeeff at gmail.com Wed Jul 23 16:52:58 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 23 Jul 2008 14:52:58 +0000 (UTC) Subject: [C++-sig] assign a pointer to global object Message-ID: Hi, I am sure I missing something trivial, but I can't make work most simple example like this: c++ side struct AAA { }; AAA s_global; void assign_aaa( bp::object& o ) { o.attr("aaa") = &s_global; } ... export_func { ... class_( "AAA", no_init ); def( "assign_aaa", &assign_aaa ); } python side: assign_aaa( object() ) Error: TypeError: No to_python (by-value) converter found for C++ type: struct AAA Please advise, Gennadiy From roman.yakovenko at gmail.com Wed Jul 23 20:04:10 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 23 Jul 2008 21:04:10 +0300 Subject: [C++-sig] assign a pointer to global object In-Reply-To: References: Message-ID: <7465b6170807231104i2723aec2j23290a821b8aa04f@mail.gmail.com> On Wed, Jul 23, 2008 at 5:52 PM, Gennadiy Rozental wrote: > Hi, > > I am sure I missing something trivial, but I can't make work most simple example > like this: > > c++ side > > struct AAA { > > }; > > AAA s_global; > > void > assign_aaa( bp::object& o ) > { > o.attr("aaa") = &s_global; > } > > ... > > export_func > { > ... > class_( "AAA", no_init ); > > def( "assign_aaa", &assign_aaa ); > } > > python side: > > assign_aaa( object() ) > > Error: > > TypeError: No to_python (by-value) converter found for C++ type: struct AAA > > Please advise, Next code was generated by Py++: #include "boost/python.hpp" #include "1.h" namespace bp = boost::python; BOOST_PYTHON_MODULE(pyplusplus){ bp::class_< AAA, boost::noncopyable >( "AAA" ) .def( bp::init< >() ); bp::scope().attr("s_global") = bp::object( boost::ref( s_global ) ); } HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From rogeeff at gmail.com Wed Jul 23 20:45:40 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 23 Jul 2008 18:45:40 +0000 (UTC) Subject: [C++-sig] assign a pointer to global object References: <7465b6170807231104i2723aec2j23290a821b8aa04f@mail.gmail.com> Message-ID: Roman Yakovenko gmail.com> writes: > #include "boost/python.hpp" > > #include "1.h" > > namespace bp = boost::python; > > BOOST_PYTHON_MODULE(pyplusplus){ > bp::class_< AAA, boost::noncopyable >( "AAA" ) I do not want python to manage instance of AAA. I specified AAA* as second argument. > .def( bp::init< >() ); And they are not constructible from python > bp::scope().attr("s_global") = bp::object( boost::ref( s_global ) ); This I am not sure what it has to do with my question. I am not setting python global var. But! adding boost::ref to the obj.attr( "aaa" ) = boost::ref( s_global ); did resolve the issue, though I am quite confused why it is required. Gennadiy From rogeeff at gmail.com Wed Jul 23 20:48:28 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Wed, 23 Jul 2008 18:48:28 +0000 (UTC) Subject: [C++-sig] automating convertion y omy exception References: Message-ID: Gennadiy Rozental gmail.com> writes: > > Hi, > > Boost.Python throws bp::error_already_set in case any error occurred. But I So, there is no way to tell Boost.Python to throw my exception instead? Gennadiy From roman.yakovenko at gmail.com Wed Jul 23 21:07:15 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 23 Jul 2008 22:07:15 +0300 Subject: [C++-sig] assign a pointer to global object In-Reply-To: References: <7465b6170807231104i2723aec2j23290a821b8aa04f@mail.gmail.com> Message-ID: <7465b6170807231207y1cc66ac4tb0f3d71b6718131a@mail.gmail.com> On Wed, Jul 23, 2008 at 9:45 PM, Gennadiy Rozental wrote: > Roman Yakovenko gmail.com> writes: >> #include "boost/python.hpp" >> >> #include "1.h" >> >> namespace bp = boost::python; >> >> BOOST_PYTHON_MODULE(pyplusplus){ >> bp::class_< AAA, boost::noncopyable >( "AAA" ) > > I do not want python to manage instance of AAA. I specified AAA* > as second argument. > >> .def( bp::init< >() ); > > And they are not constructible from python Don't miss the point, I didn't created the code to fully match your request. >> bp::scope().attr("s_global") = bp::object( boost::ref( s_global ) ); > > This I am not sure what it has to do with my question. > I am not setting python global var. > > But! > > adding boost::ref to the > > obj.attr( "aaa" ) = boost::ref( s_global ); > > did resolve the issue, though I am quite confused why it is required. 1. class ``scope`` derives from ``object`` 2. you assumed that assigning to ``object`` instance a pointer will make it to "refer" to it. Your assumption is wrong. As you already found out, it will try to copy it. I guess this is just "safer" and if you want the opposite behavior you have to use special way. Py++ contains code, which allows you to create ``object`` instance and to specify how to manage C++ instance: http://www.language-binding.net/pyplusplus/documentation/apidocs/pyplusplus.code_repository.call_policies-pysrc.html template< typename CallPolicies, class T > bpl::object make_object( T x ){ //constructs object using CallPolicies result_converter typedef BOOST_DEDUCED_TYPENAME CallPolicies::result_converter:: template apply< T >::type result_converter_t; result_converter_t rc; return bpl::object( bpl::handle<>( rc( x ) ) ); } -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From roman.yakovenko at gmail.com Wed Jul 23 21:11:40 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Wed, 23 Jul 2008 22:11:40 +0300 Subject: [C++-sig] automating convertion y omy exception In-Reply-To: References: Message-ID: <7465b6170807231211p6e12a34dw562717f04b0dad71@mail.gmail.com> On Wed, Jul 23, 2008 at 9:48 PM, Gennadiy Rozental wrote: > Gennadiy Rozental gmail.com> writes: > >> >> Hi, >> >> Boost.Python throws bp::error_already_set in case any error occurred. But I > > So, there is no way to tell Boost.Python to throw my exception instead? I am not sure what are you looking for. Take a look on next links: http://www.boost.org/doc/libs/1_35_0/libs/python/doc/v2/exception_translator.html http://www.language-binding.net/pyplusplus/troubleshooting_guide/exceptions/exceptions.html May be they will help -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From dave at boostpro.com Thu Jul 24 03:00:11 2008 From: dave at boostpro.com (David Abrahams) Date: Wed, 23 Jul 2008 21:00:11 -0400 Subject: [C++-sig] assign a pointer to global object In-Reply-To: (Gennadiy Rozental's message of "Wed, 23 Jul 2008 18:45:40 +0000 (UTC)") References: <7465b6170807231104i2723aec2j23290a821b8aa04f@mail.gmail.com> Message-ID: <87prp4hzac.fsf@mcbain.luannocracy.com> on Wed Jul 23 2008, Gennadiy Rozental wrote: > > adding boost::ref to the > > obj.attr( "aaa" ) = boost::ref( s_global ); > > did resolve the issue, though I am quite confused why it is required. Reference semantics is generally unsafe, so we make you request it explicitly. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From ericdfirst at gmail.com Thu Jul 24 16:40:52 2008 From: ericdfirst at gmail.com (Eric First) Date: Thu, 24 Jul 2008 09:40:52 -0500 Subject: [C++-sig] Wrapping std::set using Boost::Python Message-ID: <349c44440807240740v41f1688ay98de6613071e4e13@mail.gmail.com> Has anybody wrapped std::set using Boost::Python? I'm looking for the most efficient way to do this. All ideas are greatly appreciated. Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Thu Jul 24 19:16:01 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Thu, 24 Jul 2008 20:16:01 +0300 Subject: [C++-sig] Wrapping std::set using Boost::Python In-Reply-To: <349c44440807240740v41f1688ay98de6613071e4e13@mail.gmail.com> References: <349c44440807240740v41f1688ay98de6613071e4e13@mail.gmail.com> Message-ID: <7465b6170807241016l19c9e1b4iee9b8179514798c7@mail.gmail.com> 2008/7/24 Eric First : > Has anybody wrapped std::set using Boost::Python? I'm looking for the most > efficient way to do this. All ideas are greatly appreciated. Thanks. Indexing suite v2 contains such functionality. http://www.language-binding.net/pyplusplus/documentation/containers.html Also I am not sure about "most efficient". -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From erictexier at gmail.com Thu Jul 24 21:49:25 2008 From: erictexier at gmail.com (Eric Texier) Date: Thu, 24 Jul 2008 12:49:25 -0700 Subject: [C++-sig] using boost::python::list .... Message-ID: <37c1dd070807241249l3f6a6a43g727c3a7ff9e100fe@mail.gmail.com> Hi, I was wondering if you someone can help me on this one. I would like to return a dictionary with all the key/value of a c++ object (a camera is this case) some of these values are list ( position = [x,y,z]). I'm tempted to allocate those list dynamically but I'm concern about who is going to manage them.(delete ...reference count) To make it short: - should I use the way I do "position" (dynamic) or the way I do for "lookat"(static).? - if I allocate the list as a value of my dictionary key, is there anything else to do in term of reference count etc...? Thanks for you help. Eric namespace bp=boost::python; bp::dict getAsDict(ICam& myCam) { bp::dict retvals; // position bp::list *plist = new bp::list(); const Imath::V3f& p = myCam.position(); plist->append(p.x); plist->append(p.y); plist->append(p.z); retvals["position"] = plist; // lookat const Imath::V3f& d = myCam.lookat(); bp::list llist; llist.append(d.x); llist.append(d.y); llist.append(d.z); retvals["direction"] = llist; return retvals; } BOOST_PYTHON_MODULE(iParts) { class_("ICam") .def("getAsDict",&getAsDict,"return all the value in a dict") ; } -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeff.webb at nta-inc.net Thu Jul 24 22:23:10 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Thu, 24 Jul 2008 15:23:10 -0500 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <200807231119.36451.meine@informatik.uni-hamburg.de> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> Message-ID: <4888E4AE.3000500@nta-inc.net> The boost::python library provides excellent support for wrapping C++ objects managed by boost::shared_ptr reference counting smart pointers. I am attempting to achieve similar functionality with a little less memory overhead by embedding the reference count in the managed object and using boost::intrusive_ptr instead. I have come up with an implementation that I would like to post to this list for two reasons. First of all, I would be thrilled if some more knowledgeable folks would look over the code and let me know if my approach is flawed in some way. Secondly, I think the principles I am discussing will be of interest to others on the list, and possibly the code itself. Instead of posting the whole implementation at once, I am going to start out with something very basic. I will then point out some deficiencies and address them one at a time, modifying the code to overcome each one. I think this approach will be more understandable than throwing the whole mess of code out there at once. The attached mod1.cpp file defines a base class for reference counted objects (called "Pointee") and provides the functions required for managing Pointee objects with intrusive_ptr. The module also defines two test classes that are exposed to python. The VerbosePointee class is just a subclass of Pointee that contains print statements for illustration purposes. RefHolder is a subclass of VerbosePointee that contains a member called 'ref', which is an intrusive_ptr that can reference another VerbosePointee object. Here is a sample python session using this module: >>> from mod1 import * >>> r = RefHolder() creating 0x1d544af0 >>> print r.ref None >>> v = VerbosePointee() creating 0x1d6b6190 >>> r.ref = v >>> print r.ref >>> r.ref is v False >>> r.ref.id == v.id True >>> del v >>> del r destroying 0x1d6b6190 destroying 0x1d544af0 >>> r1 = RefHolder() creating 0x1de86a80 >>> r2 = RefHolder() creating 0x1d544bf0 >>> r1.ref = r2 -------------------------- Boost.Python.ArgumentError ArgumentError: Python argument types in None.None(RefHolder, RefHolder) did not match C++ signature: None(RefHolder {lvalue}, boost::intrusive_ptr) >>> r1.ref = None --------------------------------------------------------------------------- Boost.Python.ArgumentError ArgumentError: Python argument types in None.None(RefHolder, NoneType) did not match C++ signature: None(RefHolder {lvalue}, boost::intrusive_ptr) The memory management works as one would expect, but a few deficiencies are evident in the session shown above: (1) There is an object identity problem (i.e. 'r.ref is v' is False). This means that there are two python wrappers for a single C++ object. In some cases this is okay, but it is not ideal. (2) RefHolder objects cannot hold a reference to another RefHolder object, even though RefHolder is a subclass of VerbosePointee. (3) Although a null pointer is translated to python as None, a RefHolder's ref member cannot be assigned a value of None. In future posts, I will post my proposed solution to the problems mentioned above and address other issues as they arise. Any comments/questions so far? -Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: mod1.cpp Type: text/x-c++src Size: 2816 bytes Desc: not available URL: From rwgk at yahoo.com Thu Jul 24 23:14:35 2008 From: rwgk at yahoo.com (Ralf W. Grosse-Kunstleve) Date: Thu, 24 Jul 2008 14:14:35 -0700 (PDT) Subject: [C++-sig] Wrapping std::set using Boost::Python Message-ID: <101121.96354.qm@web31108.mail.mud.yahoo.com> You can easily do it from scratch (as an alternative to the indexing suite): http://phenix-online.org/cctbx_sources/scitbx/include/scitbx/stl/set_wrapper.h The sources are also here: http://cctbx.svn.sourceforge.net/viewvc/cctbx/trunk/ but SourceForge viewvc is currently down. Ralf ----- Original Message ---- From: Eric First To: C++-sig at python.org Sent: Thursday, July 24, 2008 7:40:52 AM Subject: [C++-sig] Wrapping std::set using Boost::Python Has anybody wrapped std::set using Boost::Python? I'm looking for the most efficient way to do this. All ideas are greatly appreciated. Thanks. From rogeeff at gmail.com Fri Jul 25 04:13:17 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Fri, 25 Jul 2008 02:13:17 +0000 (UTC) Subject: [C++-sig] using boost::python::list .... References: <37c1dd070807241249l3f6a6a43g727c3a7ff9e100fe@mail.gmail.com> Message-ID: Eric Texier gmail.com> writes: > To make it short: > - should I use the way I do "position" (dynamic) or the way I do for "lookat"(static).? Later, I think. Just create bp::list and assign it. It keeps ref count internally and is cheap to copy (I think). Gennadiy From mathieu.malaterre at gmail.com Fri Jul 25 10:30:33 2008 From: mathieu.malaterre at gmail.com (Mathieu Malaterre) Date: Fri, 25 Jul 2008 10:30:33 +0200 Subject: [C++-sig] Wrapping std::set using Boost::Python In-Reply-To: <101121.96354.qm@web31108.mail.mud.yahoo.com> References: <101121.96354.qm@web31108.mail.mud.yahoo.com> Message-ID: Ralf, apparently viewvc just went back on. During the transition period with no viewvc, I would send path using the svnroot, eg: http://cctbx.svn.sourceforge.net/svnroot/cctbx/trunk/ no history, but at least people can read the last rev of the files. 2cts -Mathieu On Thu, Jul 24, 2008 at 11:14 PM, Ralf W. Grosse-Kunstleve wrote: > You can easily do it from scratch (as an alternative to the indexing suite): > > http://phenix-online.org/cctbx_sources/scitbx/include/scitbx/stl/set_wrapper.h > > The sources are also here: > http://cctbx.svn.sourceforge.net/viewvc/cctbx/trunk/ > but SourceForge viewvc is currently down. > > Ralf > > > ----- Original Message ---- > From: Eric First > To: C++-sig at python.org > Sent: Thursday, July 24, 2008 7:40:52 AM > Subject: [C++-sig] Wrapping std::set using Boost::Python > > > Has anybody wrapped std::set using Boost::Python? I'm looking for the most efficient way to do this. All ideas are greatly appreciated. Thanks. > > _______________________________________________ > C++-sig mailing list > C++-sig at python.org > http://mail.python.org/mailman/listinfo/c++-sig > -- Success is getting what you want. Happiness is wanting what you get. From jeff.webb at nta-inc.net Fri Jul 25 20:29:02 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Fri, 25 Jul 2008 13:29:02 -0500 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <4888E4AE.3000500@nta-inc.net> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> Message-ID: <488A1B6E.3030905@nta-inc.net> At the end of my last post, I listed several deficiencies in my proposed python wrapper, mod1.cpp. Let me start by addressing item (2): > (2) RefHolder objects cannot hold a reference to another RefHolder > object, even though RefHolder is a subclass of VerbosePointee. A simple solution to this problem is to add the following statement at the end of BOOST_PYTHON_MODULE(mod1): implicitly_convertible, intrusive_ptr >(); This statement tells boost::python about the relationship between intrusive_ptr and intrusive_ptr and enables a python user to pass wrapped RefHolder objects to the RefHolder::set_ref function, which is expecting an intrusive_ptr. Let's see if this actually works: >>> from mod1 import * >>> r1 = RefHolder() creating 0xe49c6e0 >>> r2 = RefHolder() creating 0xda13bb0 >>> r1.ref = r2 >>> type(r1.ref) So far, so good. Now on to the next problem: > (3) Although a null pointer is translated to python as None, a > RefHolder's ref member cannot be assigned a value of None. Let's make sure adding the implicitly_convertible call didn't somehow fix the problem: >>> r1.ref = None --------------------------------------------------------------------------- Boost.Python.ArgumentError Traceback (most recent call last) ArgumentError: Python argument types in None.None(RefHolder, NoneType) did not match C++ signature: None(RefHolder {lvalue}, boost::intrusive_ptr) As you can see, this is still an issue. To find a solution, I looked at how the problem was solved for shared_ptr. The solution can be found in this file: include/boost/python/converter/shared_ptr_from_python.hpp I basically made a copy of this function, named it 'intrusive_ptr_from_python', replaced shared_ptr with intrusive_ptr, and left the shared_ptr_deleter argument off of the call to the pointer constructor. In order to register this conversion, the function template must be called from BOOST_PYTHON_MODULE(mod1): boost::python::converter::intrusive_ptr_from_python(); As it turns out, this converter also handles the implicit conversion discussed above, so the implicitly_convertible call is no longer necessary. Now let's test out our new changes, as shown in the attached file, mod2.cpp. >>> from mod2 import * >>> r1 = RefHolder() creating 0xd78af0 >>> r2 = RefHolder() creating 0x17ff260 >>> r1.ref = r2 >>> r1.ref is r2 False >>> r1.ref.id == r2.id True >>> type(r1.ref) >>> v = VerbosePointee() creating 0x1817370 >>> r2.ref = v >>> del r2 >>> r1.ref.ref.id == v.id True >>> del v >>> r1.ref.ref = None destroying 0x1817370 >>> del r1 destroying 0x17ff260 destroying 0xd78af0 So, it looks like this approach handles two of our issues. The object identity problem still remains, but I will save that discussion for another post. Any questions or comments are welcome. -Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: mod2.cpp Type: text/x-c++src Size: 4506 bytes Desc: not available URL: From tbourden at doc.ic.ac.uk Sat Jul 26 13:59:22 2008 From: tbourden at doc.ic.ac.uk (Themistoklis Bourdenas) Date: Sat, 26 Jul 2008 12:59:22 +0100 Subject: [C++-sig] wrapping the PyObject_Call() interface Message-ID: <7fd737460807260459n7ce87771r41b3854ece7cff21@mail.gmail.com> Hi, I was looking in the boost.python for a wrapper of the PyObject_Call() func but couldn't find anything. Did I missed it or has it not been implemented yet? In essence I need to call functions in python by providing a collection (either stl or boost.python collection) of boost::python::object instances instead of giving the arguments in the traditional way. Any ideas, or should I use directly PyObject_Call()? Cheers, Themis -------------- next part -------------- An HTML attachment was scrubbed... URL: From seefeld at sympatico.ca Sat Jul 26 14:46:27 2008 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Sat, 26 Jul 2008 08:46:27 -0400 Subject: [C++-sig] wrapping the PyObject_Call() interface In-Reply-To: <7fd737460807260459n7ce87771r41b3854ece7cff21@mail.gmail.com> References: <7fd737460807260459n7ce87771r41b3854ece7cff21@mail.gmail.com> Message-ID: <488B1CA3.5000304@sympatico.ca> Themistoklis Bourdenas wrote: > Hi, I was looking in the boost.python for a wrapper of the > PyObject_Call() func but couldn't find anything. Did I missed it or > has it not been implemented yet? In essence I need to call functions > in python by providing a collection (either stl or boost.python > collection) of boost::python::object instances instead of giving the > arguments in the traditional way. > > Any ideas, or should I use directly PyObject_Call()? I have a patch for this (https://svn.boost.org/trac/boost/ticket/1316), but it requires a final review. You may apply it to your sources locally. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From borpat at seznam.cz Sat Jul 26 16:51:51 2008 From: borpat at seznam.cz (Borek Patzak) Date: Sat, 26 Jul 2008 16:51:51 +0200 Subject: [C++-sig] Overloaded functions returning Ll and r values Message-ID: <488B3A07.4000503@seznam.cz> Hi, I have a question concerning wrapping overloaded functions returning both l-value and r-value. The simple example: class Array { int size; double *values; Array (int size) {this->size = size; values = new double[size]; } Array () {size=0; values=NULL;} ~Array () {if (size) delete[] values;} inline double &at(int i) { return values [ i - 1 ]; } inline double at(int i) const { return values [ i - 1 ]; } }; double (Array::*at1)(int) const = &Array::at; double& (Array::*at2)(int) = &Array::at; BOOST_PYTHON_MODULE (array_ext) { class_("Array") .def(init()) // the following line generates an error, when invoking bjam .def("at", at2, return_internal_reference<>()) .def("get", at1) ; } I am unable to generate wrapper for "double& Array ::at(int i)". Any help? Best regards, Borek From seefeld at sympatico.ca Sat Jul 26 17:12:18 2008 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Sat, 26 Jul 2008 11:12:18 -0400 Subject: [C++-sig] Overloaded functions returning Ll and r values In-Reply-To: <488B3A07.4000503@seznam.cz> References: <488B3A07.4000503@seznam.cz> Message-ID: <488B3ED2.8000704@sympatico.ca> Borek Patzak wrote: > > I am unable to generate wrapper for "double& Array ::at(int i)". > Any help? > You can't return or pass float, int, string, etc. by reference in Python, as they are immutable. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From bourdenas at gmail.com Sat Jul 26 19:07:30 2008 From: bourdenas at gmail.com (Themis Bourdenas) Date: Sat, 26 Jul 2008 18:07:30 +0100 Subject: [C++-sig] wrapping the PyObject_Call() interface In-Reply-To: <488B1CA3.5000304@sympatico.ca> References: <7fd737460807260459n7ce87771r41b3854ece7cff21@mail.gmail.com> <488B1CA3.5000304@sympatico.ca> Message-ID: <7fd737460807261007l18624d23vc99bd009b5bbc658@mail.gmail.com> Thanks that works fine. Though I'd like to ask you whether there is any reason for unary operator * to work only with boost::python::tuple and not with boost::python::list. At first I used the latter and I got a python exception that while the functions I was calling was requiring N arguments, it was provided with 0. It was also the case of a bound member function, meaning that at least the self argument was already embedded in the boost::python::object I was calling. When I converted the list to a tuple the call run smoothly. Is this patch going to be in the 1.36.0 release? If not are there any plans for which release it will be included in? Cheers, Themis On Sat, Jul 26, 2008 at 1:46 PM, Stefan Seefeld wrote: > Themistoklis Bourdenas wrote: > >> Hi, I was looking in the boost.python for a wrapper of the PyObject_Call() >> func but couldn't find anything. Did I missed it or has it not been >> implemented yet? In essence I need to call functions in python by providing >> a collection (either stl or boost.python collection) of >> boost::python::object instances instead of giving the arguments in the >> traditional way. >> >> Any ideas, or should I use directly PyObject_Call()? >> > I have a patch for this (https://svn.boost.org/trac/boost/ticket/1316), > but it requires a final review. You may apply it to your sources locally. > > 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dave at boostpro.com Sat Jul 26 19:55:59 2008 From: dave at boostpro.com (David Abrahams) Date: Sat, 26 Jul 2008 13:55:59 -0400 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <4888E4AE.3000500@nta-inc.net> (Jeff Webb's message of "Thu, 24 Jul 2008 15:23:10 -0500") References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> Message-ID: <87iqusv8b4.fsf@mcbain.luannocracy.com> on Thu Jul 24 2008, Jeff Webb wrote: > The boost::python library provides excellent support for wrapping C++ > objects managed by boost::shared_ptr reference counting smart > pointers. I am attempting to achieve similar functionality with a > little less memory overhead by embedding the reference count in the > managed object and using boost::intrusive_ptr instead. Why? Have you profiled the memory use of shared_ptr and found it to be a problem? -- Dave Abrahams BoostPro Computing http://www.boostpro.com From mateuszb at gmail.com Sun Jul 27 03:01:21 2008 From: mateuszb at gmail.com (Mateusz Berezecki) Date: Sun, 27 Jul 2008 03:01:21 +0200 Subject: [C++-sig] boost.python fails to recognize type Message-ID: Hi list readers, I want to enable Python to access the C++ class. I do this as follows: BOOST_PYTHON_MODULE(ht) { <...> class_("ScanSpec") .def_readwrite("row_limit", &Hypertable::ScanSpec::row_limit) .def_readwrite("max_versions", &Hypertable::ScanSpec::max_versions) .def_readwrite("columns", &Hypertable::ScanSpec::columns) .def_readwrite("start_row", &Hypertable::ScanSpec::start_row) .def_readwrite("start_row_inclusive", &Hypertable::ScanSpec::start_row_inclusive) .def_readwrite("end_row", &Hypertable::ScanSpec::end_row) .def_readwrite("end_row_inclusive", &Hypertable::ScanSpec::end_row_inclusive) ; <...> } The ScanSpec class is defined as follows: 00087 class ScanSpec { 00088 public: 00089 ScanSpec(); 00090 size_t encoded_length(); 00091 void encode(uint8_t **bufPtr); 00092 bool decode(uint8_t **bufPtr, size_t *remainingPtr); 00093 uint32_t row_limit; 00094 uint32_t max_versions; 00095 std::vector columns; 00096 const char *start_row; 00097 bool start_row_inclusive; 00098 const char *end_row; 00099 bool end_row_inclusive; 00100 std::pair interval; 00101 bool return_deletes; 00102 }; The conversion process happens in the Table class wrapper which is defined as follows class Table { private: Hypertable::TablePtr m_table_ptr; public: Table() {} Table(Hypertable::TablePtr ptr) : m_table_ptr(ptr) {} TableScanner create_scanner(object pyspec) { Hypertable::ScanSpec& spec = extract(pyspec); return TableScanner(m_table_ptr->create_scanner(spec, 10)); } }; The error is as follows TypeError: No registered converter was able to extract a C++ reference to type Hypertable::ScanSpec from this Python object of type Boost.Python.class I've also tried extracting it as a pointer TypeError: No registered converter was able to extract a C++ pointer to type Hypertable::ScanSpec from this Python object of type Boost.Python.class And the same happens when trying to extract a copy of ScanSpec, but this time the error message tells it's not possible to extract rvalue from Boost.Python.class. I've tried every possible combination and it doesn't work. Can somebody please help me ? Mateusz From seefeld at sympatico.ca Sun Jul 27 03:29:41 2008 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Sat, 26 Jul 2008 21:29:41 -0400 Subject: [C++-sig] wrapping the PyObject_Call() interface In-Reply-To: <7fd737460807261007l18624d23vc99bd009b5bbc658@mail.gmail.com> References: <7fd737460807260459n7ce87771r41b3854ece7cff21@mail.gmail.com> <488B1CA3.5000304@sympatico.ca> <7fd737460807261007l18624d23vc99bd009b5bbc658@mail.gmail.com> Message-ID: <488BCF85.4070204@sympatico.ca> Themis Bourdenas wrote: > Thanks that works fine. > > Though I'd like to ask you whether there is any reason for unary > operator * to work only with boost::python::tuple and not with > boost::python::list. At first I used the latter and I got a python > exception that while the functions I was calling was requiring N > arguments, it was provided with 0. It was also the case of a bound > member function, meaning that at least the self argument was already > embedded in the boost::python::object I was calling. When I converted > the list to a tuple the call run smoothly. My patch itself is agnostic to the actual types you pass for args and kwds. The requirement may stem from Python's runtime itself, I'm not sure (and I have no time to test right now), though I find that a bit surprising, as it should be polymorphic (it could even be a user-defined type implementing the sequence protocol). > Is this patch going to be in the 1.36.0 release? If not are there any > plans for which release it will be included in? The patch is going to be checked into trunk, and will end up in whatever releases branch from that. Unfortunately it's too late for the 36 release. Regards, Stefan -- ...ich hab' noch einen Koffer in Berlin... From gjcarneiro at gmail.com Sun Jul 27 19:56:37 2008 From: gjcarneiro at gmail.com (Gustavo Carneiro) Date: Sun, 27 Jul 2008 18:56:37 +0100 Subject: [C++-sig] Announce: PyBindGen 0.9 released Message-ID: PyBindGen is a Python module that is geared to generating C/C++ code that binds a C/C++ library for Python. It does so without extensive use of either C++ templates or C pre-processor macros. It has modular handling of C/C++ types, and can be easily extended with Python plugins. The generated code is almost as clean as what a human programmer would write. It can be downloaded from: http://code.google.com/p/pybindgen/ Bug reports should be filed here: https://bugs.launchpad.net/pybindgen Special thanks to Roman Yakovenko (lots of help with pygccxml) and Mathieu Lacage (API suggestions, documentation writing). === pybindgen 0.9 === - Fix GCC 4.2 compilation warnings; - Works with some GCCXML 0.9/cvs snapshots (tested with 2008-04-20), in addition to stable 0.7; - Support for overloaded virtual methods; - Add 'ignore' annotation support, allowing to ignore functions and methods; - Generally work hard to make sure the generated code at least always compiles, even if we have to disable generation of certain wrappers; - Add support for protected methods and constructors; - Preliminary support for templated classes/methods/functions; - Add more type conversions, such as uint64_t and uint16_t; - Support implicit conversions also for pass-by-reference parameters; - Add supported for nested (i.e. defined inside a class) enums and classes; - Add support for adding manually written custom method or function wrappers; - Split the gccxmlparser.ModuleParser.parse() method into several smaller methods, to allow greater customization and flexibility; - Add support for customising C++ class instance creation code; - Much improved support for wrapping pure C code; - Support std::ostream << myobject mapped as str(myobject) (Mathieu Lacage) - Support default values in parameters; - More intuitive API (thanks Mathieu Lacage for feedback) - Support generation of a Python pybindgen script from scanned API; - Support splitting of generated python script and/or C/C++ module into several files; - Lots of small bug fixes, and other features I probably forgot; - New tutorial (thanks Mathieu Lacage), and API docs. -- Gustavo J. A. M. Carneiro INESC Porto, Telecommunications and Multimedia Unit "The universe is always one step beyond logic." -- Frank Herbert -------------- next part -------------- An HTML attachment was scrubbed... URL: From roman.yakovenko at gmail.com Sun Jul 27 20:33:07 2008 From: roman.yakovenko at gmail.com (Roman Yakovenko) Date: Sun, 27 Jul 2008 21:33:07 +0300 Subject: [C++-sig] boost.python fails to recognize type In-Reply-To: References: Message-ID: <7465b6170807271133k5ee7512fv76c8cca2ee7b698c@mail.gmail.com> On Sun, Jul 27, 2008 at 4:01 AM, Mateusz Berezecki wrote: > Hi list readers, > > I want to enable Python to access the C++ class. > I do this as follows: > > BOOST_PYTHON_MODULE(ht) > { > <...> > class_("ScanSpec") > .def_readwrite("row_limit", &Hypertable::ScanSpec::row_limit) > .def_readwrite("max_versions", &Hypertable::ScanSpec::max_versions) > .def_readwrite("columns", &Hypertable::ScanSpec::columns) > .def_readwrite("start_row", &Hypertable::ScanSpec::start_row) > .def_readwrite("start_row_inclusive", > &Hypertable::ScanSpec::start_row_inclusive) > .def_readwrite("end_row", &Hypertable::ScanSpec::end_row) > .def_readwrite("end_row_inclusive", > &Hypertable::ScanSpec::end_row_inclusive) > ; > <...> > } > > The ScanSpec class is defined as follows: > 00087 class ScanSpec { > 00088 public: > 00089 ScanSpec(); > 00090 size_t encoded_length(); > 00091 void encode(uint8_t **bufPtr); > 00092 bool decode(uint8_t **bufPtr, size_t *remainingPtr); > 00093 uint32_t row_limit; > 00094 uint32_t max_versions; > 00095 std::vector columns; > 00096 const char *start_row; > 00097 bool start_row_inclusive; > 00098 const char *end_row; > 00099 bool end_row_inclusive; > 00100 std::pair interval; > 00101 bool return_deletes; > 00102 }; > > The conversion process happens in the Table class wrapper which is > defined as follows > class Table { > private: > Hypertable::TablePtr m_table_ptr; > > public: > Table() {} > Table(Hypertable::TablePtr ptr) : m_table_ptr(ptr) {} > > TableScanner create_scanner(object pyspec) > { > Hypertable::ScanSpec& spec = extract(pyspec); > return TableScanner(m_table_ptr->create_scanner(spec, 10)); > } > }; > > The error is as follows > TypeError: No registered converter was able to extract a C++ reference > to type Hypertable::ScanSpec from this Python object of type > Boost.Python.class > > I've also tried extracting it as a pointer > TypeError: No registered converter was able to extract a C++ pointer > to type Hypertable::ScanSpec from this Python object of type > Boost.Python.class > > And the same happens when trying to extract a copy of ScanSpec, but > this time the error message tells it's not possible to extract rvalue > from Boost.Python.class. > > I've tried every possible combination and it doesn't work. > > Can somebody please help me ? The first step is to create small and complete example, that shows your problem. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ From rogeeff at gmail.com Sun Jul 27 20:45:32 2008 From: rogeeff at gmail.com (Gennadiy Rozental) Date: Sun, 27 Jul 2008 18:45:32 +0000 (UTC) Subject: [C++-sig] boost.python fails to recognize type References: Message-ID: Mateusz Berezecki gmail.com> writes: > TableScanner create_scanner(object pyspec) > { > Hypertable::ScanSpec& spec = extract(pyspec); > return TableScanner(m_table_ptr->create_scanner(spec, 10)); > } > }; > > The error is as follows > TypeError: No registered converter was able to extract a C++ reference > to type Hypertable::ScanSpec from this Python object of type > Boost.Python.class Obviuosly you are getting object representing class instead of one representing instance of a class. you did not show how create_scanner is exported/invoked. Maybe you exported it as static method? Gennadiy From jeff.webb at nta-inc.net Mon Jul 28 17:53:34 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Mon, 28 Jul 2008 10:53:34 -0500 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <87iqusv8b4.fsf@mcbain.luannocracy.com> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <87iqusv8b4.fsf@mcbain.luannocracy.com> Message-ID: <488DEB7E.5030108@nta-inc.net> David Abrahams wrote: > on Thu Jul 24 2008, Jeff Webb wrote: > >> The boost::python library provides excellent support for wrapping C++ >> objects managed by boost::shared_ptr reference counting smart >> pointers. I am attempting to achieve similar functionality with a >> little less memory overhead by embedding the reference count in the >> managed object and using boost::intrusive_ptr instead. > > Why? Have you profiled the memory use of shared_ptr and found it to be > a problem? I investigated the memory usage of shared_ptr by running valgrind on a test program and by looking at the shared_ptr source code. My findings are summarized in this post: http://mail.python.org/pipermail/c++-sig/2008-July/013786.html I am designing a C++ library from the ground up, so I am not tied to any existing conventions (base classes, memory management schemes, etc.). I want to be able to expose the fundamental building blocks of my library to python, but I want to allow the library to be used without python as well. I have decided to use smart pointers internally in my C++ library to lay the foundation for seamless integration with python. Some of my library building blocks are very small, and users will most likely have a large number of instances, so the overhead of the internal memory management scheme is a concern. I am less concerned by the overhead of the python wrappers, since I expect a small percentage of these objects to by wrapped by python at any given time. It think that by using intrusive_ptr, I can save one raw pointer's worth of memory for every smart pointer I use, and another raw pointer's worth of memory (plus maybe an int) for the managed objects themselves. I have included the highlights of my previous email below, but you can use the link above if you want to look at the full post. I would be interested in hearing any thoughts you may have on any of this. Thanks, Jeff -------- Original Message -------- Date: Thu, 17 Jul 2008 18:02:26 -0500 From: Jeff Webb To: Development of Python/C++ integration Subject: shared_ptr vs. intrusive_ptr [...] I have attempted to quantify the memory usage of shared_ptr vs. a simple intrusive_ptr implementation using the attached test program. I used valgrind to verify the dynamic memory usage. Here are the results: shared_ptr ---------- Each shared_ptr is the size of two raw pointers (one for the managed object, and one for the shared reference count): A total of 8 bytes on x86 or 16 bytes on x86_64 For each object that is managed by shared_ptrs, a shared reference count must be allocated. The memory usage for the shared reference count appears to be two integers and two pointers: A total of 16 bytes on x86 or 24 bytes on x86_64 When looking at the shared_ptr source code, I could only find one pointer in the shared reference count, but I cannot reconcile this with the memory usage reported by valgrind. I suppose it doesn't really matter, but the breakdown I found in the code is listed below. Maybe I am not looking at the right implementation for my system. sp_counted_impl_p: sp_counted_base: int use_count_; (4 bytes) int weak_count_; (4 bytes) vtable pointer? (4 or 8 bytes) X * (4 or 8 bytes) intrusive_ptr ------------- Each intrusive_ptr is the size of a raw pointer: A total of 4 bytes on x86 or 8 bytes on x86_64 For each object that is being managed by this intrusive_ptr implementation, an extra integer must be added to the object to hold the reference count: A total of 4 bytes on x86 or x86_64 [...] From dave at boostpro.com Mon Jul 28 18:10:58 2008 From: dave at boostpro.com (David Abrahams) Date: Mon, 28 Jul 2008 12:10:58 -0400 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488A1B6E.3030905@nta-inc.net> Message-ID: <87ej5eyood.fsf@mcbain.luannocracy.com> on Fri Jul 25 2008, Jeff Webb wrote: > So, it looks like this approach handles two of our issues. The object > identity problem still remains, but I will save that discussion for > another post. Any questions or comments are welcome. The object identity issue is the big one. Without a custom deleter -- which is why shared_ptr works so smoothly -- there's little you can do about it, AFAIK. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From jeff.webb at nta-inc.net Mon Jul 28 18:39:17 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Mon, 28 Jul 2008 11:39:17 -0500 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <87ej5eyood.fsf@mcbain.luannocracy.com> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488A1B6E.3030905@nta-inc.net> <87ej5eyood.fsf@mcbain.luannocracy.com> Message-ID: <488DF635.4070108@nta-inc.net> David Abrahams wrote: > on Fri Jul 25 2008, Jeff Webb wrote: > >> So, it looks like this approach handles two of our issues. The object >> identity problem still remains, but I will save that discussion for >> another post. Any questions or comments are welcome. > > The object identity issue is the big one. Without a custom deleter -- > which is why shared_ptr works so smoothly -- there's little you can do > about it, AFAIK. Thanks, Dave. I have found a solution that seems to work for me. I will post it soon. I would definitely like to have you and some others take a look at it and see if it looks reasonable. -Jeff From hans_meine at gmx.net Mon Jul 28 19:59:05 2008 From: hans_meine at gmx.net (Hans Meine) Date: Mon, 28 Jul 2008 19:59:05 +0200 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <488DEB7E.5030108@nta-inc.net> References: <87iqusv8b4.fsf@mcbain.luannocracy.com> <488DEB7E.5030108@nta-inc.net> Message-ID: <200807281959.05497.hans_meine@gmx.net> On Montag 28 Juli 2008, Jeff Webb wrote: > I have included the highlights of my previous email below, but you can use > the link above if you want to look at the full post. I would be interested > in hearing any thoughts you may have on any of this. Let me just say thanks for your first two write-ups, they're much appreciated and will most probably be of help for future BPL users with similar needs. -- Ciao, / / .o. /--/ ..o / / ANS ooo -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: This is a digitally signed message part. URL: From amohr at pixar.com Mon Jul 28 20:46:36 2008 From: amohr at pixar.com (Alex Mohr) Date: Mon, 28 Jul 2008 11:46:36 -0700 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <87ej5eyood.fsf@mcbain.luannocracy.com> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488A1B6E.3030905@nta-inc.net> <87ej5eyood.fsf@mcbain.luannocracy.com> Message-ID: <488E140C.2020805@pixar.com> > The object identity issue is the big one. Without a custom deleter -- > which is why shared_ptr works so smoothly -- there's little you can do > about it, AFAIK. I have a solution to object identity using custom smart pointers, but it's quite ugly. The crux of it is to register your own to and from python conversions that do the identity work. I posted a "sketch" of how I do this awhile ago: http://mail.python.org/pipermail/c++-sig/2008-January/013265.html Alex From jeff.webb at nta-inc.net Mon Jul 28 23:33:21 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Mon, 28 Jul 2008 16:33:21 -0500 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <488E140C.2020805@pixar.com> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488A1B6E.3030905@nta-inc.net> <87ej5eyood.fsf@mcbain.luannocracy.com> <488E140C.2020805@pixar.com> Message-ID: <488E3B21.5020300@nta-inc.net> Alex Mohr wrote: >> The object identity issue is the big one. Without a custom deleter -- >> which is why shared_ptr works so smoothly -- there's little you can do >> about it, AFAIK. > > I have a solution to object identity using custom smart pointers, but > it's quite ugly. The crux of it is to register your own to and from > python conversions that do the identity work. I posted a "sketch" of > how I do this awhile ago: > > http://mail.python.org/pipermail/c++-sig/2008-January/013265.html Good stuff, Alex. I think I can learn some things from this code. Thanks for posting it and documenting it with comments. -Jeff From mateuszb at gmail.com Tue Jul 29 00:21:46 2008 From: mateuszb at gmail.com (Mateusz Berezecki) Date: Tue, 29 Jul 2008 00:21:46 +0200 Subject: [C++-sig] boost.python fails to recognize type Message-ID: Hello, That's the complete example code #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::python; using Hypertable::ScanSpec; class TableScanner { private: Hypertable::TableScannerPtr m_scanner; public: TableScanner() {} TableScanner(Hypertable::TableScannerPtr ptr) : m_scanner(ptr) { } bool next(Hypertable::Cell& cell) { return m_scanner->next(cell); } }; class Table { private: Hypertable::TablePtr m_table_ptr; public: Table() { } Table(Hypertable::TablePtr ptr) : m_table_ptr(ptr) { } TableScanner create_scanner(object const &pyspec) { extract ex(pyspec); ScanSpec& spec = ex(); return TableScanner(m_table_ptr->create_scanner(spec, 10)); } }; class Client { private: Hypertable::ClientPtr m_client; public: Client(const std::string& argv0) { m_client = new Hypertable::Client(argv0.c_str()); } Client(const std::string& argv0, const std::string& config) { m_client = new Hypertable::Client(argv0.c_str(), config); } Table open_table(const std::string& name) { Hypertable::TablePtr t = m_client->open_table(name); return Table(t); } }; BOOST_PYTHON_MODULE(ht) { class_("Client", init()) .def(init()) .def("open_table", &Client::open_table) ; class_("Table", "Table representation") .def("create_scanner", &Table::create_scanner) ; class_("TableScanner") .def("next", &TableScanner::next) ; class_("ScanSpec", "scan spec docstring") .def_readwrite("row_limit", &ScanSpec::row_limit) .def_readwrite("max_versions", &ScanSpec::max_versions) .def_readwrite("columns", &ScanSpec::columns) .def_readwrite("start_row", &ScanSpec::start_row) .def_readwrite("start_row_inclusive", &ScanSpec::start_row_inclusive) .def_readwrite("end_row", &ScanSpec::end_row) .def_readwrite("end_row_inclusive", &ScanSpec::end_row_inclusive) ; class_("Cell") .def_readonly("row_key", &Hypertable::Cell::row_key) .def_readonly("column_family", &Hypertable::Cell::column_family) .def_readonly("column_qualifier", &Hypertable::Cell::column_qualifier) .def_readonly("timestamp", &Hypertable::Cell::timestamp) .def_readonly("value", &Hypertable::Cell::value) .def_readonly("value_len", &Hypertable::Cell::value_len) .def_readonly("flag", &Hypertable::Cell::flag) ; } and the python code invoking it is: import ht client = ht.Client("ht", "/opt/hypertable/0.9.0.7/conf/hypertable.cfg") table = client.open_table("METADATA") scan_spec = ht.ScanSpec scan_spec.start_row = 0 scan_spec.start_row = "\x00" scan_spec.end_row = "\xff\xff" scan_spec.start_row_inclusive = True scan_spec.end_row_inclusive = True scan_spec.max_versions = 1 print scan_spec.__doc__ print table.__doc__ print scan_spec scanner = table.create_scanner(scan_spec) This yields the errors mentioned in the previous post. I am stuck on this one really badly. I just started playing with Boost.Python 2 days ago. Mateusz From jeff.webb at nta-inc.net Tue Jul 29 00:27:27 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Mon, 28 Jul 2008 17:27:27 -0500 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <4888E4AE.3000500@nta-inc.net> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> Message-ID: <488E47CF.4080803@nta-inc.net> Jeff Webb wrote: > (1) There is an object identity problem (i.e. 'r.ref is v' is False). > This means that there are two python wrappers for a single C++ object. > In some cases this is okay, but it is not ideal. In order to solve the object identity problem mentioned above, I needed some method of storing the PyObject pointer that is wrapping a given Pointee object and a way of looking it up. There are two methods that I have tried: (1) storing the PyObject pointer in the Pointee object itself (2) using a global dictionary to store the Pointee->PyObject mappings I initially used solution (1), which worked well for me since I have control over the Pointee data structure. I later decided that I would rather not have the overhead of an extra pointer stored in every Pointee object, whether it was accessed from python or not, so I tried approach (2), which is what I am posting here. If you like method (1) better, I think it will be easy for you to modify the attached example to work that way. I have modified my previous example (mod2.cpp) in several ways: (1) I added set_pyobject_for_pointee, get_pyobject_for_pointee, and clear_pyobject_for_pointee functions that manipulate a global std::map object. (2) I have specialized the make_instance_impl template for a T object held by an intrusive_ptr. (3) I added an init_class function template along with a helper function called install_pointer_in_pyobject. (4) I have modified the class wrappers by adding a no_init argument to the class_ statements, adding an __init__ method to call the init_class function, and adding a __del__ method that removes the pyobject pointer for the corresponding C++ object when a python wrapper is destroyed. The make_instance_impl template is where code was added to check for an existing python wrapper and to record the PyObject pointer when a new wrapper is generated. The init_class method is necessary to record the PyObject pointer when an object is created from python because the make_instance_impl template is not called in that case. The __del__ method is necessary to remove a PyObject pointer from the std::map object when a python wrapper is destroyed. I'm sure there are better ways to do some of these things, but I think you will find my modifications understandable. It see at least two main areas where there could be memory leaks: the install_pointer_in_pyobject function and the code in make_instance_impl that returns a reference to an existing pyobject. If someone could at least take a look at those sections, I would appreciate it. Here is a sample session with the new version of our module: >>> from mod3 import * >>> r1 = RefHolder() creating 0xb0741c0 >>> r2 = RefHolder() creating 0xb077140 >>> r1.ref = r2 >>> r1.ref is r2 True >>> v = VerbosePointee() creating 0xb9a95f0 >>> r2.ref = v >>> del v >>> del r2 >>> print r1.ref >>> r1.ref.ref = None destroying 0xb9a95f0 >>> del r1 destroying 0xb077140 destroying 0xb0741c0 >From the output above, it appears that the object identity problem I mentioned has been solved. The __del__ method also seems to have done it's job since we can still access r1.ref without a segmentation fault even after r2 has been deleted. This approach has worked reliably as far as I can tell. Any comments or questions on the implementation are more than welcome. -Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: mod3.cpp Type: text/x-c++src Size: 10849 bytes Desc: not available URL: From seefeld at sympatico.ca Tue Jul 29 00:37:51 2008 From: seefeld at sympatico.ca (Stefan Seefeld) Date: Mon, 28 Jul 2008 18:37:51 -0400 Subject: [C++-sig] boost.python fails to recognize type In-Reply-To: References: Message-ID: <488E4A3F.4030502@sympatico.ca> Mateusz Berezecki wrote: > Hello, > > That's the complete example code > I guess you missed the other keyword: small (or as I would have spelled it: minimal). As Gennadi guessed, you didn't instantiate your ScanSpec. Try replacing scan_spec = ht.ScanSpec by scan_spec = ht.ScanSpec() and all should work fine. HTH, Stefan -- ...ich hab' noch einen Koffer in Berlin... From dave at boostpro.com Tue Jul 29 01:23:44 2008 From: dave at boostpro.com (David Abrahams) Date: Mon, 28 Jul 2008 19:23:44 -0400 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <488E47CF.4080803@nta-inc.net> (Jeff Webb's message of "Mon, 28 Jul 2008 17:27:27 -0500") References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488E47CF.4080803@nta-inc.net> Message-ID: <87ej5dy4n3.fsf@mcbain.luannocracy.com> on Mon Jul 28 2008, Jeff Webb wrote: > Jeff Webb wrote: >> (1) There is an object identity problem (i.e. 'r.ref is v' is >> False). This means that there are two python wrappers for a single >> C++ object. In some cases this is okay, but it is not ideal. > > In order to solve the object identity problem mentioned above, I needed some method of storing the PyObject pointer that is wrapping a given Pointee object and a way of looking it up. There are two methods that I have tried: > > (1) storing the PyObject pointer in the Pointee object itself http://www.boost.org/doc/libs/1_35_0/libs/python/doc/v2/has_back_reference.html > (2) using a global dictionary to store the Pointee->PyObject mappings Isn't this going to incur comparable memory use to shared_ptr? -- Dave Abrahams BoostPro Computing http://www.boostpro.com From dave at boostpro.com Tue Jul 29 01:37:58 2008 From: dave at boostpro.com (David Abrahams) Date: Mon, 28 Jul 2008 19:37:58 -0400 Subject: [C++-sig] boost.python fails to recognize type In-Reply-To: (Mateusz Berezecki's message of "Tue, 29 Jul 2008 00:21:46 +0200") References: Message-ID: <87abg1y3zd.fsf@mcbain.luannocracy.com> on Mon Jul 28 2008, "Mateusz Berezecki" wrote: > This yields the errors mentioned in the previous post. But it's huge. Please systematically cut it down to the absolute minimum you need in order to be able to demonstrate the problem. I'll bet you find the source of the problem yourself, but if you don't, we'll be able to help you. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From amohr at pixar.com Tue Jul 29 02:20:02 2008 From: amohr at pixar.com (Alex Mohr) Date: Mon, 28 Jul 2008 17:20:02 -0700 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <87ej5dy4n3.fsf@mcbain.luannocracy.com> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488E47CF.4080803@nta-inc.net> <87ej5dy4n3.fsf@mcbain.luannocracy.com> Message-ID: <488E6232.9030605@pixar.com> >> (2) using a global dictionary to store the Pointee->PyObject mappings > > Isn't this going to incur comparable memory use to shared_ptr? We use a global table. Suppose you have a system where there are hundreds of thousands of objects and only some small fraction of them are passed to python. In this case, adding 8 bytes of overhead to every object versus adding 8 bytes of overhead to only those objects passed to python can save 100s of KB of memory. Perhaps that doesn't sound like a lot these days, but when your users are always trying to push the hardware and software as hard as they possibly can, it can definitely make a difference. Formerly I embedded the python objects inside the C++ objects but switched to the global table due to memory usage. Alex From dave at boostpro.com Tue Jul 29 02:53:14 2008 From: dave at boostpro.com (David Abrahams) Date: Mon, 28 Jul 2008 20:53:14 -0400 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <488E6232.9030605@pixar.com> (Alex Mohr's message of "Mon, 28 Jul 2008 17:20:02 -0700") References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488E47CF.4080803@nta-inc.net> <87ej5dy4n3.fsf@mcbain.luannocracy.com> <488E6232.9030605@pixar.com> Message-ID: <87od4hwlxh.fsf@mcbain.luannocracy.com> on Mon Jul 28 2008, Alex Mohr wrote: >>> (2) using a global dictionary to store the Pointee->PyObject mappings >> >> Isn't this going to incur comparable memory use to shared_ptr? > > We use a global table. > > Suppose you have a system where there are hundreds of thousands of > objects and only some small fraction of them are passed to python. > > In this case, adding 8 bytes of overhead to every object versus adding > 8 bytes of overhead to only those objects passed to python can save > 100s of KB of memory. Perhaps that doesn't sound like a lot these > days, but when your users are always trying to push the hardware and > software as hard as they possibly can, it can definitely make a > difference. > > Formerly I embedded the python objects inside the C++ objects but > switched to the global table due to memory usage. I wasn't talking about adding storage to every instance of a class. Boost.Python converts any wrapped object of type T to a shared_ptr which, when passed back to Python, gets converted back to the original Python object. The last shared_ptr to that object may be reclaimed when the C++ code is done using it. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From jeff.webb at nta-inc.net Tue Jul 29 04:41:16 2008 From: jeff.webb at nta-inc.net (Jeff Webb) Date: Mon, 28 Jul 2008 21:41:16 -0500 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <87od4hwlxh.fsf@mcbain.luannocracy.com> References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488E47CF.4080803@nta-inc.net> <87ej5dy4n3.fsf@mcbain.luannocracy.com> <488E6232.9030605@pixar.com> <87od4hwlxh.fsf@mcbain.luannocracy.com> Message-ID: <488E834C.2030601@nta-inc.net> David Abrahams wrote: > on Mon Jul 28 2008, Alex Mohr wrote: > >>>> (2) using a global dictionary to store the Pointee->PyObject mappings >>> Isn't this going to incur comparable memory use to shared_ptr? >> We use a global table. >> >> Suppose you have a system where there are hundreds of thousands of >> objects and only some small fraction of them are passed to python. >> >> In this case, adding 8 bytes of overhead to every object versus adding >> 8 bytes of overhead to only those objects passed to python can save >> 100s of KB of memory. Perhaps that doesn't sound like a lot these >> days, but when your users are always trying to push the hardware and >> software as hard as they possibly can, it can definitely make a >> difference. >> >> Formerly I embedded the python objects inside the C++ objects but >> switched to the global table due to memory usage. > > I wasn't talking about adding storage to every instance of a class. > > Boost.Python converts any wrapped object of type T to a shared_ptr > which, when passed back to Python, gets converted back to the original > Python object. The last shared_ptr to that object may be reclaimed when > the C++ code is done using it. It sounds like Alex and I have very similar applications, or at least we're thinking along the same lines. I am using smart pointers for memory management within the C++ library itself. Objects hold smart pointers to other objects, and smart pointers to objects are passed as arguments to various member functions. I want these smart pointers to be as memory efficient as possible because there will be a lot of them. I also want to be able to expose any of these objects (as well as functions that take smart pointers to these objects) to python without adding memory overhead to the internal smart pointers or the class instances themselves. As Alex mentioned, adding some overhead to keep track of the wrapped objects is acceptable (and probably unavoidable), so the global table seems like a good option. To clarify, are you suggesting that I should change my internal C++ code to use shared_ptrs everywhere, or something else? Sorry that it's taking us a while to get on the same page. -Jeff From dave at boostpro.com Tue Jul 29 15:47:11 2008 From: dave at boostpro.com (David Abrahams) Date: Tue, 29 Jul 2008 09:47:11 -0400 Subject: [C++-sig] alternative smart pointer (intrusive_ptr) example In-Reply-To: <488E834C.2030601@nta-inc.net> (Jeff Webb's message of "Mon, 28 Jul 2008 21:41:16 -0500") References: <200807220656.22034.meine@informatik.uni-hamburg.de> <4885ED8D.6090804@nta-inc.net> <200807231119.36451.meine@informatik.uni-hamburg.de> <4888E4AE.3000500@nta-inc.net> <488E47CF.4080803@nta-inc.net> <87ej5dy4n3.fsf@mcbain.luannocracy.com> <488E6232.9030605@pixar.com> <87od4hwlxh.fsf@mcbain.luannocracy.com> <488E834C.2030601@nta-inc.net> Message-ID: <87wsj4u7j4.fsf@mcbain.luannocracy.com> on Mon Jul 28 2008, Jeff Webb wrote: > David Abrahams wrote: >> on Mon Jul 28 2008, Alex Mohr wrote: >> >>>>> (2) using a global dictionary to store the Pointee->PyObject mappings >>>> Isn't this going to incur comparable memory use to shared_ptr? >>> We use a global table. >>> >>> Suppose you have a system where there are hundreds of thousands of >>> objects and only some small fraction of them are passed to python. >>> >>> In this case, adding 8 bytes of overhead to every object versus adding >>> 8 bytes of overhead to only those objects passed to python can save >>> 100s of KB of memory. Perhaps that doesn't sound like a lot these >>> days, but when your users are always trying to push the hardware and >>> software as hard as they possibly can, it can definitely make a >>> difference. >>> >>> Formerly I embedded the python objects inside the C++ objects but >>> switched to the global table due to memory usage. >> >> I wasn't talking about adding storage to every instance of a class. >> >> Boost.Python converts any wrapped object of type T to a shared_ptr >> which, when passed back to Python, gets converted back to the original >> Python object. The last shared_ptr to that object may be reclaimed when >> the C++ code is done using it. > > It sounds like Alex and I have very similar applications, or at least > we're thinking along the same lines. I am using smart pointers for > memory management within the C++ library itself. Objects hold smart > pointers to other objects, and smart pointers to objects are passed as > arguments to various member functions. I want these smart pointers to > be as memory efficient as possible because there will be a lot of > them. > > I also want to be able to expose any of these objects (as well as > functions that take smart pointers to these objects) to python without > adding memory overhead to the internal smart pointers or the class > instances themselves. As Alex mentioned, adding some overhead to keep > track of the wrapped objects is acceptable (and probably unavoidable), > so the global table seems like a good option. OK. > To clarify, are you suggesting that I should change my internal C++ > code to use shared_ptrs everywhere, or something else? Nope, I was forgetting that doubtless also want to use your Python-exposed API from C++. -- Dave Abrahams BoostPro Computing http://www.boostpro.com From pwinston at gmail.com Wed Jul 30 05:14:18 2008 From: pwinston at gmail.com (Philip Winston) Date: Tue, 29 Jul 2008 23:14:18 -0400 Subject: [C++-sig] application exit and shared_ptr Message-ID: <33677e5d0807292014s5cae77cdm7fa02b0fc21e6645@mail.gmail.com> I understand it is not possible to call Py_Finalize with Boost.Python. But is it possible to manually delete all variables from an embedded interactive interpreter? Would this be a way to to cause Python to release any shared_ptrs it is holding on to? So we return shared_ptrs from our API. But at exit (and possibly other times) we'd like to reset the interpreter, so it's no longer holding any shared_ptrs, so those objects are free to be deleted if no other references are held. Some specific excerpts (any other advice welcome): excerpts: m_mainmodule = import("__main__"); m_namespace = m_mainmodule.attr("__dict__"); exec("import PyInteractive"); exec("__pyInteractiveExec = PyInteractive.PyInteractive().executeline"); m_interactive = extract(m_namespace["__pyInteractiveExec"]); then we repeatedly call: m_interactive(string); S now we'd like to delete all objects the user created interactively at the prompt. Thanks. Philip Winston pwinston at gmail.com From dave at boostpro.com Wed Jul 30 20:33:01 2008 From: dave at boostpro.com (David Abrahams) Date: Wed, 30 Jul 2008 14:33:01 -0400 Subject: [C++-sig] application exit and shared_ptr In-Reply-To: <33677e5d0807292014s5cae77cdm7fa02b0fc21e6645@mail.gmail.com> (Philip Winston's message of "Tue, 29 Jul 2008 23:14:18 -0400") References: <33677e5d0807292014s5cae77cdm7fa02b0fc21e6645@mail.gmail.com> Message-ID: <87provnrxe.fsf@mcbain.luannocracy.com> on Tue Jul 29 2008, "Philip Winston" wrote: > I understand it is not possible to call Py_Finalize with Boost.Python. > But is it possible to manually delete all variables from an embedded > interactive interpreter? Would this be a way to to cause Python to > release any shared_ptrs it is holding on to? That's essentially the same problem, because any Python object could be holding a shared_ptr (indirectly). -- Dave Abrahams BoostPro Computing http://www.boostpro.com From amohr at pixar.com Thu Jul 31 19:09:55 2008 From: amohr at pixar.com (Alex Mohr) Date: Thu, 31 Jul 2008 10:09:55 -0700 Subject: [C++-sig] Crash (segfault) on del(x.__dict__) where x is a boost.python wrapped instance. Message-ID: <4891F1E3.6050506@pixar.com> Tested with boost 1.34 on x86-64 linux, gcc 4.1.2. I have attached a very small example below. I know that del(x.__dict__) is a rather odd thing to try to do, and we stumbled upon this by accident. It is not a big deal for us. That said, it might be nice to fix if it's easy. Thanks, Alex //////////////////////////////////////////////////////////////////////// // C++ #include class X {}; BOOST_PYTHON_MODULE(del_dict_segfault) { boost::python::class_("X"); } ######################################################################## ## Python >>> from del_dict_segfault import X >>> x = X() >>> del(x.__dict__) # this segfaults.