[C++-sig] Passing opaque data to C++ callback from Python

Stefan Seefeld stefan at seefeld.name
Fri Dec 19 05:10:01 CET 2014


On 18/12/14 10:43 PM, Peter LaDow wrote:
> Thanks for the reply!
>
> On Thu, Dec 18, 2014 at 9:16 AM, Stefan Seefeld <stefan at seefeld.name> wrote:
>> You defined 'do_something' as a callback, and registered it so it could
>> be called from C++, yes ? Then, in your implementation of
> Yes.  At some pointer in the future, the Python function
> 'do_something' will be called from C++.
>
>> 'register_callback', 'o' is actually a reference to your callback
> Right.  Using 'o' I can maintain a reference to the Python callback.
>
>> function. Do you want to access the persistent state while registering
>> the callback, or from within the callback ? Or am I misreading the code
>> above ?
> I need access to the persistent state while registering the callback.
> In fact, that persistent state is the context in which the callback
> from C++ into Python will be done.

That sounds a bit confusing to me. :-)
Typically, if you associate state with a callback (a "closure"), you
think of it as an object whose member function is the callback. But
here, the callback function lives in Python, while you want to associate
state from the C++ runtime...


>   That is, I need to register 'o'
> (which references the Python 'do_something') in that persistent state.
>
> I think I figured out a mechanism.  I was trying to make
> 'register_callback' a module function.  I get that I could do
> something like:
>
> class persistent_state_t
> {
>   public:
>     ...
>
>     void register_callback(boost::python::object& cb);
> };
>
> Then I could register persistent_state_t::register_callback, then
> create an instance of persistent_state_t, and store that object.  Then
> calls from Python to C++ would always be within the context of the
> particular instance of persistent_state_t.  The issue was figuring out
> where to store an instance of persistent_state_t, make it visible to
> the user, and to prevent issues such as copies, deletion, etc.  I
> wanted it to look like a module.
>
> The solution that I'm working with now is to store the instance of
> persistent_state_t in sys.modules with the name of the module.  It is
> a class instance, rather than a module.  But calls are within the
> context of the state.  And since sys.modules (retrieved using
> PyImport_GetModuleDict) is a per-interpreter variable, I'm not
> polluting other interpreters running.

OK, sounds like you have found what you need; great ! :-)

        Stefan

-- 

      ...ich hab' noch einen Koffer in Berlin...



More information about the Cplusplus-sig mailing list