Page 1 of 1

callbacks - setup in Python, call in C

Posted: Thu Feb 08, 2018 9:08 pm
by jickster
I'm implementing an IO API.

I want to implement an asynchronous interface: a function in .py will get called when my IO driver receives a message.

Is there an example how to accomplish this?

The .py code would look like this:

Code: Select all

def myfunc():
    ...

myIO = IO.callback(myfunc)

Re: callbacks - setup in Python, call in C

Posted: Fri Feb 09, 2018 1:11 am
by dhylands
I put together an example a while ago which is referenced in this thread:
viewtopic.php?f=16&t=2861#p19206

I just updated it to work with the latest tree, and you can find the updated sample here:
https://github.com/dhylands/micropython ... 3f397ec43e

You can run this on the pyboard like this:

Code: Select all

>>> import c_sample
>>> def foo(arg):
...     print('foo called, arg=', arg)
... 
>>> c_sample.set_callback(foo)
>>> c_sample.call_callback()
foo called, arg= b'some_string'

Re: callbacks - setup in Python, call in C

Posted: Fri Feb 09, 2018 8:00 pm
by jickster
dhylands wrote:
Fri Feb 09, 2018 1:11 am
I put together an example a while ago which is referenced in this thread:
viewtopic.php?f=16&t=2861#p19206

I just updated it to work with the latest tree, and you can find the updated sample here:
https://github.com/dhylands/micropython ... 3f397ec43e

You can run this on the pyboard like this:

Code: Select all

>>> import c_sample
>>> def foo(arg):
...     print('foo called, arg=', arg)
... 
>>> c_sample.set_callback(foo)
>>> c_sample.call_callback()
foo called, arg= b'some_string'
Actually, I meant
how to call the callback from C
.

Re: callbacks - setup in Python, call in C

Posted: Fri Feb 09, 2018 8:57 pm
by dhylands
When the python code executes call_callback, it winds up calling this C code:
https://github.com/dhylands/micropython ... .c#L15-L27

This line in particular is where the C code calls the python function:
https://github.com/dhylands/micropython ... mple.c#L24

The set_callback function saves away the reference to the callback in: MP_STATE_PORT(c_sample_callback_obj) and the call_callback function retrieves it and uses it to call the function.

The reason that the saved pointer needs to go into MP_STATE_PORT is so that the garbage collector won't collect the callback function.

Re: callbacks - setup in Python, call in C

Posted: Fri Jul 30, 2021 7:23 pm
by madmax48
I know this is an old post but it's still very relevant...

I ran into a use-case where I also needed to setup a callback. Ran into a lot of weird inconsistent behaviour before I found this thread and made sure the mp_obj_t variable holding the reference to the callback was in the structure access by the MP_STATE_PORT macro.

Thanks a lot @dhylands for this info!