param_service/main.py

123 lines
4.0 KiB
Python
Raw Normal View History

2025-02-18 20:39:39 +08:00
import ctypes
# 定义内部结构体
class InnerStructLevel2(ctypes.Structure):
_pack_ = 1
_fields_ = [
("inner_field1", ctypes.c_char),
("inner_field2", ctypes.c_double),
("inner_field3", ctypes.c_double),
]
# 定义内部结构体
class InnerStructLevel1(ctypes.Structure):
_pack_ = 1
_fields_ = [
("inner_field1", ctypes.c_int),
("inner_field2", ctypes.c_double),
("inner_level2_field3", InnerStructLevel2)
]
# 定义外部结构体
class OuterStruct(ctypes.Structure):
_pack_ = 1
_fields_ = [
("field1", ctypes.c_int),
("nested", InnerStructLevel1), # 嵌套结构体
("field2", ctypes.c_char * 10),
]
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
# 测试代码
if __name__ == "__main__":
outer = OuterStruct()
# # 打印所有字段的地址
# print_all_addresses(outer)
print(get_filed_offset(outer, "nested.inner_level2_field3"))
# # 获取特定嵌套字段的地址
# print(f'0x{ctypes.addressof(outer):08X}')
# nested_field_address = get_field_address(outer, "nested.inner_level2_field3")
#
# print(f"\n直接访问嵌套字段 nested.inner_field2 的地址: {hex(nested_field_address)}")
#
# # 获取特定嵌套字段的地址
# nested_field_address = get_field_address(outer, "nested.inner_level2_field3.inner_field3")
#
# print(f"\n直接访问嵌套字段 nested.inner_level_field3.inner_field1 的地址: {hex(nested_field_address)}")