概述
引入 python.h 標頭檔案
編寫包裝函式
處理從 python 傳入的引數
實現邏輯功能
處理 c 中的返回值
註冊函式
註冊模組
編譯原文發於2023年11月。
python 可以非常方便地和 c 進行相互的呼叫。
一般,我們不會使用 c 去直接編寫乙個 python 的模組。通常的情景是,我們需要把 c 的相關模組包裝一下,然後在 python 中可以直接呼叫它。或者是,把 python 邏輯中的某一效率要求很高的部分使用 c 來實現。整個過程大概是:
引入 python.h 標頭檔案。
編寫包裝函式。
函式中處理從 python 傳入的引數。
實現功能邏輯。
處理 c 中的返回值,包裝成 python 物件。
在乙個 pymethoddef 結構體中註冊需要的函式。
在乙個初始化方法中註冊模組名。
把這個 c 原始檔編譯成鏈結庫。
int
add(
intx
,inty)
//int main(void)
#include
static
pyobject
*w_add
(pyobject
*self
,pyobject
*args
)else
}static
pymethoddef
extendmethods
=,,};
pymodinit_func
initdemo
()
這個檔案一般位於 python 的主目錄中。比如我的 ubuntu 10.04 下,它的位置在:
/usr/
include
/python2
.6
在最後編譯的時候指定目錄就可以了。
因為 python 用到的函式與普通的 c 函式,在輸入和輸出上,會有一些不同,所以,我們需要把普通的 c 做一些封來給 python 用。
從另一方面來說,在實現功能的過程中,我們可以先完全不考慮這東西是拿給 python 用的,只專注於使用 c 把它寫好就可以了。最後,功能寫好,測試沒有問題之後,再做 python 封裝的工作。
包裝函式一般宣告成 static ,並且第乙個引數是乙個預設傳入的 python 物件,就是 python 中某個物件的屬性方法一樣,第二個引數才是我們呼叫時傳入的引數(實際上它是乙個序列化後的字串):
static
pyobject
*w_add
(pyobject
*self
,pyobject
*args
);
因為我們的相關函式,之後是在 python 環境中被呼叫的,那麼它顯然接受的就是從 python 環境下傳入的引數。這和 c 中你看到的函式是不同的,在 python 的世界中,一切都是物件。所以,包裝函式中首先要處理的問題就是解析從 python 佔獲取的引數。
常用的函式有: pyarg_parsetuple
intx;
inty
;pyarg_parsetuple
(args
,"i|i",&
x,&y
);
pyarg_parsetuple 的作用是解析我們從 python 中傳入的 args 這個字串,然後以我們規定的格式將解析結果放入指定變數的記憶體位。
" i|i " 就表示要把傳入的東西解析成兩個整數,同樣,還有 s 表示字串等。
這部分沒什麼特別的,只需要在 c 中一樣呼叫函式就可以了,相關變數我們已經在上一步處理過了。
add(x
,y);
我們使用 c 完成了功能邏輯, c 中會產生乙個返回值,要將這個值返回到我們之前呼叫函式的 python 環境中,當然還需要經過一些處理才行。
常用的函式是: py_buildvalue 。
return
py_buildvalue
("i"
,add(x
,y));
這個函式的用法和上一步中的 pyarg_parsetuple 是一樣的,它們過程相反。 py_buildvalue 把 c 中的值按給定的格式格式化成 python 需要的物件。這裡注意一下,對於 w_add 這個函式,我們可是宣告了它的返回型別為 pyobject* 的哦。
在上面的實現完成之後,就需要作匯出的準備了。第一步,就是要在乙個型別為 pymethoddef 的結構體中註冊我們需要匯出到 python 中的函式:
static
pymethoddef
extendmethods
=,,}
這個結構體成員有四個函式:
" add " 匯出後在 pyhton 中可見的方法名。
w_add 實際對映到 c 中的方法名。
此方法的注釋。
在註冊了方法後,就要註冊此模組了。方法是定義乙個 init* 的函式:
pymodinit_func
initdemo
()
方法名必須是 init 加上模組名,然後呼叫 py_initmodule 來註冊模組,這個函式的第乙個引數就是模組名,第二個引數是此模組中我們匯出的方法,就是上一步我們定義的結構體。
最後一步就是編譯了。沒什麼特別的,指定好 python.h 標頭檔案的位置就可以了:
gcc demo.c
-i /usr
/include
/python2.6
-shared
-o demo
.so
當然,鏈結庫的名字要和我們期望匯出的模組名一致。
這樣,你就可以在 python 中使用 import 直接引入 demo 模組,然後呼叫它的 add 方法了:
import
demo
demo
.add(3
,4)
c寫python庫 c寫python模組擴充套件
結構 xorcrypt 0.2 setup.py xorcrypt2.c readme setup.py usr bin python from distutils.core import setup,extension version 0.2 macros module version s ver...
python使用argparse模組寫命令列內容
寫命令python和c是有很大區別的。c可以通過mian函式,而python可以通過呼叫內建模組。import argparse parse argparse.argumentparser parse.add argument bug feature help file that only cont...
Python學習 測試和使用自己寫的模組
首先我們先自己寫乙個模組,並且可以執行當前檔案時測試該模組是否正常。usr bin env python3 coding utf 8 a test module author csdn author deftest1 print hello,test1 deftest2 print hello,te...