Python:如何使用 struct.pack_into 将不同类型的数据打包到字符串缓冲区中

发布于 2024-11-06 13:12:13 字数 572 浏览 0 评论 0原文

我正在尝试将一些无符号 int 数据打包到使用 ctypes.create_string_buffer 创建的字符串缓冲区中。

以下是以下代码段,以及一个显示错误在键盘上的运行示例:

import struct
import ctypes
import binascii

buf = ctypes.create_string_buffer(16)
struct.pack_into("=I=I=I", buf, 0, 1, 2, 3)
print binascii.hexlify(buf)

这会产生以下错误:

...
struct.error: bad char in struct format

该文档没有提到如果底层缓冲区是特定的 C 类型,是否可以打包不同类型的数据。在本例中,尝试将 unsigned int 数据打包到具有底层 c_char 类型的字符串缓冲区中。任何人都知道执行此操作的解决方案,或者是否有特定的方法来创建可以打包任何类型数据的缓冲区?

I'm trying to pack some unsigned int data into a string buffer created using ctypes.create_string_buffer.

Here is the following code segment, and a running example showing the error on codepad:

import struct
import ctypes
import binascii

buf = ctypes.create_string_buffer(16)
struct.pack_into("=I=I=I", buf, 0, 1, 2, 3)
print binascii.hexlify(buf)

This yields the following error:

...
struct.error: bad char in struct format

The documentation doesn't allude to whether you can pack data of different types if the underlying buffer is of a specific C type. In this case, trying to pack unsigned int data into a string buffer with an underlying c_char type. Anyone know of a solution to do this, or is there a specific way to create a buffer that can pack any type of data?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一笑百媚生 2024-11-13 13:12:13

您不应该在每个输出说明符前添加“=”代码。只需说一次:

struct.pack_into("=III", buf, 0, 1, 2, 3)

这会产生:

01000000020000000300000000000000

You're not supposed to prefix every output specifier with the '=' code. Just say it once:

struct.pack_into("=III", buf, 0, 1, 2, 3)

This yields:

01000000020000000300000000000000
短暂陪伴 2024-11-13 13:12:13

很抱歉重提旧话题,但我明白了“突然”的意思——可能被类似的背景习惯所击中。

“格式字符串的第一个字符可用于指示打包数据的字节顺序、大小和对齐方式”我同意。然而:

  • Python 文档故意(?)省略了使用顺序格式化程序的一个示例(所有示例均假定本机字节顺序、大小以及与大端机器的对齐方式。
  • 人们可能会假设(正如我和可能 snap所做的那样),“III”由三个格式字符串组成,我们可以随意格式化它们中的每一个。因此=I=I=I。在习惯了 Ruby 的 array.pack 之后,我搬起石头砸了自己的脚,在这种情况下,人们可以自由地改变表达式的顺序(在这种情况下,Ruby 的等价物是 I_I_I_ ,因为顺序选择器位于类型之后)。

因此,我想最好在 struct.pack/unpack 文档中添加几行,给出 order & 的示例。填充的使用(嗯,填充对我的打击更大......我可以接受本机顺序,但填充破坏了我的协议)。

Sorry for resurrecting old topic, but I get the point of "snap" - being hit by probably similar background habit.

"the first character of the format string can be used to indicate the byte order, size and alignment of the packed data" I agree. However:

  • Python docs deliberately (?) omit even a single example of use of order formatters (All examples assume a native byte order, size, and alignment with a big-endian machine.)
  • One may assume (as I and probably snap did), that "III" consists of three format strings and we may format every one of them at will. Hence =I=I=I. I shot myself in the foot after getting used to Ruby's array.pack, where one may freely change ordering along the expression (Ruby's equivalent is I_I_I_ in this case, as order selector comes after type).

Hence I guess it might be good to add a few lines to struct.pack/unpack docs, giving examples of order & padding use (meh, padding hit me even harder... I could live with native order, but padding ruined my protocol).

单挑你×的.吻 2024-11-13 13:12:13

标准操作过程:阅读错误消息。

“struct format 中的错误字符”就是它所说的意思。

标准操作流程:检查文档这里它说“第一个 [我的重点] 格式字符串的字符可用于指示打包数据的字节顺序、大小和对齐方式”,并继续列出 = 作为一种可能性。下一部分(格式字符)列出了许多字母,包括I

结论:您的格式字符串应该是 "=III"

注意:该问题与目标缓冲区完全无关,更不用说它的底层 C 类型了:

>>> import struct
>>> struct.pack("=I=I=I", 1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: bad char in struct format
>>> struct.pack("=III", 1, 2, 3)
'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
>>> 

Standard operating procedure: Read the error message.

"bad char in struct format" means what it says.

Standard operating procedure: Check the docs. Here it says "the first [my emphasis] character of the format string can be used to indicate the byte order, size and alignment of the packed data" and goes on to list = as a possibility. The next section (Format Characters) lists many letters including I.

Conclusion: your format string should be "=III".

Note: The problem has nothing to do with the destination buffer at all, let alone its underlying C type:

>>> import struct
>>> struct.pack("=I=I=I", 1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: bad char in struct format
>>> struct.pack("=III", 1, 2, 3)
'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
>>> 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文