72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
![]() |
import ctypes
|
|||
|
|
|||
|
|
|||
|
def get_field_address(struct_instance, field_path):
|
|||
|
# 分割字段路径
|
|||
|
fields = field_path.split('.')
|
|||
|
# 获取起始结构体的基地址
|
|||
|
current_address = ctypes.addressof(struct_instance)
|
|||
|
current_type = type(struct_instance)
|
|||
|
|
|||
|
# 遍历path的每个field
|
|||
|
for field in fields:
|
|||
|
# 在 _fields_ 中查找字段
|
|||
|
found = False
|
|||
|
# 遍历当前结构体的所有field
|
|||
|
for f_name, f_type in current_type._fields_:
|
|||
|
|
|||
|
# 如果结构体中的field和当前查找的field一致
|
|||
|
if f_name == field:
|
|||
|
found = True
|
|||
|
# 计算偏移量
|
|||
|
offset = sum(
|
|||
|
getattr(current_type, fname).offset for fname, _ in current_type._fields_ if fname == field)
|
|||
|
current_address += offset
|
|||
|
|
|||
|
# 如果还有下一个字段,更新当前类型
|
|||
|
if field != fields[-1]:
|
|||
|
# 判断当前的field是不是type,且是不是结构体类型
|
|||
|
if isinstance(f_type, type) and issubclass(f_type, ctypes.Structure):
|
|||
|
current_type = f_type
|
|||
|
else:
|
|||
|
raise ValueError(f"字段 '{field}' 不是结构体类型")
|
|||
|
# 跳出当前循环
|
|||
|
break
|
|||
|
|
|||
|
if not found:
|
|||
|
raise ValueError(f"在结构体中找不到字段 '{field}'")
|
|||
|
|
|||
|
return current_address
|
|||
|
|
|||
|
|
|||
|
# 使用示例
|
|||
|
def print_all_addresses(struct_instance, prefix=""):
|
|||
|
struct_type = type(struct_instance)
|
|||
|
|
|||
|
for field_name, field_type in struct_type._fields_:
|
|||
|
full_path = f"{prefix}{field_name}"
|
|||
|
|
|||
|
# 如果是结构体类型,递归打印其成员
|
|||
|
if isinstance(field_type, type) and issubclass(field_type, ctypes.Structure):
|
|||
|
nested_struct = getattr(struct_instance, field_name)
|
|||
|
print_all_addresses(nested_struct, f"{full_path}.")
|
|||
|
else:
|
|||
|
try:
|
|||
|
address = get_field_address(struct_instance, field_name)
|
|||
|
print(f"{full_path} 的地址: {hex(address)}")
|
|||
|
except ValueError as e:
|
|||
|
print(e)
|
|||
|
|
|||
|
|
|||
|
# 计算成员变量的offset
|
|||
|
def get_filed_offset(struct_instance, field_path):
|
|||
|
print(type(struct_instance))
|
|||
|
print(issubclass(type(struct_instance), ctypes.Structure))
|
|||
|
|
|||
|
if isinstance(struct_instance, type) and issubclass(struct_instance, ctypes.Structure):
|
|||
|
base_address = ctypes.addressof(struct_instance)
|
|||
|
|
|||
|
field_address = get_field_address(struct_instance, field_path)
|
|||
|
|
|||
|
return field_address - base_address
|
|||
|
return 0
|