gpt4 book ai didi

python - 解码 ctypes 结构

转载 作者:太空宇宙 更新时间:2023-11-03 15:26:19 26 4
gpt4 key购买 nike

我正在努力了解 python 中的 ctypes,并且我能够使一些简单的事情正常工作,但是当涉及到解包 c 结构时,我发现自己遇到了一些困难。我决定为了学习这个我应该尝试一下,虽然我知道套接字标准库实现了 gethostbyname_ex(),但我想我会尝试使用 ctypes< 来实现它libc.gethostbyname()

我能够相当轻松地执行 libc.gethostbyname():

#!/usr/bin/env python
from ctypes import *

cdll.LoadLibrary('libc.so.6')
libc = CDLL('libc.so.6')
he = libc.gethostbyname("www.google.com")

但这给了我一个 hostent 数据结构。我认为最好的解压方法是获取 c 结构并创建一个继承自 ctypes.Structure 的类,所以我想到了这个(我找到了 hostent netdb.h 中的结构定义):

class hostent(Structure):
'''
struct hostent
{
char *h_name; /* Official name of host. */
char **h_aliases; /* Alias list. */
int h_addrtype; /* Host address type. */
int h_length; /* Length of address. */
char **h_addr_list; /* List of addresses from name server. */
}
'''
_fields_ = [("h_name", c_char_p), ("h_aliases", POINTER(c_char_p)),
("h_addrtype", c_int), ("h_length", c_int),
("h_addr_list", POINTER(c_char_p))]

我不清楚的地方是我是否正确设置了 h_aliasesh_addr_list 字段,因为每当我尝试将它们作为数组访问时,即使是在第 0 个在查找我知道至少有一个别名和至少一个地址的东西后,我得到一个 NULL 指针访问 ValueError 异常:

>>> he = hostent(libc.gethostbyname("www.google.com"))
>>> pprint.pprint(he.h_addr_list)
<__main__.LP_c_char_p object at 0xb75dae84>
>>> print he.h_addr_list[0]
Traceback (most recent call last):
File "/tmp/py2659JxK", line 24, in <module>
print he.h_addr_list[0]
ValueError: NULL pointer access

欢迎提出任何建议。

最佳答案

您需要定义gethostbyname 的返回类型是什么:

>>> libc.gethostbyname.restype = POINTER(hostent)
>>> he = libc.gethostbyname("www.google.com")[0]
>>> he.h_aliases[0]
'www.google.com'

此外,h_addr_list 不应声明为 POINTER(c_char_p),因为 c_char_p 用于空终止字符串。在这种情况下 POINTER(POINTER(c_ubyte)) 会更好,然后第一个地址将是 he.h_addr_list[0][:4] 如果它是 IPv4 地址.

关于python - 解码 ctypes 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6322781/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com