最近看了《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.msvcrtmsg = "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_longprint "Barley amount as an int: %d" % my_barley.barley_intprint "Barley amount as a char: %s" % my_barley.barley_char

  

转载于:https://www.cnblogs.com/bigship/archive/2011/11/24/2262348.html

python ctypes库中动态链接库加载方式相关推荐

  1. Python gensim库使用word2vec 加载和保存模型、在预训练基础上训练自己的预料

    Python gensim库使用word2vec 常见: gensim.models.word2vec.Word2Vec(size=300, sg=1, min_count=1) 加载和保存模型 ge ...

  2. 优化CSS在网页中的加载方式

    点评:1.应该将 CSS 放置于结构的上方(一般放置于 head 元素内).CSS 是解释型语言,Firefox 和 IE 在等待 CSS 传输完成之前不会渲染任何东西.只有将 CSS 前置,才可在浏 ...

  3. python requests 动态加载_Python获取网页中动态加载的数据

    Python获取网页中动态加载的数据 0.XHR 是什么? XHR是 XMLHttpRequest 对象.既Ajax功能实现所依赖的对象,在JQuery中的Ajax是对 XHR的封装. 1.查看异步加 ...

  4. 软件库Library之静态库\动态库和静态加载\动态加载

    软件库Library之静态库\动态库和静态加载\动态加载 动态库之导入库 https://blog.csdn.net/wallaceli1981/article/details/5740718 * 动 ...

  5. 动态链接库dll的两种加载方式

    在第一篇技术博客"动态链接库简介"中说到了两种加载方式,当时没有详细说明,这里详细说明一下 可以通过两种方式 1.隐式链接(需要.dll,.lib,.h) 2.显式链接(需要.dl ...

  6. 浅谈Entity Framework中的数据加载方式

    如果你还没有接触过或者根本不了解什么是Entity Framework,那么请看这里http://www.entityframeworktutorial.net/EntityFramework-Arc ...

  7. android studio打包apk,jnilibs中的so库未被加载到apk内

    不久前,因为需要接入人脸识别以及某个tts的播报功能,人脸识别使用旷世,语音本地播报使用思必驰,在集成的时候出现思必驰的so库无法集成到apk内,思必驰的so库结构为: ,旷世的sdk却是使用的aar ...

  8. Android将so库封装到jar包中并加载其中的so库

    Android将so库封装到jar包中并加载其中的so库 之前写过将jar包和so库封装到jar包中的文章,但是没有考虑别人调用时需要加载so库的问题.因为so库放入jar之后,so就不是一个独立的. ...

  9. ios首次加载web_IOS_IOS中UIWebView的使用详解,一、初始化与三种加载方式 UI - phpStudy...

    IOS中UIWebView的使用详解 一.初始化与三种加载方式 UIWebView继承与UIView,因此,其初始化方法和一般的view一样,通过alloc和init进行初始化,其加载数据的方式有三种 ...

最新文章

  1. 重磅直播 | PointDSC:基于特征匹配的点云配准方法(CVPR2021)
  2. lingo calcinit
  3. NET 2.0中WinForm自定义的程序配置存放到哪里去了
  4. ABAP Debugging Script(调试器脚本)使用的一些实际例子
  5. 调节Win7系统任务栏预览窗口大小的方法
  6. Javascript - 面向对象
  7. java开发工作找不到要放弃吗,这样学习Java,才能找到一份Java开发的工作。不要盲目的学!...
  8. C#之DotfuscatorCommunity
  9. 动态规划算法 dynamic programming
  10. sublime编辑器修改默认的Tab缩进风格
  11. 荣耀/华为电脑安装重新安装电脑管家实现跟华为手机多屏协同(666)
  12. 自然语言处理-聊天机器人
  13. 杰出女吉他大师Muriel Anderson
  14. 全面的关于OLAP数仓总结
  15. 数学脱式计算在线计算机,四年级数学脱式计算练习400题
  16. 在电商平台落地大数据应用的6个场景、2类服务、12个框架
  17. 微信小程序 修改radio样式
  18. 3个5相乘列乘法算式_三年级下册期中数学17个考点专题复习资料
  19. 游戏系统开发设计分享
  20. 如何进行电源干扰及抑制技术?

热门文章

  1. 上古卷轴3晨风职业_上古卷轴3:晨风
  2. Python基础语法总结,Python初学者必备
  3. c++ 类数组_输入输出流IO体系及常用类关系结构(精要收藏)
  4. office插件开发_Visual Studio Code有哪些你常用的插件?
  5. 了解下SOAP Header 元素
  6. unix oracle控制台,Linux平台下启动oracle11gEM控制台
  7. java中字节输入流和输出流的简单使用例子
  8. 树链剖分(轻重链剖分) 讲解 (模板题目 P3384 【模板】轻重链剖分 )
  9. 蓝桥杯国赛-矩阵计数三种解法-java实现
  10. 可视化卷积神经网络的过滤器_万字长文:深度卷积神经网络特征可视化技术(CAM)最新综述...