## 人生苦短我用python[0x08] 使用ctypes调用c语言接口 ##
2017-07-17 00:00
603 查看
<font color=red>文章内容为原创,欢迎转载请注明出处</font>
作者: EflyPro->晦明禅师
简单解析一下上面的几行代码,我们知道printf函数是c语言基础库,放在libc.so文件里面,以例子所在Ubuntu 16.04 x64 Server,具体路径是 /lib/x86_64-linux-gnu/libc.so.6,首先是用ctypes加载对应的so文件,因为libc是系统基础库文件,所以不用指定绝对路径,加载完之后就实例化libc的对象,比如程序的libc,然后就可以调用libc里面的printf函数了。根据printf的函数原型,除了输出字符信息之外,还返回输出信息的长度,所以我们看到除了输出hello world!之外,下面返回的14就是字符串的长度。
foo.h
foo.c
编译foo so动态库
一切顺利的话,当前目录下会有一个libfoo.so的动态库文件,下面我们写一个main.c的程序测试一下这个libfoo.so库
main.c
编译main.c文件
一切顺利之后会产生test的执行文件,我们执行它,不过执行之前我们先要定义一下系统库路径,要不执行test的时候系统会提示找不到库文件
顺利输出信息。我们知道我们的libfoo.so是正常可用的,那么我们就写一个python程序去调用我们的libfoo里面的foo函数接口。
main.py
具体代码其实跟3.例子类似,只是因为我们的库是非系统的,所以要指定绝对路径而已,字符串最后的27是输出字符串的长度。
由睿江云提供,想了解更多,请登陆www.eflycloud.com
作者: EflyPro->晦明禅师
1.背景
python作为解析语言大规模应用在各个领域,c语言作为系统级别的语言广泛应用在基础,系统,网络等底层服务当中,可以说python和c语言之间各有擅长和不擅长的地方,今天文章讨论的是,如何使用python开发的程序调用c语言写的库文件,使得两种语言得以互补。2.ctypes
ctypes是python自带的用于跟c语言做对接的库,里面提供了针对c语言数据类型,除此还提供了加载动态库和调用动态库函数的功能,比如在windows下可以加载dll文件并可以调用里面的函数接口,在linux下可以加载so文件调用里面的函数接口。3.例子
我们使用ctypes库,调用c语言经常用到的printf函数作为一个简单的例子,下面是具体python代码>>> import ctypes >>> ctypes.cdll.LoadLibrary('libc.so.6') <CDLL 'libc.so.6', handle 7f7495ee59b0 at 7f7495d5c850> >>> libc = ctypes.CDLL('libc.so.6') >>> libc.printf <_FuncPtr object at 0x7f7495d30c80> >>> libc.printf("hello %s\n", "world!") hello world! 13 >>>
简单解析一下上面的几行代码,我们知道printf函数是c语言基础库,放在libc.so文件里面,以例子所在Ubuntu 16.04 x64 Server,具体路径是 /lib/x86_64-linux-gnu/libc.so.6,首先是用ctypes加载对应的so文件,因为libc是系统基础库文件,所以不用指定绝对路径,加载完之后就实例化libc的对象,比如程序的libc,然后就可以调用libc里面的printf函数了。根据printf的函数原型,除了输出字符信息之外,还返回输出信息的长度,所以我们看到除了输出hello world!之外,下面返回的14就是字符串的长度。
4.实战
上面3的例子是调用系统自带的库,下面我们自己尝试用c语言编写一个动态库,然后使用ctypes调用里面的函数接口。我们先用c语言编写一个最简单的库,然后这个库里面只有一个函数接口。foo.h
#ifndef foo_h__ #define foo_h__ extern void foo(void); #endif // foo_h__
foo.c
#include <stdio.h> void foo(void) { printf("Hello, I'm a shared library"); }
编译foo so动态库
gcc -c -Wall -Werror -fpic foo.c gcc -shared -o libfoo.so foo.o
一切顺利的话,当前目录下会有一个libfoo.so的动态库文件,下面我们写一个main.c的程序测试一下这个libfoo.so库
main.c
#include <stdio.h> #include "foo.h" int main(void) { printf("This is a shared library test..."); foo(); return 0; }
编译main.c文件
#这里需要用-L参数告诉gcc我们的so库所在目录,要不gcc会找不到我们的库 gcc -L/tmp/test -Wall -o test main.c -lfoo
一切顺利之后会产生test的执行文件,我们执行它,不过执行之前我们先要定义一下系统库路径,要不执行test的时候系统会提示找不到库文件
export LD_LIBRARY_PATH=/tmp/test:$LD_LIBRARY_PATH ./test
顺利输出信息。我们知道我们的libfoo.so是正常可用的,那么我们就写一个python程序去调用我们的libfoo里面的foo函数接口。
main.py
>>> import ctypes >>> ctypes.cdll.LoadLibrary('/tmp/test/libfoo.so') >>> libfoo = ctypes.CDLL('libfoo.so') >>> libfoo = ctypes.CDLL('/tmp/test/libfoo.so') >>> libfoo <CDLL '/tmp/test/libfoo.so', handle f10de0 at 7f7495d46750> >>> libfoo.foo() Hello, I'm a shared library27 >>>
具体代码其实跟3.例子类似,只是因为我们的库是非系统的,所以要指定绝对路径而已,字符串最后的27是输出字符串的长度。
由睿江云提供,想了解更多,请登陆www.eflycloud.com
相关文章推荐
- (原)python使用ctypes调用C/C++接口
- Linux使用Python调用C/C++接口
- Python使用ctypes调用C函数传参处理
- 使用c语言调用python小结
- python学习笔记--使用ctypes调用C函数
- Python:使用ctypes库调用外部DLL(转)
- 使用boost.python在python调用C++接口(windows)
- 深度学习(caffe+VS2013+WIN10)使用GPU编译——调用python接口并且成功运行mnist
- Python:使用ctypes库调用外部DLL
- 使用c语言调用python小结
- Python 使用库ctypes调用C代码接口
- Python调用ctypes使用C函数printf
- Python接口(1):使用Python调用C/C++的种种方法
- python使用suds调用webservice接口
- Python:使用ctypes库调用外部DLL(转)
- Python 使用ctypes调用 C 函数
- Python接口(2):使用ctpyes模块在python中调用c++代码
- 【转】Python调用ctypes使用C函数printf
- 使用c语言调用python小结
- python使用ctypes模块调用windowsapi获取系统版本示例