Python調用c庫學習
Python模塊ctypes是Python內建的用於調用動態鏈接庫函數的功能模塊,一定程度上可以用於Python與其他語言的混合編程。由於編寫動態鏈接庫,使用C/C++是最常見的方式,故ctypes最常用於Python與C/C++混合編程之中。
一、ctypes原理及優缺點
從ctypes的文檔中可以推斷,在各個平臺上均使用了對應平臺動態加載動態鏈接庫的方法,並通過一套類型映射的方式將Python與二進制動態鏈接庫相連接。在Windows平臺下,最終調用的是Windows API中LoadLibrary函數和GetProcAddress函數,在Linux和Mac OS X平臺下,最終調用的是Posix標準中的dlopen和dlsym函數。ctypes 實現了一系列的類型轉換方法,Python的數據類型會包裝或直接推算爲C類型,作爲函數的調用參數;函數的返回值也經過一系列的包裝成爲Python類型。也就是說,PyObject* <-> C types的轉換是由ctypes內部完成的。
ctypes 有以下優點:
· Python內建,不需要單獨安裝
· 可以直接調用二進制的動態鏈接庫
· 在Python一側,不需要了解Python內部的工作方式
· 在C/C++一側,也不需要了解Python內部的工作方式
· 對基本類型的相互映射有良好的支持
ctypes 有以下缺點:
· 平臺兼容性差
· 不能夠直接調用動態鏈接庫中未經導出的函數或變量(理解爲不能直接調用當前so中包含的其他so文件中的函數)
· 對C++的支持差
二、一個簡單的demo
1)、實現test_ctypes.c文件,內容如下:
#include <stdio.h>
int sum(int a,int b)
{
return a+b;
}
int main()
{
print("hello ctypes!sum:%d\n",sum(1,2));
return 0;
}
2)、編譯爲動態so庫:
gcc -fPIC -shared test_ctypes.c -o test_ctypes.so
3)、在python中調用sum函數或者main函數
so相互依賴問題的解決:
so相互依賴時使用RTLD_LAZY標誌加載so庫,先不解析未找到的symbol;後續在調用到這些symbol時會全局搜素,找得到就會調用。
import ctypes
#此處如果出現so之間的相互依賴關係,可以參考是用dlopen的RTLD_*相關的flag,如mode=1|RTLD_GLOBAL
test=ctypes.CDLL("test_ctypes.so")
test.main()