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
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!