ctypes获取导出变量

在dll中,不仅会导出方法,类,结构体,还会导出对应变量。

那么ctypes可以获取导出变量。

首先需要确定导出的是什么类型;

 我们直接使用python自己的库作为案例。我们获取导出的变量    Py_OptimizeFlag,这个是一个整型,值一般是0,1,2表示解释器的三种状态。无,-o,-oo。

ctypes可以通过in_dll类方法进行获取这个变量。pythonapi是一个预定义的变量,用来接入python的c api的。

>>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
>>> print(opt_flag)
c_long(0)
>>>

如果python解释器以-o的模式启动,那么输出就是一个c_long(1),-oo就是c_long(2).

下面将扩展这个案例,展示由python导出的一个指针变量,这个指针变量指向的PyImport_FrozenModules。

这个内容包含了docs帮助文档

为了操纵这个内存,我们需要知道这一块内存是怎么分配的,分别是什么类型。这样才能更好的被ctypes读取操作。

>>> from ctypes import *
>>>
>>> class struct_frozen(Structure):
...     _fields_ = [("name", c_char_p),
...                 ("code", POINTER(c_ubyte)),
...                 ("size", c_int)]
...
>>>

在上面的代码中,我们定义了struct_frozen数据类型,所以我们可以创建一个指向类型是sruct_frozen的指针来指向这块内存。

>>> from ctypes import *
>>>
>>> class struct_frozen(Structure):
...     _fields_ = [("name", c_char_p),
...                 ("code", POINTER(c_ubyte)),
...                 ("size", c_int)]
...
>>>

因为table是一个指针,指向的还是一组数据,所以我们可以通过for进行迭代遍历。但是只有确认了迭代终止条件我们才可以进行迭代。但是因为这个指针没有长度,当我们访问越界的时候就可能造成崩溃。所以,最好在读取到NULL的时候就终止。如下。

>>> for item in table:
...     if item.name is None:
...         break
...     print(item.name.decode("ascii"), item.size)
...
_frozen_importlib 31764
_frozen_importlib_external 41499
__hello__ 161
__phello__ -161
__phello__.spam 161
>>>

事实上,标准的python静态模块和静态的包(由负数代表容量)其他的用证书,这个仅仅做测试,如果想要实验,可以通过  import __hello__ 进行验证。

猜你喜欢

转载自blog.csdn.net/rubikchen/article/details/89631706