如何用Python寫C擴充套件?

2021-09-10 12:17:02 字數 3514 閱讀 4069

1. 環境準備

如果是linux只需要安裝python3.x + python-dev。

windows下稍微複雜點,vs2017 + python3.6.3

vs2017可用社群版,需要選擇安裝的環境如下:

2.1 c模組封裝

以計算兩個數相加為例,選擇任意資料夾,新建如下c語言原始碼:

// 檔名 calc.c

#include

int add(int x, int y)

static pyobject *calc_add(pyobject *self, pyobject *args)

// 模組的方法列表

static pymethoddef calcmethods = ,

};// 模組

static struct pymoduledef calcmodule = ;

// 初始化

pymodinit_func pyinit_calc(void)

其中,靜態函式calc_add 以python的c介面方式封裝了add函式,命名方式 模組名_函式名

靜態pymethoddef列表變數 calcmethods 包含了該模組方法的描述

靜態struct pymoduledef結構體變數 calcmodule 定義了模組的描述

pyinit_calc函式初始化了模組,命名方式 pyinit_模組名

2.2 c原始碼編譯

在vs2017中可以直接生成 .dll 檔案,然後改名為 .pyd 就可在python程式中引入該模組了,但是,這不"清真",正確的姿勢是寫乙個 setup.py然後通過python調cl.exe編譯。

新建 setup.py檔案,內容如下:

# setup.py

from distutils.core import setup, extension

module1 = extension('calc',

sources=['calc.c'])

setup(name='calc_model',

version='1.0',

description='hello ?',

ext_modules=[module1]

)

然後,從windows的命令列(命令提示符)下進入到這個資料夾下,執行:

python setup.py build

即可完成編譯,如果出現某 .bat檔案未找到,說明你的vs沒有安裝相應的依賴(linux下編譯不成功原因可能是沒有裝python-dev),按文章開頭給出的依賴庫新增修改(此時不需要重新安裝vs)。

編譯結束後,在該資料夾下會出現build資料夾,進入該資料夾,出現如下兩個資料夾:

進入lib.***那個資料夾,裡面有個.pyd結尾的檔案(linux下為.so結尾),這就是我們編譯好的python模組了,如下:

當然,你也可以改名為calc.pyd比較好看,不過這不影響呼叫。

2.3 python呼叫

這部分就簡單了,進入含有編譯好的.pyd資料夾,新建如下檔案:

import calc

print(calc.add(12, 21))

這就是乙個普通庫,這樣呼叫就ok了。

3. python的引數傳遞以及c的返回值相關問題

這部分我直接甩出檔案就行,編譯及呼叫過程與上面一樣。

c 檔案

/**構建返回值

py_buildvalue("") none

py_buildvalue("i", 123) 123

py_buildvalue("iii", 123, 456, 789) (123, 456, 789)

py_buildvalue("s", "hello") 'hello'

py_buildvalue("y", "hello") b'hello'

py_buildvalue("ss", "hello", "world") ('hello', 'world')

py_buildvalue("s#", "hello", 4) 'hell'

py_buildvalue("y#", "hello", 4) b'hell'

py_buildvalue("()") ()

py_buildvalue("(i)", 123) (123,)

py_buildvalue("(ii)", 123, 456) (123, 456)

py_buildvalue("(i,i)", 123, 456) (123, 456)

py_buildvalue("[i,i]", 123, 456) [123, 456]

py_buildvalue("", "abc", 123, "def", 456)

py_buildvalue("((ii)(ii)) (ii)", 1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))

**/#include

static pyobject *value_commonargs(pyobject *self, pyobject *args)

static pyobject *value_tupletest(pyobject *self, pyobject *args)

static pyobject *value_some(pyobject *self, pyobject *args){

/* 可選引數,可能是下面幾種, "|" 代表後面的引數可選

c 寫php擴充套件,如何用C語言編寫PHP擴充套件的詳解

1 預定義 在home目錄,也可以其他任意目錄,寫乙個檔案,例如caleng module.def 內容是你希望定義的函式名以及引數 int a int x,int y string b string str,int n 2 到php原始碼目錄的ext目錄 cd usr local php 5.4....

如何用VSCode愉快的寫Python

在學習python的過程中,一直沒有找到比較趁手的第三方編輯器,用的最多的還是python自帶的編輯器。由於本人用慣了宇宙第一ide visual studio 所以當visual studio code出現時,心情有點小激動呢。從我的使用經驗出發,可以說vscode用來寫python真的是再合適不...

如何用vuetify寫表單

菜鳥本人最近在用vuetify寫登入註冊頁面,這個ui強大但是難用,很難自己調整到滿意的程度。我琢磨了好久,寫出了乙個粗糙的註冊頁面 clear both mx auto my 16 max width 600 min width 300 shaped mx auto my 16 ref form ...