callbacks - setup in Python, call in C

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

callbacks - setup in Python, call in C

Post by jickster » Thu Feb 08, 2018 9:08 pm

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)

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: callbacks - setup in Python, call in C

Post by dhylands » 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'

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: callbacks - setup in Python, call in C

Post by jickster » Fri Feb 09, 2018 8:00 pm

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
.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: callbacks - setup in Python, call in C

Post by dhylands » Fri Feb 09, 2018 8:57 pm

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.

madmax48
Posts: 1
Joined: Fri Apr 16, 2021 10:55 am

Re: callbacks - setup in Python, call in C

Post by madmax48 » Fri Jul 30, 2021 7:23 pm

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!

Post Reply