打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
python ctypes库中动态链接库加载方式

最近看了《Gray hat python》一书,这才知道为什么python是黑客必学的编程语言。通过python的ctypes模块,可以直接调用动态链接库中的导出函数,而且甚至可以直接在python中构建出复杂的C结构体!!!使得python也具备了底层内存操作的能力,再配合python本身强大的表达能力,能不让人激动么。

 

之前为了在python中调用动态链接库导出的函数,你需要自行解析出这些导出函数的地址。而现在ctypes库会替我们完成这个麻烦的过程,大大方便了我们直接在python中调用C函数的能力。

ctypes模块中有三种不同的动态链接库加载方式:cdll, windll, oledll。不同之处在于链接库中的函数所遵从的函数调用方式(calling convention)以及返回方式有所不同。

cdll用于加载遵循cdecl标准函数调用约定的链接库。windll则用于加载遵循stdcall调用约定的动态链接库。oledll与windll完全相同,只是会默认其载入的函数会统一返回一个Windows HRESULT错误编码。

先复习一下有关函数调用约定的知识:函数调用约定指的是函数参数入栈的顺序、哪些参数入栈、哪些通过寄存器传值、函数返回时栈帧的回收方式(是由调用者负责清理,还是被调用者清理)、函数名称的修饰方法等等。基本上我们最常见的调用约定就是cdecl和stdcall两种。在《程序员的自我修养--链接、装载与库》一书的第10章有对函数调用约定的更详细介绍。

cdecl规定函数参数列表以从右到左的方式入栈,且由函数的调用者负责清除栈帧上的参数。stdcall的参数入栈方式与cdecl一致,但函数返回时是由被调用者自己负责清理栈帧。而且stdcall是Win32 API函数所使用的调用约定。OK,就这么多,够了。

测试一下在Linux平台和Windows平台下通过ctypes模块导入C库中函数的小例子:

Windows 下:

from ctypes import *
msvcrt = cdll.msvcrt
msg = "Hello world!\n"
msvcrt.printf("Testing: %s", msg)


Linux下:

from ctypes import *
libc = CDLL("libc.so.6")
msg = "Hello, world!\n"
libc.printf("Testing: %s", msg)

 

可以看到动态链接库中的printf被直接导入到python中来调用了。

那么,在python中怎么表示C的类型?不用担心,下面这张表就能搞定。

有了这个映射关系,多复杂的C类型也能在python中表达出来。

 

在C中定义一个联合:

union 
{
long barley_long;
int barley_int;
char barley_char[8];
}barley_amount;

 

而在python中同等的定义为:注意一下python中定义数组的方式。

class barley_amount(Union):
_fields_ = [
("barley_long", c_long),
("barley_int", c_int),
("barley_char", c_char * 8),
]



测试一下这个例子,在python中定义一个联合体,为其赋值,再分别访问其成员。

from ctypes import *
class barley_amount(Union):
_fields_ = [
("barley_long", c_long),
("barley_int", c_int),
("barley_char", c_char * 8),
]
value = raw_input("Enter the amount of barley to put into the beer vat:")
my_barley = barley_amount(int(value))
print "Barley amount as a long: %ld" % my_barley.barley_long
print "Barley amount as an int: %d" % my_barley.barley_int
print "Barley amount as a char: %s" % my_barley.barley_char



 




 


  

 

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Python调用windows下DLL详解 - ctypes库的使用
Python使用ctypes模块调用DLL函数之传递数值、指针与字符串参数
Python调用windows下DLL详解
用Python来使用科大讯飞语音识别,so easy
Python与C之间的相互调用(PythonCAPI及Pythonctypes库)
新中新a16d二代居民身份证阅读器Python示例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服