【问题标题】:Passing uint32_t array to Python using Python.h使用 Python.h 将 uint32_t 数组传递给 Python
【发布时间】:2021-04-20 06:28:37
【问题描述】:

我正在尝试在 C 中为 python 构建一个模块。该模块有几个行和方法,但其中最重要的一个是有效地传递一个连接的整数表示uint32_t 数组到 python。例如,从下面的代码中

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

我希望在 python 中该十六进制元素的连接的整数表示为 0x000003000000110000022200 = 14167099467300633453056。如您所见,我尝试使用“s#”,但没有成功。请给我一个建议好吗?

【问题讨论】:

  • 你的意思是char charstate[12];*charstate[12] 表示字符串列表。
  • @rickimaru 我更正了,谢谢
  • I expect in python the integer representation 字节序呢?从Py_BuildValue 的文档中,我看到s# 转换了一个C 字符串。 charstate 的第一个字节是 0x00(无论是字节序方式)所以它是一个空字符串......
  • @KamilCuk 例如 0x000003000000110000022200 我预计 14167099467300633453056
  • “例如”是什么意思? 0x000003000000110000022200 是一个数字,而不是一个字符串。 s# 接受一个字符串。一个等于state[0] << 32 | state[1] << 16 | state[2] 的数字 等于memcpy 它,因为很可能你是小端的..

标签: python c stdint


【解决方案1】:

使用 Python.h 将 uint32_t 数组传递给 Python

我只想做一个数组,就像你在 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 是一个足够宽的类型,可以存储uint32_t

如果我的整数是“大”整数,你认为正确的类型是什么?

如果值超过 64 位,则没有“正确”类型。是这样,把计算移到python端。

如果您想要在 python 端使用单个值 14167099467300633453056,那么 C 中最宽的可用类型无法适应它 - unsigned long long (至少)有 64 位,而该值预计有 96位。我建议:

  • 在 python 端将上述代码的结果值向右移动 32 或乘以 2^32,因为 python 支持任意数字范围,或者
  • 将 3 个值转换为其字符串表示形式,并将 C 字符串转换为 python 字符串

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);

然后将结果值转换为python端的数字,类似于python中的int("3000000110000022200", 16)

我希望在 python 中该十六进制元素的连接的整数表示为 0x000003000000110000022200

little endian 系统上memcpy 之后,charstate 的内容将是:

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

调用Py_BuildValue("s#", charstate 到 python 字符串,看起来像:

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

然后您必须将每个字节逐字节转换为整数,并将每个字节的结果移位 8(或乘以 2^8)到某个累加器以获得结果值。

【讨论】:

  • 我试过 char charstate[12] = { 0x00, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00 };返回 Py_BuildValue("s#", charstate);但是在 python 打印之后,我看不到类似于 \00\03\00\00\00\x11\00\00\00\x22\x02\00 的内容
猜你喜欢
  • 2020-04-15
  • 1970-01-01
  • 2015-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 2018-08-23
  • 2010-09-27
  • 1970-01-01
相关资源
最近更新 更多