You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python ctypes镜像包含std::string的C++结构体?

用ctypes读取含std::string的C++结构体内存值

方案一:模拟std::string的内存布局读取

C++的std::string内存布局会因编译器(如GCC/Clang、MSVC)略有差异,但多数64位平台下的标准实现是由三个8字节字段组成:指向字符串数据的指针、字符串长度、容量。你可以用ctypes定义对应结构来匹配:

import ctypes

# 适配GCC/Clang的std::string布局(64位)
class StdString(ctypes.Structure):
    _fields_ = [
        ("data_ptr", ctypes.c_void_p),   # 指向字符串数据的指针
        ("length", ctypes.c_size_t),     # 字符串实际长度
        ("capacity", ctypes.c_size_t)    # 已分配的内存容量
    ]

# 修改后的结构体定义,替换原char数组为StdString
class AppStructFoo(ctypes.Structure):
    _fields_ = [
        ("next", ctypes.c_void_p),
        ("prev", ctypes.c_void_p),            
        ("name", StdString),
        ("identifier", ctypes.c_int32),
        ("flag", ctypes.c_int),
        ("idname", StdString),
        ("typeinfo", ctypes.c_void_p),
        ("type_legacy", ctypes.c_int16),
        ("ui_order", ctypes.c_int16),
        ("custom1", ctypes.c_int16),
        ("custom2", ctypes.c_int16),
        # 其他字段...
    ]

# 读取结构体并获取目标值
node_struct = AppStructFoo.from_address(memory_address)
print(node_struct.custom2)

# 若需要读取字符串内容
name_str = ctypes.c_char_p(node_struct.name.data_ptr).value.decode('utf-8')
print(name_str)

注意:如果目标程序用MSVC编译,std::string会有小字符串优化(SSO),布局会更复杂,需要对应调整结构体定义。这种方案的局限性是依赖具体编译器实现,跨平台可能失效。

方案二:跳过std::string字段,直接计算偏移读取目标值

如果只需要读取custom2这类后续字段,完全可以跳过std::string的具体布局,通过计算字段偏移量直接读取目标内存地址:

import ctypes

# 定义临时结构体,用占位符模拟std::string的大小(保证对齐正确)
class TempStruct(ctypes.Structure):
    _fields_ = [
        ("next", ctypes.c_void_p),
        ("prev", ctypes.c_void_p),            
        # 用3个void*占位,匹配64位std::string的24字节大小
        ("name", ctypes.c_void_p * 3),
        ("identifier", ctypes.c_int32),
        ("flag", ctypes.c_int),
        ("idname", ctypes.c_void_p * 3),
        ("typeinfo", ctypes.c_void_p),
        ("type_legacy", ctypes.c_int16),
        ("ui_order", ctypes.c_int16),
        ("custom1", ctypes.c_int16),
    ]

# 计算custom2相对于结构体起始地址的偏移量
custom2_offset = ctypes.sizeof(TempStruct)

# 直接读取目标值
custom2_value = ctypes.c_int16.from_address(memory_address + custom2_offset).value
print(custom2_value)

这种方案的优势是不依赖std::string的具体实现,无需关心字符串内容,只专注于目标字段的偏移,稳定性更高。

内容的提问来源于stack exchange,提问作者DB3D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 10:25:14