Page 1 of 1

Link to class methods in composition technique

Posted: Wed Dec 23, 2020 11:08 am
by ales.coppelli
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' ?

Re: Link to class methods in composition technique

Posted: Thu Dec 24, 2020 8:39 am
by stijn
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.

Re: Link to class methods in composition technique

Posted: Thu Dec 24, 2020 9:39 am
by ales.coppelli
Thank you very much Stijn. Sorry for my goofy post.
I'll try immidiatly your suggestions.

Re: Link to class methods in composition technique

Posted: Tue Mar 09, 2021 9:08 pm
by Krasn4ck
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?