lv_binding_micropython icon indicating copy to clipboard operation
lv_binding_micropython copied to clipboard

Disabling LV_USE_PRIVATE_API will generate wrong `add_event_cb` C code , causing "Cannot convert 'function' to pointer" error

Open garywill opened this issue 2 months ago • 0 comments

If in lv_conf.h #define LV_USE_PRIVATE_API is set to 0,

when we try to use

# btn.add_event_cb(btn_cb, lv.EVENT.ALL, None)

we will get error:

Cannot convert 'function' to pointer

(lambda won't work)

I found the reason : when LV_USE_PRIVATE_API disabled, wrong lv_mp.c generated:

static mp_obj_t mp_lv_obj_add_event_cb(size_t mp_n_args, const mp_obj_t *mp_args, void *lv_func_ptr)
{
    void *user_data = mp_to_ptr(mp_args[3]);
    lv_event_cb_t event_cb = mp_to_ptr(mp_args[1]);
    lv_event_code_t filter = (int)mp_obj_get_int(mp_args[2]);
    lv_obj_t *obj = mp_to_lv(mp_args[0]);
    lv_event_dsc_t * _res = ((lv_event_dsc_t *(*)(lv_obj_t *, lv_event_cb_t, lv_event_code_t, void *))lv_func_ptr)(obj, event_cb, filter, user_data);
    return mp_read_ptr_lv_event_dsc_t((void*)_res);
}
....
static mp_obj_t mp_lv_indev_add_event_cb(size_t mp_n_args, const mp_obj_t *mp_args, void *lv_func_ptr)
{
    void *user_data = mp_to_ptr(mp_args[3]);
    lv_event_cb_t event_cb = mp_to_ptr(mp_args[1]);
    lv_event_code_t filter = (int)mp_obj_get_int(mp_args[2]);
    lv_indev_t *indev = mp_write_ptr_lv_indev_t(mp_args[0]);
    ((void (*)(lv_indev_t *, lv_event_cb_t, lv_event_code_t, void *))lv_func_ptr)(indev, event_cb, filter, user_data);
    return mp_const_none;
}

But the correct C code should be like: (when LV_USE_PRIVATE_API enabled, defaulty)

static mp_obj_t mp_lv_obj_add_event_cb(size_t mp_n_args, const mp_obj_t *mp_args, void *lv_func_ptr)
{
    void *user_data = mp_to_ptr(mp_args[3]);
    void *event_cb = mp_lv_callback(mp_args[1], &lv_obj_add_event_cb_event_cb_callback, MP_QSTR_lv_obj_add_event_cb_event_cb, &user_data, NULL, (mp_lv_get_user_data)NULL, (mp_lv_set_user_data)NULL);
    lv_event_code_t filter = (int)mp_obj_get_int(mp_args[2]);
    lv_obj_t *obj = mp_to_lv(mp_args[0]);
    lv_event_dsc_t * _res = ((lv_event_dsc_t *(*)(lv_obj_t *, lv_event_cb_t, lv_event_code_t, void *))lv_func_ptr)(obj, event_cb, filter, user_data);
    return mp_read_ptr_lv_event_dsc_t((void*)_res);
}

garywill avatar Oct 11 '25 04:10 garywill