Python读写位于指定内存地址的数据(不受Python机制限制的指针)

    Python的ctypes库中提供了pointer函数,返回指针对象。它包装了C语言中的指针。但是,Python设计者有意限制了我们使用它。我们无法给指针对象赋值以改变它指向的内存地址,或者对它做加减运算。它只是被用于传址调用,从而兼容C语言编写的库。这造成了不便。

    为了改变指针对象指向的内存地址,我们可以采用二级指针。具体代码如下:

from ctypes import *
a=c_int(521)
address=addressof(a)
#addressof函数以int型返回a的内存地址
p=pointer(pointer(c_int(0)))
#获取任意一个c_int型对象的内存地址
p.contents=c_longlong(address)
#在32位系统中,c_longlong应改为c_int
print(p.contents.contents)
#应该得到c_int(520)

    通过修改address变量的值,我们可以访问任意内存地址。对于其它类型的对象(如c_double),我们可以将“p=pointer(pointer(c_int(0)))”中的c_int换成对应的类型。

    通过此方法,我们还可以遍历数组。代码如下:

from ctypes import *
a=(c_float*10)(3.1416,2013.14,123.456)
#创建一个数组
address=addressof(a)
p=pointer(pointer(c_float(0.0)))
p.contents=c_longlong(address+4)
#由于c_float型长度为4字节,所以address+4指向数组第二个元素。
#必须加减指向数据的类型的长度的整数倍,否则会出错。这里与C语言有差异
print(p.contents.contents)
#应该输出c_float(2013.14)

    我们还可以修改指针指向的数据:

from ctypes import *
a=c_longlong(111111)
address=addressof(a)
p=pointer(pointer(c_longlong(0)))
p.contents=c_longlong(address)
p.p.contents.contents.value=123456
print(a)
#应该输出123456

    定义两个函数以方便读取与更改指定内存地址中的值:

from ctypes import *
def readMEM(addr:int,typ:type):
    p=pointer(pointer(typ(0)))
    p.contents=c_longlong(addr)
    return p.contents.contents
def writeMEM(addr:int,value):
    p=pointer(pointer(type(value)(0)))
    p.contents=c_longlong(addr)
    p.contents.contents=value
    return p.contents.contents
#注意在32位系统中将c_longlong改为c_int

    注意不要在程序中随意访问用户输入的内存地址,否则容易报出 Segmentation fault 。

    本文介绍的方法仅供学习Python和兼容C语言编写的库使用。Python中不推荐使用指针。我们应该学会使用Python推荐的方式。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值