你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

C語(yǔ)言是編程語(yǔ)言的祖母,但是隨著一代一代的編程語(yǔ)言長(zhǎng)大,所以祖母也是會(huì)拍在沙灘上的,很多小小伙伴應(yīng)該都會(huì)學(xué)過(guò)或者了解C語(yǔ)言,因?yàn)檐浖档臅?huì)教嘛,但是Python我想很多人都沒(méi)學(xué)過(guò),下面小編給大家介紹下,C語(yǔ)言和Python一起混合編程會(huì)產(chǎn)生什么不一樣的火花吧!

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

在Mac OS X 下的編譯命令同上

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

產(chǎn)生可執(zhí)行文件后,直接運(yùn)行,結(jié)果為輸出

1

2

Hello Python!

Python庫(kù)函數(shù)PyRun_SimpleString可以執(zhí)行字符串形式的Python代碼。

雖然非常簡(jiǎn)單,但這段代碼除了能用C語(yǔ)言動(dòng)態(tài)生成一些Python代碼之外,并沒(méi)有什么用處。我們需要的是C語(yǔ)言的數(shù)據(jù)結(jié)構(gòu)能夠和Python交互。

下面舉個(gè)例子,比如說(shuō),有一天我們用Python寫(xiě)了一個(gè)功能特別強(qiáng)大的函數(shù):

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

從上述代碼可以窺見(jiàn)Python內(nèi)部運(yùn)行的方式:

現(xiàn)在我們得到了一個(gè)C語(yǔ)言的函數(shù)了,可以寫(xiě)一個(gè)main測(cè)試它

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

編譯的方式就用本節(jié)開(kāi)頭使用的方法。

在Linux/Mac OSX運(yùn)行此示例之前,可能先需要設(shè)置環(huán)境變量:

bash:

1

2

export PYTHONPATH=.:$PYTHONPATH

csh:

1

2

setenv PYTHONPATH.:$PYTHONPATH

2 Python 調(diào)用 C/C++(基礎(chǔ)篇)

這種做法稱(chēng)為Python擴(kuò)展。

比如說(shuō),我們有一個(gè)功能強(qiáng)大的C函數(shù)

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

除了功能強(qiáng)大的函數(shù)great_function外,這個(gè)文件中還有以下部分:

在Windows下面,在Visual Studio命令提示符下編譯這個(gè)文件的命令是

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

本部分參考資料

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

這其中有非Python關(guān)鍵字cdef和public。這些關(guān)鍵字屬于Cython。由于我們需要在C語(yǔ)言中使用“編譯好的Python代碼”,所以得讓great_function從外面變得可見(jiàn),方法就以“public”修飾。而cdef類(lèi)似于Python的def,只有使用cdef才可以使用Cython的關(guān)鍵字public。

這個(gè)函數(shù)中其他的部分與正常的Python代碼是一樣的。

接下來(lái)編譯 great_module.pyx

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

編譯命令和第一部分相同:

在Windows下編譯命令為

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

在Visual Studio命令提示符下編譯:

1

2

cl/LD dllmain.cgreat_module.c-IC:Python27includeC:Python27libspython27.lib

會(huì)得到一個(gè)dllmain.dll。我們?cè)贓xcel里面使用它,沒(méi)錯(cuò),傳說(shuō)中的Excel與Python混合編程:

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

參考資料:Cython的官方文檔,質(zhì)量非常高:

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

接下來(lái)使用SWIG將這個(gè)配置文件編譯為所謂Python Module Wrapper

1

2

swig-python mymodule.i

得到一個(gè) mymodule_wrap.c和一個(gè)mymodule.py。把它編譯為Python擴(kuò)展:

Windows:

1

2

cl/LD mymodule_wrap.c/o_mymodule.pyd-IC:Python27includeC:Python27libspython27.lib

Linux:

1

2

gcc-fPIC-shared mymodule_wrap.c-o_mymodule.so-I/usr/include/python2.7/-lpython2.7

注意輸出文件名前面要加一個(gè)下劃線。

現(xiàn)在可以立即在Python下使用這個(gè)module了:

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

換句話說(shuō),SWIG自動(dòng)完成了諸如Python類(lèi)型轉(zhuǎn)換、module初始化、導(dǎo)出代碼表生成的諸多工作。

對(duì)于C++,SWIG也可以應(yīng)對(duì)。例如以下代碼有C++類(lèi)的定義:

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

你試過(guò)C語(yǔ)言和Python一起混合編程嗎??jī)烧呦嗉硬皇且呀?jīng)無(wú)敵了!

寫(xiě)在最后:

由于CPython自身的結(jié)構(gòu)設(shè)計(jì)合理,使得Python的C/C++擴(kuò)展非常容易。如果打算快速完成任務(wù),Cython(C/C++調(diào)用Python)和SWIG(Python調(diào)用C/C++)是很不錯(cuò)的選擇。但是,一旦涉及到比較復(fù)雜的轉(zhuǎn)換任務(wù),無(wú)論是繼續(xù)使用Cython還是SWIG,仍然需要學(xué)習(xí)Python源代碼。