Utility functions:
ctypes.addressof(obj)
Returns the address of the memory buffer as integer. obj must be an instance of a ctypes type.
ctypes.alignment(obj_or_type)
Returns the alignment requirements of a ctypes type. obj_or_type must be a ctypes type or instance.
ctypes.byref(obj[, offset])
Returns a light-weight pointer to obj, which must be an instance of a ctypes type. offset defaults to zero, and must be an integer that will be added to the internal pointer value.
byref(obj, offset) corresponds to this C code:
(((char *)&obj) + offset)
The returned object can only be used as a foreign function call parameter. It behaves similar to pointer(obj), but the construction is a lot faster.
New in version 2.6: The offset optional argument was added.
ctypes.cast(obj, type)
This function is similar to the cast operator in C. It returns a new instance of type which points to the same memory block as obj. type must be a pointer type, and obj must be an object that can be interpreted as a pointer.
1、addressof与byref关系
>>>str1=c_char_p("hello world")
>>>p1=addressof(str1)
>>>p2=byref(str1)
>>>print hex(p1)
0x107a26a30
>>>print p2
<cparam 'P' (0x107a26a30)>
#其内存地址为0x107a26a30
2、c_char_p、c_int、pointer内存中形式
>>>str1=c_char_p("hello world")
>>>i1=c_int(3333)
>>>p1=pointer(i1)
str1的内存为一个指针,指向一个字符串;
i1的内存为一个整数;
p1的内存为一个数据结构;
在windbg查看以上对象的内存内容发现c_int的内存形式与c语言的整数形式一样。c_char_p的内存内容为一个指针,指针指向一个字符串,而c语言中一个字符串变量的内存内容直接是字符串。pointer对象有其自己结构,其第三个DWORD为其contents指针,contents内容为pointer指向对象的指针。假如指向对象为c_int,则contents中内容为c_int对象的地址。
>>>str1=c_char_("hello world")
>>>p1=cast(str1,POINTER(c_int))
>>>print p1.contents.value
0x6c6c6568 #为hell的十六进制形式
假如我们要移位输出str1的话,那怎么办呢?比如获得“world”这个字符串。
>>>i1=cast(byref(str1),POINTER(c_int))#str1内容是字符串的指针,我们要对此指针进行加操作,先得获取此指针,就是将其转换成整数,cast只接受指针,所以先获取他们的指针,再转。
>>>offset1=i1.contents.value+6 #加偏移6,便是字符串world的地址,接下来需要将此地址转成c_char_p
>>>i2=c_int(offset1) #首先得得到它的对象
>>>str2=cast(byref(i2),POINTER(c_char_p)) #将i2转成c_char_p,由于cast只接受指针,所以先取其指针,再转。
>>>print str2.contents.value
world
挺无聊,其实就是想通过这个例子弄清楚ctypes中常用类型的类型转换。