python c 语言接口,## 人生苦短我用python[0x08] 使用ctypes调用c语言接口 ##
文章內容為原創,歡迎轉載請注明出處
作者: 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')
>>> libc = ctypes.CDLL('libc.so.6')
>>> libc.printf
>>> 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
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
#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
>>> libfoo.foo()
Hello, I'm a shared library27
>>>
具體代碼其實跟3.例子類似,只是因為我們的庫是非系統的,所以要指定絕對路徑而已,字符串最后的27是輸出字符串的長度。
由睿江云提供,想了解更多,請登陸www.eflycloud.com
總結
以上是生活随笔為你收集整理的python c 语言接口,## 人生苦短我用python[0x08] 使用ctypes调用c语言接口 ##的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JSBox 移动端 JavaScript
- 下一篇: 【1】Python 视频文字识别提取 -