python調用c模塊
在函數聲明加入前綴,如
__declspec(dllexport) int Fun(int a, int b)
否則在載入該dll時會提示找不到該符號
在windows下可以通過vs自帶的mpbin工具查看可被調用符號
mpbin /exports test.dll
C函數在調用過程中關於參數傳遞和壓棧由多種規定,作為dll提供給其他程序調用時,必須明確並統一為同一種調用規定,否則會導致棧破壞,編譯器負責具體實現調用規定,主要有以下幾種調用規定
python下調用C庫有多種方式,ctypes是其中一種比較方便的,調用時首先需要載入dll文件,根據C dll的調用規定不同需要使用不同介面,使用ctypes需要 import ctypes 庫
對於簡單的C函數,例如 int add(int a, int b) , 此時就可以直接調用了,如
對於較復雜的C函數的參數情況,ctypes調用時對入參和出餐做一定處理,這里分情況討論
以上包含了幾種主要的參數傳遞情況,ctypes也提供了一個較為完整的python類型和C類型的對照,如下:
2. 如何讓python調用C和C++代碼
要搞明白如何讓python調用C/C++代碼(也就是寫python的extension),你需要征服手冊中的<<Extending && embedding>>厚厚的一章。在昨天花了一個小時看地頭暈腦脹,仍然不知道如何寫python的extension後,查閱了一些其他書籍,最終在<<Python Programming On Win32>>書中找到了教程。
1. 首先要明白的是,所謂的python擴展(也就是你提供給python的c/c++代碼,不一定是c/c++代碼,可以是其他語言寫的代碼)是一個dll,並且這個dll放在本機python安裝目錄下的DLLs目錄下(譬如我機器上的路徑是:F:/Program Files/Python25/DLLs),假如我們接下來要寫的擴展mole名為mb,python調用的代碼為:import mbmb.showMsg("Python's really amazing, I kindda love it!")
2. 搭建環境,我們要使用python提供的c頭文件和lib庫來進行擴展的開發。
在vs 2005下點擊菜單 "工具"->"選項", 打開選項對話框,選擇"項目和解決方案->VC++目錄", 然後在右邊"顯示以下內容的目錄"得comboBox上選擇"包含文件」,添加python的include目錄(我的機器上是"F:/Program Files/Python25/include"),然後選擇庫文件,添加python的libs目錄(我的機器上是"F:/Program Files/Python25/libs")。
既然擴展是一個dll,接下來我們要建立一個「動態鏈接庫」工程,然後開始寫代碼:
#include <python.h> //python.h是包含python一些定義的頭文件,在python的include目錄下/*我的python版本是2.5, 因為安裝python後它沒提供debug下的lib庫文件,因此你必須生成release版的dll,
想要生成dll版本的,你要到python官網上自己去下載python源代碼,當然你可以繼續生成release版本的dll,但dll中包含調試信息*/#pragma comment(lib, "python25.lib")//先不管static PyObject* mb_showMsg(PyObject* self, PyObject *args);/*如果你的擴展是mb,那麼必須實現一個initmb函數,並且從dll中導出這個函數,但我們在python中調用import mb時,python會去dll里去調用
extern "C" __declspec(dllexport) void initmb(){/*當調用mb.showMsg("Python's really amazing, I kindda love it!")時, 相當於你告訴python我有一個showMsg函數,我們怎麼告訴python去調用我們dll里的mb_showMsg函數呢?技巧就是下面的方式,定義一個字典數據結構,key => showMsg, value =>mb_showMsg,METH_VARARGS是函數調用方式,仔細查手冊吧*/static PyMethodDef mbMethods[] = {
{"showMsg", mb_showMsg, METH_VARARGS},
{NULL, NULL, NULL} /*sentinel,哨兵,用來標識結束*/};//告訴python我們的模塊名叫mb, 模塊包含的函數都在mbMethods字典里
PyObject *m = Py_InitMole("mb", mbMethods);}/*接下來實現核心功能showMsg*///第一個self參數我們用不著,具體查手冊,第二個參數是python傳給我們的參數,它是一個python的參數tuple
static PyObject* mb_showMsg(PyObject* self, PyObject *args){//我們的showMsg函數需要的是一個字元串參數
const char* msg = NULL;/*調用特殊參數解碼python傳遞給我們的參數,s是string,我們傳遞接收參數的變數地址,
如果你的功能函數需要兩個參數,在PyArg_parseTuple後面繼續添加接受參數的變數地址,
這個函數的原型是類似printf的不定參數的形式
PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);*/if (!PyArg_ParseTuple(args, "s", &msg))
return NULL;//調用MBint r = ::MessageBox(NULL, "hello", "Caption:Form C mole", MB_ICONINFORMATION | MB_OK);//返回值return Py_BuildValue("i", r);}將上面這段混雜著大量注釋的代碼拷貝到你的編輯器里,然後編譯生成mb.dll,修改後綴成mb.pyd,然後拷貝到python的DLLs目錄下,打開idle(python的交互程序),寫入代碼:import mbmb.showMsg("Python's really amazing, I kindda love it!")
3. python作業如果要調用abc模塊的c函數,正確的書寫格式應該為什麼
import abc #導入模塊
abc.c() #調用函數
4. 為什麼python可以調用C或者C++寫的模塊
Python的API(應用程序編程介面)定義了一系列的函數、宏指令和變數 來與Python的運行系統的大部分方面進行連接通信,而通常來說,用c語言編寫的Python API 會在程序文檔里添加「python.h」作為頭文件。
按我的理解來說就像Python把一個值交給運行系統,然後運行系統把這個值轉化成C語言能夠識別的值,然後交到C語言模塊去做運算,運算好了把結果值交給Python的運行系統,處理成Python能夠識別的值。
你不妨看看這幾個網頁:
http://hi..com/softguarder/blog/item/c3dc8b02b44cec80d43f7c57.html
http://docs.python.org/extending/extending.html#a-simple-example
http://hi..com/softguarder/blog/item/c3dc8b02b44cec80d43f7c57.html
5. 怎樣把Python代碼嵌入到C程序
步驟1:安裝Python開發包
由於需要訪問Python/C API,首先安裝Python開發包。
在Debian,Ubuntu或Linux Mint中:
在CentOS,Fedora或RHEL中:
安裝成功後,Python頭文件在/usr/include/python2.7。根據Linux發行版的不同,確切的路徑可能是不相同的。例如,CentOS 6中是/usr/include/python2.6。
步驟2:初始化解釋器並設置路徑
C中嵌入Python的第一步是初始化Python解釋器,這可以用以下C函數完成。
初始化解釋器後,需要設置你的C程序中要導入的Python模塊的路徑。例如,比如你的Python模塊位於/usr/local/moles。然後使用以下C函數調用來設置路徑。
步驟3:數據轉換
C中嵌入Python最重要的方面之一是數據轉換。從C中傳遞數據到Python函數,需要首先將數據從C數據類型轉換到Python數據類型。Python/C API提供各種函數來實現這。例如,轉換C字元串到Python字元串,使用PyString_FromString函數。
另外一個類似函數PyInt_FromLong,將C中long數據類型轉換為Python int。每個Python/C API函數返回一個PyObject類型的引用。
步驟4:定義一個Python模塊
當你想嵌入Python代碼到另一種語言如C,該代碼需要被寫成Python模塊,然後用另一種語言「導入」。所以讓我們來看看如何在C中導入Python模塊。
為了進行說明,我們實現一個簡單的Python模塊例子如下:
以上的Python函數有一個字元串作為參數並返回兩個重復的字元串。例如,如果輸入字元串是「cyberpersons」,該函數返回'cyberpersonscyberpersons'。此模塊文件命名為「printData.py」並將它放在前面聲明的Python模塊目錄中(/usr/local/moles)。
步驟5:載入一個Python模塊
現在你已經定義了Python模塊,是時候在C程序中載入它了。導入模塊的C代碼看起來像這樣:
步驟6:構建函數的參數
當載入一個模塊時,可以調用模塊中定義的Python函數。通常,我們需要傳遞一個或多個參數到一個Python函數。我們必須構建一個Python元組對象,它包括Python函數中的參數。
在我們的例子中,printData函數定義帶一個參數的模塊。因此,我們構建一個大小是一的Python元組對象如下。我們可以使用PyTuple_SetItem設置元組對象的每個項。
我們已經成功構建一個參數傳遞到函數調用,是時候從C程序調用python函數了。
步驟7:調用Python函數
一旦成功創建Python元組對象作為函數參數,我們可以調用一個帶參數的Python函數。為此,通過使用PyObject_GetAttrString首先獲得模塊中定義的函數的引用,然後使用PyObject_CallObject調用該函數。例如:
步驟8:錯誤檢查
避免運行時錯誤的常見方法是檢查函數的返回值並根據返回值採取適當的行動。類似於C程序中的全局變數errno,Python/C API提供一個全局指示符,它報告最後發生的錯誤。當Python/C API函數失敗,全局指示符設置為指示錯誤,並且PyErr_Print可以用於顯示相應的人類可讀的trackback。例如:
在你的應用程序中,你可以輕松地將各種錯誤檢查。
這里是完整的C程序,它如本教程描述的嵌入Python代碼。
步驟9:編譯和執行
保存以上代碼到finalCode.c,並且鏈接Python庫(-lpython2.7)編譯該代碼。根據發行版的不同,可能使用不同的版本(例如,-lpython2.6)。
6. c調用python訓練模型,輸入怎麼設置
可以使用Python的ctypes模塊來實現C和Python之間的通信,從而實現C調攔桐用Python訓練模型的輸入。
ctypes模塊提供了一種調用共享庫的方法,可以將Python的變數和函數轉換為C語言的變數和函數,從而實現C調用Python的功能。
要實現C調用Python訓練模型的輸入,需要做的第一步是在C程序簡脊坦中定義一個Python函數野嫌,並將其轉換為C函數。然後,可以使用ctypes模塊將Python函數轉換為C函數,從而實現C調用Python訓練模型的輸入。
7. 怎樣讓Python腳本與C++程序互相調用
二、Python調用C/C++x0dx0ax0dx0ax0dx0a1、Python調用C動態鏈接庫x0dx0ax0dx0a Python調用C庫比較簡單,不經過任何封裝打包成so,再使用python的ctypes調用即可。x0dx0a(1)C語言文件:pycall.cx0dx0ax0dx0a[html] view plain x0dx0a/***gcc -o libpycall.so -shared -fPIC pycall.c*/ x0dx0a#include
8. python 怎麼調用c語言介面
ctypes: 可直接調用c語言動態鏈接庫。
使用步驟:
1> 編譯好自己的動態連接庫
2> 利用ctypes載入動態連接庫
3> 用ctype調用C函數介面時,需要將python變數類型做轉換後才能作為函數參數,轉換原則見下圖:
#Step1:test.c#include<stdio.h>
intadd(inta,intb)
{
returna+b;
}#Step2:編譯動態鏈接庫(如何編譯動態鏈接庫在本文不詳解,網上資料一大堆。)gcc-fPIC-sharedtest.c-olibtest.so
#Step3:test.py
fromctypesimport*mylib=CDLL("libtest.so")或者cdll.LoadLibrary("libtest.so")add=mylib.add
add.argtypes=[c_int,c_int]#參數類型,兩個int(c_int是ctypes類型,見上表)
add.restype=c_int#返回值類型,int(c_int是ctypes類型,見上表)
sum=add(3,6)