Passing uint32_t array to Python using Python.h

-1

I am trying to construct a module for python in C. The module has several lines and methods, but one of the most important is to pass, efficiently, the integer representation of the concatenation of a uint32_t array to python. For example, from code below

{
    uint32_t state[3] = {0x00000300, 0x00001100, 0x00022200}
    char charstate[12];
    memcpy(charstate, state, 12);
    return Py_BuildValue("s#", charstate, 12);
}

I expect in python the integer representation of the concatenation of that hex elements that is 0x000003000000110000022200 = 14167099467300633453056. As you can see I tried to use 's#', but without success. Could you give me an advice, please?

python
c
stdint
asked on Stack Overflow Jan 15, 2021 by Juan • edited Jan 15, 2021 by Lundin

1 Answer

2

Passing uint32_t array to Python using Python.h

I would just do an array, as you have in C.

uint32_t state[3] = {0x00000300, 0x00001100, 0x00022200}
return Py_BuildValue("[k,k,k]", 
       (unsigned long)state[0],
       (unsigned long)state[1],
       (unsigned long)state[2]);

unsigned long is a type wide enough to store uint32_t.

what do you think is the correct type, if my integer is a "big" integer?

If the value has more then 64-bits, there is no "correct" type. Is so, move the calculations to python side.

If you want a single value of 14167099467300633453056 on python side, then the widest available type in C can't fit it - unsigned long long has (at least) 64-bits, while the value is expected to have 96 bits. I suggest either to:

  • to shift by 32 to the right or multiply by 2^32 the resulting values from the above code on python side, as python supports arbitrary number ranges, or
  • convert the 3 values to it's string representation and convert that C-string to python string

char buffer[200];
int len = snprintf(buffer, sizeof(buffer), 
     "%16"PRIx32"%016"PRIx32"%016"PRIx32,
     state[0], state[1], state[2]);
Py_BuildValue("#s", buffer, len);

and then convert the resulting value to number on python side, which would be analogous to int("3000000110000022200", 16) in python.

I expect in python the integer representation of the concatenation of that hex elements that is 0x000003000000110000022200

After memcpy on a little endian system the content of charstate would be:

char charstate[12] = {
    0x00, 0x03, 0x00, 0x00,
    0x00, 0x11, 0x00, 0x00, 
    0x00, 0x22, 0x02, 0x00 };

which on call to Py_BuildValue("s#", charstate to a python string, that would look like:

ret="\00\03\00\00\00\x11\00\00\00\x22\x02\00"
# len(ret)=12 - 12 bytes!

then you would have to convert each byte by byte to an integer and shift the result on each byte by 8 (or multiply by 2^8) to some accumulator to get the resulting value.

answered on Stack Overflow Jan 15, 2021 by KamilCuk • edited Jan 15, 2021 by KamilCuk

User contributions licensed under CC BY-SA 3.0