Passing structs to external C modules

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
ProudPagan
Posts: 35
Joined: Fri Apr 12, 2019 8:55 am

Passing structs to external C modules

Post by ProudPagan » Tue Jun 11, 2019 5:38 am

Hi,

I need to pass a C struct (below) from MicroPython to an external C module.

Code: Select all

typedef struct {
    struct myS *stptr;
    uint32_t i;
    uint32_t *jptr;
} myT;
I am planning to pack a ustruct and call the C function, but what `mp_obj_get_ ( )` should I call
in my C function to retrieve the struct?

Thanks very much!

PP

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Passing structs to external C modules

Post by jimmo » Tue Jun 11, 2019 8:33 am

If you're using ustruct.pack, you'll get a byte array (which is what I assume you're passing to your function). So your C function can get the underlying buffer and cast it to your struct type. Look at, for example, modframebuf.c for an example of something that takes a buffer from Python.

I'm not sure how you're going to use struct.pack to make the pointer members though?

ProudPagan
Posts: 35
Joined: Fri Apr 12, 2019 8:55 am

Re: Passing structs to external C modules

Post by ProudPagan » Wed Jun 12, 2019 7:59 am

Hi jimmo,

Thanks for the reply. You are right -- it might get very kludgy trying to use ustruct or uctypes, and probably
not possible at all.

Instead, I wrote a C wrapper around the lower level C functions. This C wrapper handles all the struct and
pointer management and will take a string and an integer (all operations are encoded in this string and will be parsed
by the C wrapper).

The MicroPython wrapper around my C wrapper will be like this:

Code: Select all

STATIC mp_obj_t mp_my_c_wrapper (mp_obj_t oa, mp_obj_t oi) {
	const char *a = mp_obj_str_get_str(oa);
	int i = mp_obj_get_int(oi);
	char *val = malloc(2000);
        val = my_c_wrapper (a, i);
	return val; // FIXME: How do I return a string?
}
Two questions:
  • Is mp_obj_str_get_str() the right function to use to convert the mp_obj_t passed to mp_my_c_wrapper() to a char * ?
  • My C wrapper needs to return a string back to Python, How do I accomplish this?


Thanks!

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Passing structs to external C modules

Post by jimmo » Wed Jun 12, 2019 11:38 am

ProudPagan wrote:
Wed Jun 12, 2019 7:59 am
Is mp_obj_str_get_str() the right function to use to convert the mp_obj_t passed to mp_my_c_wrapper() to a char * ?
Yup, but you might be better off with mp_obj_str_get_data

See py/obj.h

Code: Select all

qstr mp_obj_str_get_qstr(mp_obj_t self_in); // use this if you will anyway convert the string to a qstr
const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated
const char *mp_obj_str_get_data(mp_obj_t self_in, size_t *len);
ProudPagan wrote:
Wed Jun 12, 2019 7:59 am
My C wrapper needs to return a string back to Python, How do I accomplish this?

Code: Select all

mp_obj_t mp_obj_new_str(const char* data, size_t len);

ProudPagan
Posts: 35
Joined: Fri Apr 12, 2019 8:55 am

Re: Passing structs to external C modules

Post by ProudPagan » Thu Jun 13, 2019 3:52 am

Thanks a ton!

My module is now done.

PP

Post Reply