Page 1 of 2
Calling a python function from C
Posted: Mon Feb 02, 2015 11:37 pm
by gshilling
I'm working on embedding micro python into another STM32 C application I have. I would like to be able to call functions in a python script file from the C application. Is there a call like PyObject_GetAttrString from CPython to get a pointer to a function that could then be feed into mp_call_function_n_kw?
Re: Calling a python function from C
Posted: Tue Feb 03, 2015 2:28 am
by dhylands
Here's an example of calling a python function from C:
https://github.com/micropython/micropyt ... pin.c#L118
If you search for mp_call_function in the stmhal directory you'll see several other examples.
Posted: Tue Feb 03, 2015 6:31 pm
by Damien
You might want to try mp_load_global to get a function (or other object) defined by a script.
Re: Calling a python function from C
Posted: Tue Feb 07, 2017 1:59 pm
by Tetraeder
I have a similar question to the thread topic:
I create for pyboard the frozen script -> own.py
I created in stmhal the folder "scripts" and define in Makefile the FROZEN_DIR. Copied the own.py script in folder scripts.
compile-> repl -> works, with
Code: Select all
>>> import own
>>> own.test()
hello test
>>>
but how can I call this function for example in main.c by "soft reset".
I tried:
Code: Select all
mp_call_function_0(MP_STATE_PORT(own_test))
but no output via repl.
Maybe I don't understand the function
Re: Calling a python function from C
Posted: Tue Feb 07, 2017 5:33 pm
by dhylands
The real trick is that you need to register the function from python first so that C can get a pointer to the function.
Otherwise you need to import the module, and then dig the function out of the module, which is doable, just a bunch more code.
You could also do the equivalent to the do_str function in unix/main.c:
https://github.com/micropython/micropyt ... #L287-L290
and call:
Disclaimer: I didn't actually test that.
boot.py and main.py both run as part of a soft-reset.
You need to ensure that you're calling it at the right place in main.c.
boot.py is run before USB is initialized. main.py is run after USB is initialized.
Re: Calling a python function from C
Posted: Fri Oct 20, 2017 3:04 pm
by jickster
The link is dead. Please post another one showing how to call Python from C.
Re: Calling a python function from C
Posted: Fri Oct 20, 2017 5:23 pm
by benalb
[/quote]
The link is dead. Please post another one showing how to call Python from C.
[/quote]
I think this is the right link, with the changes in 1.9 tree:
https://github.com/micropython/micropyt ... pin.c#L118
Re: Calling a python function from C
Posted: Thu Dec 14, 2017 4:45 pm
by jickster
dhylands wrote: ↑Tue Feb 07, 2017 5:33 pm
The real trick is that you need to register the function from python first so that C can get a pointer to the function.
Otherwise you need to import the module, and then dig the function out of the module, which is doable, just a bunch more code.
You could also do the equivalent to the do_str function in unix/main.c:
https://github.com/micropython/micropyt ... #L287-L290
and call:
Disclaimer: I didn't actually test that.
boot.py and main.py both run as part of a soft-reset.
You need to ensure that you're calling it at the right place in main.c.
boot.py is run before USB is initialized. main.py is run after USB is initialized.
How would I call gc_disable() from C?
Re: Calling a python function from C
Posted: Mon Dec 18, 2017 8:30 pm
by dhylands
An updated link to the pin.c file (which only moved by a single line) is:
https://github.com/micropython/micropyt ... pin.c#L119
Are you referring to this gc_disable function?
https://github.com/micropython/micropyt ... odgc.c#L45
which is what gets called when you do this in MicroPython:
I guess I would ask what is it that you're really trying to achieve?
To call that exact function from C, you need to locate the gc module, and then look up the disable method. The following:
Code: Select all
mp_obj_t gc_module_obj = mp_module_get(MP_QSTR_gc);
if (gc_module_obj) {
mp_obj_t gc_disable_fn = mp_load_attr(gc_module_obj, MP_QSTR_disable);
if (gc_disable_fn) {
mp_call_function_0(gc_disable_fn);
}
}
worked for me.
Re: Calling a python function from C
Posted: Sat Mar 03, 2018 11:59 pm
by jickster
dhylands wrote: ↑Mon Dec 18, 2017 8:30 pm
An updated link to the pin.c file (which only moved by a single line) is:
https://github.com/micropython/micropyt ... pin.c#L119
Are you referring to this gc_disable function?
https://github.com/micropython/micropyt ... odgc.c#L45
which is what gets called when you do this in MicroPython:
I guess I would ask what is it that you're really trying to achieve?
To call that exact function from C, you need to locate the gc module, and then look up the disable method. The following:
Code: Select all
mp_obj_t gc_module_obj = mp_module_get(MP_QSTR_gc);
if (gc_module_obj) {
mp_obj_t gc_disable_fn = mp_load_attr(gc_module_obj, MP_QSTR_disable);
if (gc_disable_fn) {
mp_call_function_0(gc_disable_fn);
}
}
worked for me.
I want to copy mp_obj_list_t. I know how to do it the long-way: use mp_map_lookup on mp_type_list.locals_dict and call MP_QSTR_copy. Is there a more direct way or do I have to make my own?
I followed through the execution path of mp_module_get(MP_QSTR_list) and it doesn't recurse into the builtins.
The list_copy function and struct are both static so I can't directly call them.
list_copy_obj = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_type_list.locals_dict), MP_OBJ_NEW_QSTR(MP_QSTR_copy));
list_copy_obj->base.type->call(list_copy_obj, 1, 0, & self_can_msg->list_small_int);