From f.maile at gmx.de Tue May 13 10:08:01 2014 From: f.maile at gmx.de (Florian Maile) Date: Tue, 13 May 2014 10:08:01 +0200 Subject: [C++-sig] LINK : fatal error LNK1181: cannot open input file 'python26_d.lib' Message-ID: An HTML attachment was scrubbed... URL: From nikolay.mladenov at gmail.com Wed May 14 14:07:56 2014 From: nikolay.mladenov at gmail.com (Nikolay Mladenov) Date: Wed, 14 May 2014 08:07:56 -0400 Subject: [C++-sig] LINK : fatal error LNK1181: cannot open input file 'python26_d.lib' In-Reply-To: References: Message-ID: May be remove the python debugging? On Tue, May 13, 2014 at 4:08 AM, Florian Maile wrote: > Hello, > > I?m really getting insane of building the tutorial. My steps were: > > > 1. Unpacking the ZIP > 2. Running bootstrap in the boost.python root directory > 3. Configuration of user-config.jam as below: > > > # Copyright 2003, 2005 Douglas Gregor > # Copyright 2004 John Maddock > # Copyright 2002, 2003, 2004, 2007 Vladimir Prus > # Distributed under the Boost Software License, Version 1.0. > # (See accompanying file LICENSE_1_0.txt or > http://www.boost.org/LICENSE_1_0.txt) > > # This file is used to configure your Boost.Build installation. You can > modify > # this file in place, or you can place it in a permanent location so that > it > # does not get overwritten should you get a new version of Boost.Build. > See: > # > # > http://www.boost.org/boost-build2/doc/html/bbv2/overview/configuration.html > # > # for documentation about possible permanent locations. > > # This file specifies which toolsets (C++ compilers), libraries, and > other > # tools are available. Often, you should be able to just uncomment existing > # example lines and adjust them to taste. The complete list of supported > tools, > # and configuration instructions can be found at: > # > # http://boost.org/boost-build2/doc/html/bbv2/reference/tools.html > # > > # This file uses Jam language syntax to describe available tools. Mostly, > # there are 'using' lines, that contain the name of the used tools, and > # parameters to pass to those tools -- where paremeters are separated by > # semicolons. Important syntax notes: > # > # - Both ':' and ';' must be separated from other tokens by whitespace > # - The '\' symbol is a quote character, so when specifying Windows > paths you > # should use '/' or '\\' instead. > # > # More details about the syntax can be found at: > # > # > http://boost.org/boost-build2/doc/html/bbv2/advanced.html#bbv2.advanced.jam_language > # > > # ------------------ > # GCC configuration. > # ------------------ > > # Configure gcc (default version). > # using gcc ; > > # Configure specific gcc version, giving alternative name to use. > # using gcc : 3.2 : g++-3.2 ; > > > # ------------------- > # MSVC configuration. > # ------------------- > > # Configure msvc (default version, searched for in standard locations and > PATH). > # using msvc ; > > # Configure specific msvc version (searched for in standard locations and > PATH). > using msvc : 10.0 : C:\\app\\tools\\MSVisualStudio2010\\VC\\bin\\cl.exe ; > > > # ---------------------- > # Borland configuration. > # ---------------------- > # using borland ; > > > # ---------------------- > # STLPort configuration. > # ---------------------- > > # Configure specifying location of STLPort headers. Libraries must be > either > # not needed or available to the compiler by default. > # using stlport : : /usr/include/stlport ; > > # Configure specifying location of both headers and libraries explicitly. > # using stlport : : /usr/include/stlport /usr/lib ; > > > # ----------------- > # QT configuration. > # ----------------- > > # Configure assuming QTDIR gives the installation prefix. > # using qt ; > > # Configure with an explicit installation prefix. > # using qt : /usr/opt/qt ; > > # --------------------- > # Python configuration. > # --------------------- > > # Configure specific Python version. > # using python : 3.1 : /usr/bin/python3 : /usr/include/python3.1 : > /usr/lib ; > > using python > : 2.6 > > # Version > : > C:\\app\\Python26\\python.exe # > Python Path > : > C:\\app\\Python26\\include # include path > : > C:\\app\\Python26\\libs > # lib path(s) > : on BOOST_ALL_NO_LIB=1 > ; > > > > 1. Invoking bjam in the tutorial directory as below: > > > C:\User\Z182428\boost_1_55_0\libs\python\example>cd tutorial > > C:\User\Z182428\boost_1_55_0\libs\python\example\tutorial>bjam > link.jam: No such file or directory > ...patience... > ...patience... > ...found 1674 targets... > ...updating 53 targets... > common.mkdir bin > common.mkdir bin\msvc-10.0 > common.mkdir bin\msvc-10.0\debug > common.mkdir ..\..\..\..\bin.v2 > common.mkdir ..\..\..\..\bin.v2\libs > common.mkdir ..\..\..\..\bin.v2\libs\python > common.mkdir ..\..\..\..\bin.v2\libs\python\build > common.mkdir ..\..\..\..\bin.v2\libs\python\build\msvc-10.0 > common.mkdir ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\numeric.obj > numeric.cpp > compile-c-c++ ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\list.obj > list.cpp > compile-c-c++ ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\long.obj > long.cpp > compile-c-c++ ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\dict.obj > dict.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\tuple.obj > tuple.cpp > compile-c-c++ ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\str.obj > str.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\slice.obj > slice.cpp > common.mkdir ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\converter > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\converter\fro > m_python.obj > from_python.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\converter\reg > istry.obj > registry.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\converter\typ > e_id.obj > type_id.cpp > common.mkdir ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\enum.o > bj > enum.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\class. > obj > class.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\functi > on.obj > function.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\inheri > tance.obj > inheritance.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\life_s > upport.obj > life_support.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\pickle > _support.obj > pickle_support.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\errors.obj > errors.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\module.obj > module.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\converter\bui > ltin_converters.obj > builtin_converters.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\converter\arg > _to_python_base.obj > arg_to_python_base.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\iterat > or.obj > iterator.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\stl_it > erator.obj > stl_iterator.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object_protoc > ol.obj > object_protocol.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object_operat > ors.obj > object_operators.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\wrapper.obj > wrapper.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\import.obj > import.cpp > compile-c-c++ ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\exec.obj > exec.cpp > compile-c-c++ > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\object\functi > on_doc_signature.obj > function_doc_signature.cpp > msvc.link.dll > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\boost_python- > vc100-gd-1_55.dll > LINK : fatal error LNK1181: cannot open input file 'python26_d.lib' > > call "C:\app\tools\msvisualstudio2010\vc\vcvarsall.bat" x86 >nul > link /NOLOGO /INCREMENTAL:NO /DLL /DEBUG /MACHINE:X86 /MANIFEST > /subsystem:conso > le > /out:"..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\boost_python-vc100 > -gd-1_55.dll" > /IMPLIB:"..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\boos > t_python-vc100-gd-1_55.lib" /LIBPATH:"C:\app\Python26\libs" > @"..\..\..\..\bin. > v2\libs\python\build\msvc-10.0\debug\boost_python-vc100-gd-1_55.dll.rsp" > if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL% > > ...failed msvc.link.dll > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug\boo > st_python-vc100-gd-1_55.dll > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\debug > \boost_python-vc100-gd-1_55.lib > ..\..\..\..\bin.v2\libs\python\build\msvc-10.0\d > ebug\boost_python-vc100-gd-1_55.pdb... > compile-c-c++ bin\msvc-10.0\debug\hello.obj > hello.cpp > ...skipped hello_ext.dll for lack of > libs\python\build\msvc-10.0\debug>boost_python-vc100-gd-1_55.lib... > ...skipped hello_ext.lib for lack of > libs\python\build\msvc-10.0\debug>boost_python-vc100-gd-1_55.lib... > ...skipped hello_ext.pdb for lack of > libs\python\build\msvc-10.0\debug>boost_python-vc100-gd-1_55.lib... > ...skipped boost_python-vc100-gd-1_55.dll for lack of > ibs\python\build\msvc-10.0\debug>boost_python-vc100-gd-1_55.dll... > ...skipped hello_ext.dll for lack of > hello_ext.dll... > common.mkdir bin\hello.test > common.mkdir bin\hello.test\msvc-10.0 > common.mkdir bin\hello.test\msvc-10.0\debug > ...skipped hello for lack of > bug>hello_ext.dll... > ...failed updating 3 targets... > ...skipped 7 targets... > ...updated 43 targets... > > C:\User\Z182428\boost_1_55_0\libs\python\example\tutorial> > > I would be very grateful if someone could give me a clue ! > > Thank a lot in advance ! > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > https://mail.python.org/mailman/listinfo/cplusplus-sig > -------------- next part -------------- An HTML attachment was scrubbed... URL: From larsand at gmail.com Mon May 19 08:27:39 2014 From: larsand at gmail.com (laan) Date: Sun, 18 May 2014 23:27:39 -0700 (PDT) Subject: [C++-sig] Boost::Python Reference Counting Message-ID: <1400480859720-4662504.post@n4.nabble.com> Hi, I'm having issues with Boost::Python objects that contain a reference to a c++ object: --- C++ code ---- #include struct Container; struct Element { Element(const Container * c) : _container(c) { } std::string name() const; const Container * _container; }; struct Container { Container(const std::string & s) : _string(s) { } Element getElement() { return Element(this); } std::string name() const { return this->_string; } std::string _string; }; std::string Element::name() const { return _container->name(); } using namespace boost::python; BOOST_PYTHON_MODULE(libkatya) { class_("Element", no_init) .def("name", &Element::name) ; class_("Container", init()) .def("getElement", &Container::getElement) ; } --- Python Code ---------------------- container = test.Container("X") elem = container.getElement() del(container) print(elem.name()) When calling elem.name(), it will reference the "container" object, which has been deleted, and I'm getting a segfault. How can I make boost::python increment the reference counter of Container when an element containing a pointer to the Container is returned? -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Python-Reference-Counting-tp4662504.html Sent from the Python - c++-sig mailing list archive at Nabble.com. From ndbecker2 at gmail.com Tue May 20 13:57:54 2014 From: ndbecker2 at gmail.com (Neal Becker) Date: Tue, 20 May 2014 07:57:54 -0400 Subject: [C++-sig] Boost::Python Reference Counting References: <1400480859720-4662504.post@n4.nabble.com> Message-ID: laan wrote: > Hi, > > I'm having issues with Boost::Python objects that contain a reference to a > c++ object: > > --- C++ code ---- > > #include > > struct Container; > > struct Element > { > Element(const Container * c) : _container(c) { } > std::string name() const; > const Container * _container; > }; > > struct Container > { > Container(const std::string & s) : _string(s) { } > > Element getElement() > { > return Element(this); > } > std::string name() const > { > return this->_string; > } > std::string _string; > }; > > std::string Element::name() const > { > return _container->name(); > } > > using namespace boost::python; > > BOOST_PYTHON_MODULE(libkatya) > { > class_("Element", no_init) > .def("name", &Element::name) > ; > > class_("Container", init()) > .def("getElement", &Container::getElement) > ; > } > --- Python Code ---------------------- > container = test.Container("X") > elem = container.getElement() > del(container) > print(elem.name()) > > When calling elem.name(), it will reference the "container" object, which > has been deleted, and I'm getting a segfault. > > How can I make boost::python increment the reference counter of Container > when an element containing a pointer to the Container is returned? > > > > > > -- > View this message in context: > http://boost.2283326.n4.nabble.com/Boost-Python-Reference-Counting-tp4662504.html > Sent from the Python - c++-sig mailing list archive at Nabble.com. Usually if I need a c++ obj to hold onto a reference, I use boost::shared_ptr. boost::python knows how to interoperate between boost::shared_ptr and python ref counting. From jaedyn.cppsig at jaedyn.co Tue May 20 16:48:00 2014 From: jaedyn.cppsig at jaedyn.co (Jaedyn Draper) Date: Tue, 20 May 2014 09:48:00 -0500 Subject: [C++-sig] Boost::Python Reference Counting In-Reply-To: <1400480859720-4662504.post@n4.nabble.com> References: <1400480859720-4662504.post@n4.nabble.com> Message-ID: <537B6B20.9020001@jaedyn.co> std::shared_ptr and similar types can also be used like so: boost::python::class_> But I don't think that would solve the problem because it's a raw pointer to _container being held here. I don't think there's a way to do what you want with raw pointers. The only way I would know of to do that is to make const Container * _container; into const std::shared_ptr _container; or const boost::shared_ptr _container; or you can probably make this work with your own custom type, too, by replacing the second argument to class_ with your C++ ref-counted shared pointer class. Then anything exposed to python that deals with the Container class (like the constructor for Element) should return it or accept it as a shared_ptr instead of a pointer. With raw pointers the ownership of the memory sits in just one place, and you're deleting that place. This is an issue that goes deeper than python, down to the C++ architecture - if you did the same thing in C++ using raw pointers like that, you'd have the same behavior. In order to get this sort of ref counting behavior in python, you have to have it in C++. In general, unless you're working with very performance-sensitive code like a rendering pipeline (which isn't something you should use python for, as it has relatively poor performance characteristics compared to some other scripting languages - it's great for a lot of things, but performance isn't one of them), I tend to advocate the use of shared_ptr (or some similar memory management construct) over raw pointers for long-term storage anyway. It can save you from a lot of headaches and opens up a lot of possibilities when you combine it with weak_ptr. ... Of course, one other option that doesn't require shared pointers is to set it up something like this: struct Element { Element(const Container * c, PyObject * obj) : _container(c), containerPyObj(obj) { Py_INCREF(containerPyObj); } ~Element() { Py_DECREF(containerPyObj); } std::string name() const; const Container * _container; PyObject * containerPyObj; }; Element GetElementProxy(boost::python::object self) { Container * container = boost::python::extract(self); return Element(container, self.ptr()); } BOOST_PYTHON_MODULE(libkatya) { class_("Element", no_init) .def("name", &Element::name) ; class_("Container", init()) .def("getElement", &GetElementProxy) // NOTE the change here, it's calling the free function, not the member ; } Caveat, I haven't tested this code, so I don't know if it compiles, but I've done similar things before. If you're dead set on not using shared pointers for whatever reason, this should do what you want. On 5/19/2014 1:27 AM, laan wrote: > Hi, > > I'm having issues with Boost::Python objects that contain a reference to a > c++ object: > > --- C++ code ---- > > #include > > struct Container; > > struct Element > { > Element(const Container * c) : _container(c) { } > std::string name() const; > const Container * _container; > }; > > struct Container > { > Container(const std::string & s) : _string(s) { } > > Element getElement() > { > return Element(this); > } > std::string name() const > { > return this->_string; > } > std::string _string; > }; > > std::string Element::name() const > { > return _container->name(); > } > > using namespace boost::python; > > BOOST_PYTHON_MODULE(libkatya) > { > class_("Element", no_init) > .def("name", &Element::name) > ; > > class_("Container", init()) > .def("getElement", &Container::getElement) > ; > } > --- Python Code ---------------------- > container = test.Container("X") > elem = container.getElement() > del(container) > print(elem.name()) > > When calling elem.name(), it will reference the "container" object, which > has been deleted, and I'm getting a segfault. > > How can I make boost::python increment the reference counter of Container > when an element containing a pointer to the Container is returned? > > > > > > -- > View this message in context: http://boost.2283326.n4.nabble.com/Boost-Python-Reference-Counting-tp4662504.html > Sent from the Python - c++-sig mailing list archive at Nabble.com. > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > https://mail.python.org/mailman/listinfo/cplusplus-sig From talljimbo at gmail.com Tue May 20 17:16:43 2014 From: talljimbo at gmail.com (Jim Bosch) Date: Tue, 20 May 2014 11:16:43 -0400 Subject: [C++-sig] Boost::Python Reference Counting In-Reply-To: <1400480859720-4662504.post@n4.nabble.com> References: <1400480859720-4662504.post@n4.nabble.com> Message-ID: I think what you want is the with_custodian_and_ward CallPolicy: http://www.boost.org/doc/libs/1_55_0/libs/python/doc/v2/with_custodian_and_ward.html I can never remember the details of how to invoke it, so I don't have an example ready to go that solves your specific problem, but hopefully the docs above will point you in the right direction. As Neal said, if you can afford to change your C++ code, it's probably cleaner and easier to use boost::shared_ptr, but you should still be able to get what you want with CallPolicies even if you can't. Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From jaedyn.cppsig at jaedyn.co Tue May 20 17:36:25 2014 From: jaedyn.cppsig at jaedyn.co (Jaedyn Draper) Date: Tue, 20 May 2014 10:36:25 -0500 Subject: [C++-sig] Boost::Python Reference Counting In-Reply-To: <537B6B20.9020001@jaedyn.co> References: <1400480859720-4662504.post@n4.nabble.com> <537B6B20.9020001@jaedyn.co> Message-ID: <537B7679.80907@jaedyn.co> Upon a bit of further reflection on this topic, I realized my suggestion is doing something silly. struct Element { Element(const Container * c, boost::python::object obj) : _container(c), containerPyObj(obj) { } std::string name() const; const Container * _container; boost::python::object containerPyObj; }; Element GetElementProxy(boost::python::object self) { Container * container = boost::python::extract(self); return Element(container, self); } boost::python::object will handle the incref and decref for you if it's a member of that class. No need to do it manually. On 5/20/2014 9:48 AM, Jaedyn Draper wrote: > std::shared_ptr and similar types can also be used like so: > > boost::python::class_> > > But I don't think that would solve the problem because it's a raw > pointer to _container being held here. I don't think there's a way to > do what you want with raw pointers. The only way I would know of to do > that is to make > > const Container * _container; > > into > > const std::shared_ptr _container; > > or > > const boost::shared_ptr _container; > > or you can probably make this work with your own custom type, too, by > replacing the second argument to class_ with your C++ ref-counted > shared pointer class. Then anything exposed to python that deals with > the Container class (like the constructor for Element) should return > it or accept it as a shared_ptr instead of a pointer. > > With raw pointers the ownership of the memory sits in just one place, > and you're deleting that place. This is an issue that goes deeper than > python, down to the C++ architecture - if you did the same thing in > C++ using raw pointers like that, you'd have the same behavior. In > order to get this sort of ref counting behavior in python, you have to > have it in C++. > > In general, unless you're working with very performance-sensitive code > like a rendering pipeline (which isn't something you should use python > for, as it has relatively poor performance characteristics compared to > some other scripting languages - it's great for a lot of things, but > performance isn't one of them), I tend to advocate the use of > shared_ptr (or some similar memory management construct) over raw > pointers for long-term storage anyway. It can save you from a lot of > headaches and opens up a lot of possibilities when you combine it with > weak_ptr. > > ... > > Of course, one other option that doesn't require shared pointers is to > set it up something like this: > > struct Element > { > Element(const Container * c, PyObject * obj) : _container(c), > containerPyObj(obj) > { > Py_INCREF(containerPyObj); > } > ~Element() > { > Py_DECREF(containerPyObj); > } > std::string name() const; > const Container * _container; > PyObject * containerPyObj; > }; > > Element GetElementProxy(boost::python::object self) > { > Container * container = boost::python::extract(self); > return Element(container, self.ptr()); > } > > BOOST_PYTHON_MODULE(libkatya) > { > class_("Element", no_init) > .def("name", &Element::name) > ; > > class_("Container", init()) > .def("getElement", &GetElementProxy) // NOTE the change here, > it's calling the free function, not the member > ; > } > > > Caveat, I haven't tested this code, so I don't know if it compiles, > but I've done similar things before. If you're dead set on not using > shared pointers for whatever reason, this should do what you want. > > > On 5/19/2014 1:27 AM, laan wrote: >> Hi, >> >> I'm having issues with Boost::Python objects that contain a reference >> to a >> c++ object: >> >> --- C++ code ---- >> >> #include >> >> struct Container; >> >> struct Element >> { >> Element(const Container * c) : _container(c) { } >> std::string name() const; >> const Container * _container; >> }; >> >> struct Container >> { >> Container(const std::string & s) : _string(s) { } >> Element getElement() >> { >> return Element(this); >> } >> std::string name() const >> { >> return this->_string; >> } >> std::string _string; >> }; >> >> std::string Element::name() const >> { >> return _container->name(); >> } >> >> using namespace boost::python; >> >> BOOST_PYTHON_MODULE(libkatya) >> { >> class_("Element", no_init) >> .def("name", &Element::name) >> ; >> >> class_("Container", init()) >> .def("getElement", &Container::getElement) >> ; >> } >> --- Python Code ---------------------- >> container = test.Container("X") >> elem = container.getElement() >> del(container) >> print(elem.name()) >> >> When calling elem.name(), it will reference the "container" object, >> which >> has been deleted, and I'm getting a segfault. >> >> How can I make boost::python increment the reference counter of >> Container >> when an element containing a pointer to the Container is returned? >> >> >> >> >> >> -- >> View this message in context: >> http://boost.2283326.n4.nabble.com/Boost-Python-Reference-Counting-tp4662504.html >> Sent from the Python - c++-sig mailing list archive at Nabble.com. >> _______________________________________________ >> Cplusplus-sig mailing list >> Cplusplus-sig at python.org >> https://mail.python.org/mailman/listinfo/cplusplus-sig > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > https://mail.python.org/mailman/listinfo/cplusplus-sig From wmamrak at gmail.com Tue May 20 21:26:37 2014 From: wmamrak at gmail.com (Wojciech Mamrak) Date: Tue, 20 May 2014 21:26:37 +0200 Subject: [C++-sig] Boost::Python Reference Counting In-Reply-To: <537B7679.80907@jaedyn.co> References: <1400480859720-4662504.post@n4.nabble.com> <537B6B20.9020001@jaedyn.co> <537B7679.80907@jaedyn.co> Message-ID: In your code, after the call del(container), Element::_container is a dangling pointer. Using .def("getElement", &Container::getElement, return_internal_reference<>()) should prevent the deletion of container for as long as element variable will be alive, me understands (ties lifetime of _conteiner with Element's this). This is of course inconsistent with behaviour of your C++ code. One may ask a question why would anyone make her code inconsistent. The tutorial gives one argument: "Python users should not be able to crash the system just by using our C++ interface". The other is, if that code had been written in Python entirely, it would run perfectly fine. And call policies help us keep our C++ code intact in such cases (no need for smart pointers). I would like to hear some expert on that, though. 2014-05-20 17:36 GMT+02:00 Jaedyn Draper : > Upon a bit of further reflection on this topic, I realized my suggestion is > doing something silly. > struct Element > { > Element(const Container * c, boost::python::object obj) : _container(c), > containerPyObj(obj) { } > > std::string name() const; > const Container * _container; > boost::python::object containerPyObj; > > }; > > Element GetElementProxy(boost::python::object self) > { > Container * container = boost::python::extract(self); > return Element(container, self); > } > > boost::python::object will handle the incref and decref for you if it's a > member of that class. No need to do it manually. > > > On 5/20/2014 9:48 AM, Jaedyn Draper wrote: >> >> std::shared_ptr and similar types can also be used like so: >> >> boost::python::class_> >> >> But I don't think that would solve the problem because it's a raw pointer >> to _container being held here. I don't think there's a way to do what you >> want with raw pointers. The only way I would know of to do that is to make >> >> const Container * _container; >> >> into >> >> const std::shared_ptr _container; >> >> or >> >> const boost::shared_ptr _container; >> >> or you can probably make this work with your own custom type, too, by >> replacing the second argument to class_ with your C++ ref-counted shared >> pointer class. Then anything exposed to python that deals with the Container >> class (like the constructor for Element) should return it or accept it as a >> shared_ptr instead of a pointer. >> >> With raw pointers the ownership of the memory sits in just one place, and >> you're deleting that place. This is an issue that goes deeper than python, >> down to the C++ architecture - if you did the same thing in C++ using raw >> pointers like that, you'd have the same behavior. In order to get this sort >> of ref counting behavior in python, you have to have it in C++. >> >> In general, unless you're working with very performance-sensitive code >> like a rendering pipeline (which isn't something you should use python for, >> as it has relatively poor performance characteristics compared to some other >> scripting languages - it's great for a lot of things, but performance isn't >> one of them), I tend to advocate the use of shared_ptr (or some similar >> memory management construct) over raw pointers for long-term storage anyway. >> It can save you from a lot of headaches and opens up a lot of possibilities >> when you combine it with weak_ptr. >> >> ... >> >> Of course, one other option that doesn't require shared pointers is to set >> it up something like this: >> >> struct Element >> { >> Element(const Container * c, PyObject * obj) : _container(c), >> containerPyObj(obj) >> { >> Py_INCREF(containerPyObj); >> } >> ~Element() >> { >> Py_DECREF(containerPyObj); >> } >> std::string name() const; >> const Container * _container; >> PyObject * containerPyObj; >> }; >> >> Element GetElementProxy(boost::python::object self) >> { >> Container * container = boost::python::extract(self); >> return Element(container, self.ptr()); >> } >> >> BOOST_PYTHON_MODULE(libkatya) >> { >> class_("Element", no_init) >> .def("name", &Element::name) >> ; >> >> class_("Container", init()) >> .def("getElement", &GetElementProxy) // NOTE the change here, it's >> calling the free function, not the member >> ; >> } >> >> >> Caveat, I haven't tested this code, so I don't know if it compiles, but >> I've done similar things before. If you're dead set on not using shared >> pointers for whatever reason, this should do what you want. >> >> >> On 5/19/2014 1:27 AM, laan wrote: >>> >>> Hi, >>> >>> I'm having issues with Boost::Python objects that contain a reference to >>> a >>> c++ object: >>> >>> --- C++ code ---- >>> >>> #include >>> >>> struct Container; >>> >>> struct Element >>> { >>> Element(const Container * c) : _container(c) { } >>> std::string name() const; >>> const Container * _container; >>> }; >>> >>> struct Container >>> { >>> Container(const std::string & s) : _string(s) { } >>> Element getElement() >>> { >>> return Element(this); >>> } >>> std::string name() const >>> { >>> return this->_string; >>> } >>> std::string _string; >>> }; >>> >>> std::string Element::name() const >>> { >>> return _container->name(); >>> } >>> >>> using namespace boost::python; >>> >>> BOOST_PYTHON_MODULE(libkatya) >>> { >>> class_("Element", no_init) >>> .def("name", &Element::name) >>> ; >>> >>> class_("Container", init()) >>> .def("getElement", &Container::getElement) >>> ; >>> } >>> --- Python Code ---------------------- >>> container = test.Container("X") >>> elem = container.getElement() >>> del(container) >>> print(elem.name()) >>> >>> When calling elem.name(), it will reference the "container" object, which >>> has been deleted, and I'm getting a segfault. >>> >>> How can I make boost::python increment the reference counter of Container >>> when an element containing a pointer to the Container is returned? >>> >>> >>> >>> >>> >>> -- >>> View this message in context: >>> http://boost.2283326.n4.nabble.com/Boost-Python-Reference-Counting-tp4662504.html >>> Sent from the Python - c++-sig mailing list archive at Nabble.com. >>> _______________________________________________ >>> Cplusplus-sig mailing list >>> Cplusplus-sig at python.org >>> https://mail.python.org/mailman/listinfo/cplusplus-sig >> >> >> _______________________________________________ >> Cplusplus-sig mailing list >> Cplusplus-sig at python.org >> https://mail.python.org/mailman/listinfo/cplusplus-sig > > > _______________________________________________ > Cplusplus-sig mailing list > Cplusplus-sig at python.org > https://mail.python.org/mailman/listinfo/cplusplus-sig From talljimbo at gmail.com Tue May 20 21:34:39 2014 From: talljimbo at gmail.com (Jim Bosch) Date: Tue, 20 May 2014 15:34:39 -0400 Subject: [C++-sig] Boost::Python Reference Counting In-Reply-To: References: <1400480859720-4662504.post@n4.nabble.com> <537B6B20.9020001@jaedyn.co> <537B7679.80907@jaedyn.co> Message-ID: On Tue, May 20, 2014 at 3:26 PM, Wojciech Mamrak wrote: > In your code, after the call del(container), Element::_container is a > dangling pointer. Using > > .def("getElement", &Container::getElement, return_internal_reference<>()) > > should prevent the deletion of container for as long as element > variable will be alive, me understands (ties lifetime of _conteiner > with Element's this). This is of course inconsistent with behaviour of > your C++ code. One may ask a question why would anyone make her code > inconsistent. The tutorial gives one argument: > "Python users should not be able to crash the system just by using our > C++ interface". > The other is, if that code had been written in Python entirely, it > would run perfectly fine. And call policies help us keep our C++ code > intact in such cases (no need for smart pointers). > > This solution supercedes (or, rather, extends) mine: return_internal_reference uses with_custodian_and_ward under the hood, but it's a much easier way to call it. I didn't originally recognize that one could use it here. I think the OP was asking for a solution that does make the Python code inconsistent with the C++ code in exactly this way (i.e. by making the Python code safer), so I think think we're all in good agreement on that. The only area where I think there might be disagreement is whether one should rewrite the C++ code to use shared_ptr instead, and I don't think it's worthwhile to try to have a general rule on that one way or the other. Jim -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndbecker2 at gmail.com Thu May 29 16:27:38 2014 From: ndbecker2 at gmail.com (Neal Becker) Date: Thu, 29 May 2014 10:27:38 -0400 Subject: [C++-sig] np.int64 does not match unsigned long on py3? Message-ID: Using boost::python, it seems a python arg of type np.int64 will match a call requiring c++ type size_t on python2, but on python3 I get: burst.pilot_xsyms = gold_code_generator (-1, -1) (burst.n_pilot_syms) Boost.Python.ArgumentError: Python argument types in gold_code_generator.__call__(gold_code_generator, numpy.int64) did not match C++ signature: __call__(gold_code_generator {lvalue}, unsigned long) __call__(gold_code_generator {lvalue}) Any ideas?