Python利用ctypes实现C库函数调用
0X00
ctypes 是强大的,使用它我们就能够调 用动态链接库中函数,同时创建各种复杂的 C 数据类型和底层操作函数。使得python也具备了底层内存操作的能力,再配合python本身强大的表达能力,这才知道为什么python是黑客必学的编程语言。
0x01 ctypes使用
ctypes 提供了三种方法调用动态链接库:cdll(), windll(), 和 oledll()。
它们的不同之处就在 于,函数的调用方法和返回值。cdll() 加载的库,其导出的函数必须使用标准的 cdecl 调用约定。
windll()方法加载的库,其导出的函数必须使用 stdcall 调用约定(Win32API 的原生约 定)。
oledll()方法和 windll()类似,不过如果函数返回一个 HRESULT 错误代码,可以使用 COM 函数得到具体的错误信息。
0X02 调用约定
调用约定专指函数的调用方法。其中包括,函数参数的传递方法,顺序(压入栈或 者传给寄存器),以及函数返回时,栈的平衡处理。
下面这两种约定是我们最常用到的: cdecl and stdcall。
cdecl 调用约定: 函数的参数从右往左依次压入栈内,函数的调用者, 在函数执行完成后,负责函数的平衡。这种约定常用于 x86 架构的 C 语言里。
In C
int python_rocks(reason_one,reason_two,reason_three);
In x86 Assembly
push reason_three
push reason_two
push reason_one
call python_rocks
add esp,12
从上面的汇编代码中,可以清晰的看出参数的传递顺序,最后一行,栈指针增加了 12 个字节(三个参数传递个函数,每个被压入栈的指针都占 4 个字节,共 12
个), 使得 函数调用之后的栈指针恢复到调用前的位置。
stdcall调用约定:参数传递的顺序也是从右到左,不过栈的平衡处理由函数 my_socks 自己完成,而不是调用者。
In C
int my_socks(color_onecolor_two,color_three);
In x86 Assembly
push color_three
push color_two
push color_one
call my_socks
最后一点,这两种调用方式的返回值都存储在 EAX 中。
0x03 使用方法
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)
使用 Python 创建一个 C数据类型很简单,可以很容易的使用由C或者C++些的组件。 下面这张图很好的表示了映射关系。

0x04 定义结构和联合
In C
union
{
long barley_long;
int barley_int;
char barley_char[8];
}barley_amount;
In Python
class barley_amount(Union):
_fields_ = [
("barley_long", c_long),
("barley_int", c_int),
("barley_char", c_char * 8),
]
eg:
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
输出结果:
Enter the amount of barley to put into the beer vat:66
Barley amount as a long: 66
Barley amount as an int: 66
Barley amount as a char: B
给联合赋一个值就能得到三种不同的表现方式。最后一个 barley_char 输出的结果是 B, 因为 66 刚好是 B 的 ASCII 码。
barley_char 成员同时也是个数组,一个八个字符大小的数组。在 ctypes 中申请一个数组, 只要简单的将变量类型乘以想要申请的数量就可以了。
Python利用ctypes实现C库函数调用的更多相关文章
- Python利用ctypes实现按引用传参
C的代码 void test_cref(char *a, int *b, char *data) { , sizeof(char)); strcpy(p, "cute"); a[] ...
- python利用or在列表解析中调用多个函数.py
python利用or在列表解析中调用多个函数.py """ python利用or在列表解析中调用多个函数.py 2016年3月15日 05:08:42 codegay & ...
- 通过实例简介python使用ctypes模块调用C语言动态库
看介绍python语言时,说它是胶水语言,可以调用其他语言.通过使用ctypes模块就可以调用C语言的动态库.下面先放上官方文档和几个比较好的博文. 1.官方文档:http://python.net/ ...
- [Python] 利用Django进行Web开发系列(二)
1 编写第一个静态页面——Hello world页面 在上一篇博客<[Python] 利用Django进行Web开发系列(一)>中,我们创建了自己的目录mysite. Step1:创建视图 ...
- python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie)
python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie) 主要包括两部分内容:(1)利用python中的dict实现Trie:(2) ...
- python 利用栈实现复杂计算器
#第五周的作业--多功能计算器#1.实现加减乘除及括号的优先级的解析,不能使用eval功能,print(eval(equation))#2.解析复杂的计算,与真实的计算器结果一致#用户输入 1 - 2 ...
- Linux系统调用和库函数调用的区别
Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).系统调用实际上就是指最底层的一个调用,在linux程序设计里面就是底层调用的意思 ...
- linux系统调用和库函数调用的区别(转)
Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).可以参考<Linux程序设计>(英文原版为<Beginning ...
- python 利用 ogr 写入shp文件,数据格式
python 利用 ogr 写入 shp 文件, 定义shp文件中的属性字段(field)的数据格式为: OFTInteger # 整型 OFTIntegerList # 整型list OFTReal ...
随机推荐
- CODING 项目协同 2.0 —— 让协作有条不紊
本文为 CODING 高级产品经理王海明 在腾讯云 CIF 工程效能峰会上所做的分享.文末可前往峰会官网,观看回放并下载 PPT. 大家好,我是 CODING 高级产品经理王海明,今天与大家分享的是项 ...
- JDK源码阅读(7):ConcurrentHashMap类阅读笔记
ConcurrentHashMap public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implement ...
- html+css第七篇-表格
表格标签: table 表格 thead 表格头 tbody 表格主体 tfoot 表格尾 tr 表格行 th 元素定义表头 td 元素定义表格单元 表格样式重置 table{border-colla ...
- 32、最长有效括号 | 算法(leetode,附思维导图 + 全部解法)300题
零 标题:算法(leetode,附思维导图 + 全部解法)300题之(32)最长有效括号 一 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: // 方案1 "滑动窗 ...
- [Noip 2012]同余方程(线性同余方程)
我们先放题面-- RT就是求一个线性同余方程ax≡1(mod b)的最小正整数解 我们可以将这个同于方程转换成这个方程比较好理解 ax=1+bn(n为整数 我们再进行一个移项变为ax-bn=1 我们设 ...
- 【洛谷1340】兽径管理(最小生成树 Kruskal)(sort的一些技巧)【2012福建省信息学奥林匹克CCF NOIP夏令营第05天训练】
Description 约翰农场的牛群希望能够在 N 个(1<=N<=6000) 草地之间任意移动.草地的编号由 1到 N.草地之间有树林隔开.牛群希望能够选择草地间的路径,使牛群能够从任 ...
- [省选联考 2021 A/B 卷] 卡牌游戏
垃圾福建垫底选手来看看这题. 大家怎么都写带 \(log\) 的. 我来说一个线性做法好了. 那么我们考虑枚举 \(k\) 作为翻转完的最小值. 那么构造出一个满足条件的操作,我们在 \(a_i\) ...
- Codeforces 1225G - To Make 1(bitset+状压 dp+找性质)
Codeforces 题目传送门 & 洛谷题目传送门 还是做题做太少了啊--碰到这种题一点感觉都没有-- 首先我们来证明一件事情,那就是存在一种合并方式 \(\Leftrightarrow\) ...
- Docker将容器制作成镜像并提交到远程仓库
Docker将容器制作成镜像并提交到远程仓库 步骤如下 先在dockerhub上创建一个自己的用户https://hub.docker.com/.或者在阿里云也可以. 2. 然后先创建一个空的镜像名. ...
- Linux生产应用常见习题汇总
1.如果想修改开机内核参数,应该修改哪个文件? C A./dev/sda1 (scsi sata sas,是第1块盘的第1个分区) B./etc/fstab (开机磁盘自动挂载配置文件) C./etc ...