I’m currently working on a project that I’ve written a C++ library for. I’m now wondering what the idiomatic way would be to call the library from micropython code. Do I have to create a interface myself or is there a much easier (more automated) way? As I need to interface with external hardware I’d like to not have to re-implement everything for micropython.
I’m using FemtoIDE to test and compile the programs.
Any help or hints into the right direction are very much appreciated.
You have to implement the wrapper functions in two places.
Make a methods in MicroPython C-implementation. That enables to call the functions from a python script.
Create a “python binding” wrapper with which you can forward the C-method to C++ method call to PokittoLib (or your own C++ API).
So the call goes like this:
python script => micropython internal C-implementation => C/C++ wrapper => PokittoLib
This is e.g. how I have made the Tilemap class of PokittoLib to be used from the python script.
So there is not very easy way
Of course, as everything is open source, you can make all kinds of dirty hacks and use existing PokittoLib functions (which have python bindings already) for the purpose they are not designed for, but that is evil
If your C++ library is very simple, it might still be easier to reimplement it in python. MicroPython has a
(somewhat limited) support for reading and writing to GPIO pins. I have used it with the “Joystick & rumble” PEX extension hat, where it worked well:
Btw. The online python editor is by far the easiest way to make python programs for Pokitto. It is also the preferred way.
Thanks for your reply. Really appreciate the help.
I need to use I²C (for a port expander that is ultimately controlling some LED) and things like 1-Wire for stuff like a DHT11 sensor. It would also be easier for me to only have my code in one place and not needing to re-implement everything a second time.
Currently I create a corresponding object in C++ then then allows to call some functions.
led.on(0); //argument is a uint8_t 0-7
Ideally I’d like to use this C++ code to:
import LED as led
I’m not sure if what I want is possible or practical but it would make my life a little easier.
The methods only really every need one argument or return one value, most of them are void with no arguments. So generally really simple.
I’ve placed all my C++ stuff into a folder in PokittoLib\Pokitto to have it in one place and then reference it in the project.json from Femto IDE.
I have found the PythonBindings.h in the PokittoLib but I don’t really see the big picture yet. What exact part of the implementation is in this file?
Should I extend those files or would it be possible to just reference my implementations via a include? Ideally I want to modify the original PokittoLib as little as necessary but have my code integrating as seamless as possible.
A simple example would be really nice if that would be possible.
The missing piece is here, in a different repository. I have forked the official MicroPython repository and made necessary changes for Pokitto.
In modUPyGame.c the actual python modules and classes are created in C. It calls those bindings API methods mentioned above.
What makes this a bit difficult is the conventions of Python C-implementation (e.g. how Python modules and classes are defined in C-structs), and that you have to set up a separate compiling environment (I use Cygwin) for MicroPython.
I think I’d have to do a lot of documentation reading to make sense of all of that.
I can understand a few things here and there.
(If the Pokitto can digest all of this then it ought to be able to manage modified Lua.)
This certainly implies that @ThxAndBye is going to have quite a bit of work ahead of them.
Is there some decent documentation of all the mp_ stuff somewhere?
Going slightly off-piste one moment…
If n_args is 2 or 3, does this not cause a buffer overrun bug?
It seems that mp_arg_check_num(n_args, n_kw, 1, 4, false); checks ((n_args >= 1) && (n_args <= 4)), in which case a value of 2 or 3 ought to result in an attempt to read args (and args), which I would assume is beyond the end of args.
I was actually thinking if it would make sense to make a very simple “user extension” API in Python for this kind of needs? I mean a simple way to send and receive data between Python and C++ programs. That would make possible to do “hybrid Python & C++ programs”.
I’d be fine to write a C++ program, even if C/C++ isn’t really in my comfort zone, but the library is supposed to be used for teaching purposes and Python is the preferred language. That’s the reason why I want to implement a Python interface.
A simple interface between Python and C/C++ code would be really cool. Currently the interfacing looks like lots of boilerplate and I don’t really understand every detail of it to create my own. (What goes where, the complete control flow trough the individual files and how to easily expand it).
But whether or not it would work for Pokitto and micropython I have no idea.
For anyone in particular or just as a general teaching thing?
Unfortunately that’s the case with most bytecode-based/interpreted languages implemented in C.
There will always be boilerplate simply to interface C/C++'s static type system with the target language’s dynamic type system and general infrastructure.
(I.e. language binding.)
As I said before, it is possible to automatically generate that boilerplate,
but it would require either writing a parser to read the input code and then generate the boilerplate,
or some clever C++ magic (like the functionality provided by Boost.Python).
Thanks for the generous offer. Is it possible to implement the API for Python as a separate entity and then include it in one of the files in the PikittoLib?
Since it’ll need expansion in the future for other sensors, I’d like to be able to expand it myself, if possible.
My class for the LEDs has those public methods:
void on(uint8_t position);
void off(uint8_t position);
void toggle(uint8_t position);
It unfortunately just has void return types so if there are special step needed to return a single value then an example would be cool too.
I’d prefer a user extension specific to the library, since it requires custom hardware.
The LEDs are connected to a TCA9554 IO expander and thus the default implementation wouldn’t work.
The Pins from the PEX are in use for other things and I try to rely as much as possible on the implementations from the PokittoLib.
Yes, the C++ that I have so far works like a charm.