-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?

8
  • Do you mean char charstate[12];? *charstate[12] means a list of strings. Commented Jan 15, 2021 at 9:06
  • @rickimaru I correct it, thanks Commented Jan 15, 2021 at 9:11
  • 1
    I expect in python the integer representation What about endianess? From documentation of Py_BuildValue I see s# converts a C string. The first byte of charstate is 0x00 (either endianess way) so it's an empty string... Commented Jan 15, 2021 at 9:13
  • @KamilCuk for example for 0x000003000000110000022200 I expect 14167099467300633453056 Commented Jan 15, 2021 at 9:15
  • What do you mean "for example"? 0x000003000000110000022200 is a number, not a string. s# takes a string. And a number equal to state[0] << 32 | state[1] << 16 | state[2] is not equal to memcpy it, because most probably you are little endian.. Commented Jan 15, 2021 at 9:16

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I tried char charstate[12] = { 0x00, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00 }; return Py_BuildValue("s#", charstate); But after python print I do not see something similar to \00\03\00\00\00\x11\00\00\00\x22\x02\00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.