Link to class methods in composition technique

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
ales.coppelli
Posts: 34
Joined: Wed Aug 08, 2018 9:15 am

Link to class methods in composition technique

Post by ales.coppelli » Wed Dec 23, 2020 11:08 am

I have a STM32F411 board and when I try to use
the I2C bus master is all ok:

-------
from machine import I2C

i2c = I2C(1)
i2c.scan() -->Ok [25,30][i.e. address of accelerometer, address of magnetometer]


i2c.writeto_mem(25,32,b'\x77')
i2c.writeto_mem(25,35,b'\x08')

i2c.readfrom_mem(25,40,1)
i2c.readfrom_mem(25,41,1)
-------


Now I would like to write ( in C ) a class for my project that use an I2C object
i.e. I would like write something like this ( in Micropython interpreter):

from machine import I2C
from MYMODULE_WROTE_IN_C import MYCLASS_WROTE_IN_C

i2c = I2C(1)
a = MYCLASS_WROTE_IN_C(i2c)

and now the object 'a' should be use the object 'i2c'
(composition technique )


Question:


How I can use/run/invoke the class methods ( 'writeto_mem' e 'readfrom_mem' )
from a method in MYCLASS_WROTE_IN_C ?


This is what I did.

The definition of my class is:

typedef struct _myclass_obj_t {
mp_obj_base_t base;
struct _machine_hard_i2c_obj_t* i2c;
...
...
} myclass_obj_t;

and in the constructor of my class I verify the correct type


...
...
if (mp_obj_get_type(args[0]) == &machine_hard_i2c_type) {
self->i2c=args[0];
}else{
mp_print_str(MP_PYTHON_PRINTER, "The argumet is not a I2C type.");
}
...
...

and the compilation is ok.

But when I write something like

...
self->i2c->machine_i2c_writeto_mem(25,35,0x08);
...
I obtain the compilation error:

error: dereferencing pointer to incomplete type 'struct _machine_hard_i2c_obj_t'


If I write in the file "myclass_wrote_in_c.c"

//From ports/stm32/machine_i2c.c
typedef struct _machine_hard_i2c_obj_t {
mp_obj_base_t base;
i2c_t *i2c;
mp_hal_pin_obj_t scl;
mp_hal_pin_obj_t sda;
} machine_hard_i2c_obj_t;

I obtained the correct error:

error: 'struct _machine_hard_i2c_obj_t' has no member named 'writeto_mem'

What do I do to invoke a class methods that belongs to object 'i2c' ?

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Link to class methods in composition technique

Post by stijn » Thu Dec 24, 2020 8:39 am

Looking at the error, the compiler probably doesn't know what _machine_hard_i2c_obj_t is so it cannot do anything with it. You'd have to #include the full definition (not just the declaration). But that is not possible, because different platforms each use their own implementation so there are no .h files with the definition, only local definitions in .c files. Which also means it's a 'private' implementation detail and you shouldn't be usng it; well, you cannot, because the compiler doesn't know what it is.

Instead you could just store an mp_obj_t and in your constructor retrieve the methods you want using mp_load_method(). Then later call them using mp_call_function_n_kw(). That has some overheard in comparison with callin a function directly, but I don't think there is another way here.
Or write this in Python?

Note the forum uses https://en.wikipedia.org/wiki/BBCode so if put code tags around your code (manually, or by clicking the button above the text editor) things become much more readable.

ales.coppelli
Posts: 34
Joined: Wed Aug 08, 2018 9:15 am

Re: Link to class methods in composition technique

Post by ales.coppelli » Thu Dec 24, 2020 9:39 am

Thank you very much Stijn. Sorry for my goofy post.
I'll try immidiatly your suggestions.

Krasn4ck
Posts: 10
Joined: Wed Feb 10, 2021 5:46 pm
Location: Baikonur

Re: Link to class methods in composition technique

Post by Krasn4ck » Tue Mar 09, 2021 9:08 pm

ales.coppelli wrote:
Thu Dec 24, 2020 9:39 am
Thank you very much Stijn. Sorry for my goofy post.
I'll try immidiatly your suggestions.
Hi ales, were you able to try to implement the methods of machine_i2c.c in your C module?

Post Reply