Re: [C++-sig] Passing Python classes derived from C++ back into C++
Hi Rento, Got it working now. I did not realize that the wrapper<> automatically handled downcast conversion as well. Thanks, Paul "Renato Araujo" wrote in message news:[email protected]... Hi Paul, You can extend from boost::python::wrapper and use this function to get PyObject from c++ object. namespace detail { .. namespace wrapper_base_ // ADL disabler { inline PyObject* get_owner(wrapper_base const volatile& w); BR On Tue, Jul 7, 2009 at 7:54 AM, Paul Scruby wrote: > Hiya, > > I'm trying to pass a C++ class that I've extended in Python to a C++ > function. I found an example of how to do this in David Abrahams article > on > Building Hybrid Systems with Boost Python. > http://www.boostpro.com/writing/bpl.html#virtual-functions > > However, I've not managed to get this example to compile: > > #include > #include > using namespace boost::python; > > class Base > { > public: > virtual int f(std::string x) { return 42; } > virtual ~Base() {} > }; > > int calls_f(Base & b, std::string x) { return b.f(x); } > > struct BaseWrap : Base > { > BaseWrap(PyObject * self_) : self(self_) {} > PyObject * self; > int f_default(std::string x) { return this->Base::f(x); } > int f(std::string x) { return call_method(self, "f", x); } > }; > > BOOST_PYTHON_MODULE(mytest) > { > def("calls_f", calls_f); > class_("Base") > .def("f", &Base::f, &BaseWrap::f_default); > } > > _ > > from mytest import * > > class Derived(Base): > def f(self, s): > return len(s) > > calls_f(Base(), 'foo') > calls_f(Derived(), 'forty-two') > > > With Boost 1.38 and Visual Studio 8 compiler I get the error: > > boost_1_38\boost\python\object\make_instance.hpp(68) : see reference to > function template instantiation > 'boost::python::objects::value_holder_back_reference::value_holder_back_reference>(PyObject > *,A0)' being compiled > with > [ > Value=Base, > Held=BaseWrap, > T=const Base, > A0=boost::reference_wrapper > ] > > With Boost 1.63 and Sun C++ 5.9 compiler I get the error: > > boost-1_36/boost/python/object/class_metadata.hpp", line 232: > Error: Overloading ambiguity between "static > boost::python::objects::class_metadata boost::python::detail::not_specified, > boost::python::detail::not_specified>::maybe_register_pointer_to_python(void*, > void*, void*)" > and "static boost::python::objects::class_metadata boost::python::detail::not_specified, > boost::python::detail::not_specified>::maybe_register_pointer_to_python(void*, > void*, mpl_::bool_<1>*)". > > I also tried extending the boost::python::wrapper using get_override() > instead of call_method(), but as it can not be constructed with a > PyObject * so the C++ base class can't be extracted from a Python > derivation. > > Has anyone managed to get this working? Any help will be gratefully > received. > > Cheers, > > Paul > > > > ___ > Cplusplus-sig mailing list > [email protected] > http://mail.python.org/mailman/listinfo/cplusplus-sig > -- Renato Araujo Oliveira Filho ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] pybindgen: allow_subclassing option causing reference parameters to be copied?
2009/7/8 J. Michael Owen > Hello Gustavo, > > I have some further evolved changes for the sequence methods that you may > want to use over my previous version. This is more general, and involves > less code as I realized I could register the sequence methods to just call > the wrapped methods pybindgen is already providing. This also also > corrects a bug I had with exposing containers of pointers. Since this code > is more general and smaller, it seems like an improvement over what I gave > you before. > > I'm also including some minor extensions to your name mangling code in > utils.py here, which I found necessary 'cause I'm using templated functions > with things like "add_function_as_method". > > These changes are current with your latest Bazaar branch, and I've verified > that all tests are passing. There are three altered files I'm including > here: cppclass.py, pytypeobject.py, and utils.py. > Pushed these changes, with memory leaks fixed. Thanks. > > Mike. > > > > > > > > On Jul 7, 2009, at 8:27 AM, Gustavo Carneiro wrote: > >> >> I just pushed your merged contribution with some fixes and unit tests to >> bazaar trunk. >> > > -- Gustavo J. A. M. Carneiro INESC Porto, Telecommunications and Multimedia Unit "The universe is always one step beyond logic." -- Frank Herbert ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] boost::python and threads
Hi Renato,
Okay, I have installed Python 2.4.2 with gcc 4.1.2 on Linux and it's
crashing in the same place as on Solaris.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x41074940 (LWP 12004)]
0x00307740c850 in sem_post () from /lib64/libpthread.so.0
(gdb) where
#0 0x00307740c850 in sem_post () from /lib64/libpthread.so.0
#1 0x00308b2b78e9 in PyThread_release_lock ()
from /usr/lib64/libpython2.4.so.1.0
#2 0x2b46531d9f82 in Ticker::operator() (this=0xbd0f478) at
ticker.cc:28
#3 0x2b46531d9fb0 in boost::detail::thread_data::run (
this=0xbd0f370)
at /opt/atm/include/boost-1_39/boost/thread/detail/thread.hpp:56
#4 0x2b46533ee14b in thread_proxy ()
from /opt/atm/lib64/libboost_thread-gcc41-mt-1_39.so.1.39.0
#5 0x003077406367 in start_thread () from /lib64/libpthread.so.0
#6 0x0030768d2f7d in clone () from /lib64/libc.so.6
With the global interpret lock added my code now looks like this...
#include
#include
#include
using namespace boost::python;
class Ticker
:public wrapper
{
private:
bool run_;
volatile bool * running_;
boost::thread * thread_;
boost::xtime xt_;
PyGILState_STATE state_;
public:
Ticker() :running_(&run_) { *running_ = false; }
void operator()()
{
while (*running_)
{
boost::xtime_get(&xt_, boost::TIME_UTC);
++xt_.sec;
boost::thread::sleep(xt_);
state_ = PyGILState_Ensure();
onTick();
PyGILState_Release(state_);
}
}
void run()
{
if (*running_ == false)
{
*running_ = true;
thread_ = new boost::thread(*this);
}
}
void stop()
{
if (*running_ == true)
{
*running_ = false;
thread_->join();
delete thread_;
}
}
virtual void onTick() { get_override("onTick")(); }
void default_onTick() {}
};
BOOST_PYTHON_MODULE(tick)
{
class_ ("Ticker")
.def("run", &Ticker::run)
.def("stop", &Ticker::stop)
.def("onTick", &Ticker::default_onTick);
}
Thanks again,
Paul
"Renato Araujo" wrote in message
news:[email protected]...
I'm using gcc/linux and python >= 2.4 and works fine for me.
On Mon, Jul 6, 2009 at 7:39 AM, Paul Scruby wrote:
> Hello again,
>
> Sorry, I spoke too soon. The good news is that wrapping my virtual method
> calls into Python between PyGILState_Ensure() and PyGILState_Release()
> fixed
> the crash under Python2.6.2 on Windows, but not when I tested it again
> under
> Python 2.4.4 on Solaris. Under Python 2.4.4 on SolarisSolaris it now calls
> and exits the virtual method in Python sucessfully, but then crashes when
> C++ trys to release the global interpretor lock.
>
> The call-stack with the Sun C++ 5.9 compiler under Solaris is
> t...@2 (l...@2) signal SEGV (no mapping at the fault address) in sem_invalid
> at 0xfec453ed
> 0xfec453ed: sem_invalid+0x0013: movzwl 0x0006(%eax),%eax
> Current function is Ticker::operator()
> 28 PyGILState_Release(state_);
> (dbx) where
> current thread: t...@2
> [1] sem_invalid(0x0), at 0xfec453ed
> [2] _sem_post(0x0), at 0xfec454c4
> [3] PyThread_release_lock(0x0, 0xfe77ef2c, 0xfef43eba, 0x80c55c0,
> 0xfe77ef38, 0xfef441b5), at 0xfef492dc
> [4] PyEval_ReleaseLock(0x80c55c0, 0xfe77ef38, 0xfef441b5, 0xfeb12aec,
> 0xfe77ef70, 0xfeafb2e3), at 0xfef27abe
> [5] PyThreadState_DeleteCurrent(0xfeb12aec, 0xfe77ef70, 0xfeafb2e3, 0x1,
> 0x0, 0x80a3140), at 0xfef43eba
> [6] PyGILState_Release(0x1, 0x0), at 0xfef441b5
> =>[7] Ticker::operator()(this = 0x810a304), line 28 in "ticker.cc"
> [8] boost::detail::thread_data::run(this = 0x810a288), line 56
> in "thread.hpp"
> [9] thread_proxy(0x810a288), at 0xfea78ce4
> [10] _thr_setup(0xfe670200), at 0xfee159b9
> [11] _lwp_start(0xfe77ef08, 0xfec454c4, 0x0, 0xfe77ef54, 0x80c55c0,
> 0xfe77ef14), at 0xfee15ca0
>
> Do you think it's worth repeating this test using gcc/linux, or do you
> think
> that this is just a limitation of using Python with threads?
>
> Thanks again,
>
> Paul
>
>
> t...@2 (l...@2) signal SEGV (no mapping at the fault address) in sem_invalid
> at
> 0xfec453ed
> 0xfec453ed: sem_invalid+0x0013: movzwl 0x0006(%eax),%eax
> Current function is Ticker::operator()
> 28 PyGILState_Release(state_);
> (dbx) where
> current thread: t...@2
> [1] sem_invalid(0x0), at 0xfec453ed
> [2] _sem_post(0x0), at 0xfec454c4
> [3] PyThread_release_lock(0x0, 0xfe77ef2c, 0xfef43eba, 0x80c55c0,
> 0xfe77ef38, 0xfef441b5), at 0xfef492dc
> [4] PyEval_ReleaseLock(0x80c55c0, 0xfe77ef38, 0xfef441b5, 0xfeb12aec,
> 0xfe77ef70, 0xfeafb2e3), at 0xfef27abe
> [5] PyThreadState_DeleteCurrent(0xfeb12aec, 0xfe77ef70, 0xfeafb2e3, 0x1,
> 0x0, 0x80a3140), at 0xfef43eba
> [6]
Re: [C++-sig] boost::python and threads
Ok I made 2 modifications and I got this working here.
Try this.
51,54c50
< virtual void onTick() {
< if (object o = get_override("onTick"))
< o();
< }
---
> virtual void onTick() { get_override("onTick")(); }
60d55
< PyEval_InitThreads();
65a61
>
BR
On Wed, Jul 8, 2009 at 12:48 PM, Paul Scruby wrote:
> Hi Renato,
>
> Okay, I have installed Python 2.4.2 with gcc 4.1.2 on Linux and it's
> crashing in the same place as on Solaris.
>
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 0x41074940 (LWP 12004)]
> 0x00307740c850 in sem_post () from /lib64/libpthread.so.0
> (gdb) where
> #0 0x00307740c850 in sem_post () from /lib64/libpthread.so.0
> #1 0x00308b2b78e9 in PyThread_release_lock ()
> from /usr/lib64/libpython2.4.so.1.0
> #2 0x2b46531d9f82 in Ticker::operator() (this=0xbd0f478) at
> ticker.cc:28
> #3 0x2b46531d9fb0 in boost::detail::thread_data::run (
> this=0xbd0f370)
> at /opt/atm/include/boost-1_39/boost/thread/detail/thread.hpp:56
> #4 0x2b46533ee14b in thread_proxy ()
> from /opt/atm/lib64/libboost_thread-gcc41-mt-1_39.so.1.39.0
> #5 0x003077406367 in start_thread () from /lib64/libpthread.so.0
> #6 0x0030768d2f7d in clone () from /lib64/libc.so.6
>
> With the global interpret lock added my code now looks like this...
>
> #include
> #include
> #include
> using namespace boost::python;
>
> class Ticker
> : public wrapper
> {
> private:
> bool run_;
> volatile bool * running_;
> boost::thread * thread_;
> boost::xtime xt_;
> PyGILState_STATE state_;
> public:
> Ticker() :running_(&run_) { *running_ = false; }
>
> void operator()()
> {
> while (*running_)
> {
> boost::xtime_get(&xt_, boost::TIME_UTC);
> ++xt_.sec;
> boost::thread::sleep(xt_);
> state_ = PyGILState_Ensure();
> onTick();
> PyGILState_Release(state_);
> }
> }
>
> void run()
> {
> if (*running_ == false)
> {
> *running_ = true;
> thread_ = new boost::thread(*this);
> }
> }
>
> void stop()
> {
> if (*running_ == true)
> {
> *running_ = false;
> thread_->join();
> delete thread_;
> }
> }
>
> virtual void onTick() { get_override("onTick")(); }
> void default_onTick() {}
> };
>
> BOOST_PYTHON_MODULE(tick)
> {
> class_ ("Ticker")
> .def("run", &Ticker::run)
> .def("stop", &Ticker::stop)
> .def("onTick", &Ticker::default_onTick);
> }
>
>
> Thanks again,
>
> Paul
>
>
> "Renato Araujo" wrote in message
> news:[email protected]...
> I'm using gcc/linux and python >= 2.4 and works fine for me.
>
>
>
> On Mon, Jul 6, 2009 at 7:39 AM, Paul Scruby wrote:
>> Hello again,
>>
>> Sorry, I spoke too soon. The good news is that wrapping my virtual method
>> calls into Python between PyGILState_Ensure() and PyGILState_Release()
>> fixed
>> the crash under Python2.6.2 on Windows, but not when I tested it again
>> under
>> Python 2.4.4 on Solaris. Under Python 2.4.4 on SolarisSolaris it now calls
>> and exits the virtual method in Python sucessfully, but then crashes when
>> C++ trys to release the global interpretor lock.
>>
>> The call-stack with the Sun C++ 5.9 compiler under Solaris is
>> t...@2 (l...@2) signal SEGV (no mapping at the fault address) in sem_invalid
>> at 0xfec453ed
>> 0xfec453ed: sem_invalid+0x0013: movzwl 0x0006(%eax),%eax
>> Current function is Ticker::operator()
>> 28 PyGILState_Release(state_);
>> (dbx) where
>> current thread: t...@2
>> [1] sem_invalid(0x0), at 0xfec453ed
>> [2] _sem_post(0x0), at 0xfec454c4
>> [3] PyThread_release_lock(0x0, 0xfe77ef2c, 0xfef43eba, 0x80c55c0,
>> 0xfe77ef38, 0xfef441b5), at 0xfef492dc
>> [4] PyEval_ReleaseLock(0x80c55c0, 0xfe77ef38, 0xfef441b5, 0xfeb12aec,
>> 0xfe77ef70, 0xfeafb2e3), at 0xfef27abe
>> [5] PyThreadState_DeleteCurrent(0xfeb12aec, 0xfe77ef70, 0xfeafb2e3, 0x1,
>> 0x0, 0x80a3140), at 0xfef43eba
>> [6] PyGILState_Release(0x1, 0x0), at 0xfef441b5
>> =>[7] Ticker::operator()(this = 0x810a304), line 28 in "ticker.cc"
>> [8] boost::detail::thread_data::run(this = 0x810a288), line 56
>> in "thread.hpp"
>> [9] thread_proxy(0x810a288), at 0xfea78ce4
>> [10] _thr_setup(0xfe670200), at 0xfee159b9
>> [11] _lwp_start(0xfe77ef08, 0xfec454c4, 0x0, 0xfe77ef54, 0x80c55c0,
>> 0xfe77ef14), at 0xfee15ca0
>>
>> Do you think it's worth repeating this test using gcc/linux, or do you
>> think
>> that this is just a limitation of using Python with threads?
>>
>> Thanks again,
>>
>> Paul
>>
>>
>> t...@2 (l...@2) signal SEGV (no mapping at the fault address) in sem_invalid
>> at
>> 0xfec453ed
>> 0xfec453ed: sem_invalid+0x0013: movzwl 0x0006(%eax),%eax
>> Current functi
[C++-sig] sys.exit() and PyRun_SimpleFileExFlags()
Hi, There is a behaviour I do not understand of PyRun_SimpleFileExFlags(), normally when it executes a python script containing a sys.exit(), it results by ending the calling application. I have got this behaviour with PyRun_SimpleFileExFlags() when I call it from the main thread of a GUI application (so I use PyRun_FileExFlags() in this case). But in another application when it is called (PyRun_SimpleFileExFlags())) from a working thread (not the main one) of a console application, everything just go fine without exiting the application nor the thread. It returns the exit code specified in sys.exit() just fine. Last things, I am working on Windows. And for the story, I started to make a small function to wrap some embedded python script call using the simple way with PyRun_SimpleFileExFlags() for the second application, but when I integrate it in the first one (with GUI) got some problems (:)) so I redo things with a cleaner PyRun_FileExFlags() call. So, my question is: why do I have different behaviour of PyRun_SimpleFileExFlags() in this two cases? Regards, Xavier Benech. ___ Cplusplus-sig mailing list [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
