如何在Python ctypes中测试指针相等性?
解决ctypes中数组对象与返回指针的地址比较问题
嘿,这个问题我之前踩过坑!你直接用assertEqual(rval, ptr)失败的原因很简单:你比较的是两个不同的Python包装对象,而不是它们底层指向的内存地址。ptr是c_longlong_Array_100类型的数组实例,rval是LP_c_longlong类型的指针实例,它们是完全不同的Python对象,所以直接用==比较的是对象身份,而不是内存地址。
下面给你两种可行的解决方法:
方法1:直接比较内存地址的整数数值
ctypes提供了addressof()函数来获取对象的内存地址,同时指针对象可以直接转换为整数表示其地址。你可以这样做:
import ctypes # 假设你的api已经正确加载了C库 ptr = (ctypes.c_int64 * 100)() rval = api.foo(ptr) # 比较两者的内存地址数值 assert ctypes.addressof(ptr) == int(rval)
ctypes.addressof(ptr)会返回数组首元素的内存地址(因为数组在内存中是连续的,首地址就是整个数组的起始地址)int(rval)会把指针对象转换为对应的内存地址整数
方法2:将数组转换为指针类型后再比较
你可以用ctypes.cast()把数组对象转换成和rval同类型的指针,这样两个指针对象就可以直接用==比较地址了:
import ctypes ptr = (ctypes.c_int64 * 100)() rval = api.foo(ptr) # 将数组转换为c_int64指针 ptr_as_ptr = ctypes.cast(ptr, ctypes.POINTER(ctypes.c_int64)) # 现在两个都是同类型的指针对象,可以直接比较 assert ptr_as_ptr == rval
这种方法的好处是,转换后的ptr_as_ptr和rval都是LP_c_longlong类型的指针实例,此时==运算符会自动比较它们指向的内存地址是否相同,而不是对象身份。
补充说明
为什么直接比较ptr和rval不行?因为数组对象和指针对象在ctypes里是不同的包装类型:
- 数组对象不仅包含内存地址,还包含数组长度等元信息
- 指针对象只是对内存地址的简单包装
它们是不同的Python实例,所以ptr is rval或者ptr == rval都会返回False,但它们底层指向的是同一块内存区域。
内容的提问来源于stack exchange,提问作者left4bread
相关产品推荐
相关产品推荐

