Re: [C++-sig] Passing Python classes derived from C++ back into C++

2009-07-08 Thread Paul Scruby
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-07-08 Thread Gustavo Carneiro
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

2009-07-08 Thread Paul Scruby
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

2009-07-08 Thread Renato Araujo
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()

2009-07-08 Thread Xavier Bénech


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