二、Python調用C/C++\x0d\x0a\x0d\x0a\x0d\x0a1、Python調用C動態鏈接庫\x0d\x0a\x0d\x0a Python調用C庫比較簡單,不經過任何封裝打包成so,再使用python的ctypes調用即可。\x0d\x0a(1)C語言文件:pycall.c\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0a/***gcc -o libpycall.so -shared -fPIC pycall.c*/ \x0d\x0a#include \x0d\x0a#include \x0d\x0aint foo(int a, int b) \x0d\x0a{ \x0d\x0a printf("you input %d and %d\n", a, b); \x0d\x0a return a+b; \x0d\x0a} \x0d\x0a(2)gcc編譯生成動態庫libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++編譯生成C動態庫的代碼中的函數或者方法時,需要使用extern "C"來進行編譯。\x0d\x0a(3)Python調用動態庫的文件:pycall.py\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0aimport ctypes \x0d\x0all = ctypes.cdll.LoadLibrary \x0d\x0alib = ll("./libpycall.so") \x0d\x0alib.foo(1, 3) \x0d\x0aprint '***finish***' \x0d\x0a(4)運行結果:\x0d\x0a\x0d\x0a\x0d\x0a2、Python調用C++(類)動態鏈接庫 \x0d\x0a\x0d\x0a 需要extern "C"來輔助,也就是說還是只能調用C函數,不能直接調用方法,但是能解析C++方法。不是用extern "C",構建后的動態鏈接庫沒有這些函數的符號表。\x0d\x0a(1)C++類文件:pycallclass.cpp\x0d\x0a\x0d\x0a[html] view plain copy \x0d\x0a#include \x0d\x0ausing namespace std; \x0d\x0a \x0d\x0aclass TestLib \x0d\x0a{ \x0d\x0a public: \x0d\x0a void display(); \x0d\x0a void display(int a); \x0d\x0a}; \x0d\x0avoid TestLib::display() { \x0d\x0a cout \x0d\x0ausing namespace std; \x0d\x0aint test() \x0d\x0a{ \x0d\x0a int a = 10, b = 5; \x0d\x0a return a+b; \x0d\x0a} \x0d\x0aint main() \x0d\x0a{ \x0d\x0a cout \x0d\x0a#include \x0d\x0a#include \x0d\x0a \x0d\x0aint fac(int n) \x0d\x0a{ \x0d\x0a if (n
創新互聯建站主要從事成都網站設計、成都網站制作、網頁設計、企業做網站、公司建網站等業務。立足成都服務南京,10多年網站建設經驗,價格優惠、服務專業,歡迎來電咨詢建站服務:18980820575
回答于?2022-11-16
二、Python調用C/C++1、Python調用C動態鏈接庫Python調用C庫比較簡單,不經過任何封裝打包成so,再使用python的ctypes調用即可。(1)C語言文件:pycall.c[html]viewplaincopy/***gcc-olibpycall.so-shared-fPICpycall.c*/#include#includeintfoo(inta,intb){printf("youinput%dand%d\n",a,b);returna+b;}(2)gcc編譯生成動態庫libpycall.so:gcc-olibpycall.so-shared-fPICpycall.c。使用g++編譯生成C動態庫的代碼中的函數或者方法時,需要使用extern"C"來進行編譯。(3)Python調用動態庫的文件:pycall.py[html]viewplaincopyimportctypesll=ctypes.cdll.LoadLibrarylib=ll("./libpycall.so")lib.foo(1,3)print'***finish***'(4)運行結果:2、Python調用C++(類)動態鏈接庫需要extern"C"來輔助,也就是說還是只能調用C函數,不能直接調用方法,但是能解析C++方法。不是用extern"C",構建后的動態鏈接庫沒有這些函數的符號表。(1)C++類文件:pycallclass.cpp[html]viewplaincopy#includeusingnamespacestd;classTestLib{public:voiddisplay();voiddisplay(inta);};voidTestLib::display(){cout#include#includeintfac(intn){if(n2)return(1);/*0!==1!==1*/return(n)*fac(n-1);/*n!==n*(n-1)!*/}char*reverse(char*s){registerchart,/*tmp*/*p=s,/*fwd*/*q=(s+(strlen(s)-1));/*bwd*/while(p
ctypes:? 可直接調用c語言動態鏈接庫。
使用步驟:
1 編譯好自己的動態連接庫
2 利用ctypes載入動態連接庫
3 用ctype調用C函數接口時,需要將python變量類型做轉換后才能作為函數參數,轉換原則見下圖:
4 Python若想獲取ctypes調用的C函數返回值,需要先指定返回值類型。我們將在接下來的完整Sample中看到如何使用。
#Step?1:??test.c#include?stdio.h
int?add(int?a,?int?b)
{
return?a?+?b;
}#Step?2:?編譯動態鏈接庫?(?如何編譯動態鏈接庫在本文不詳解,網上資料一大堆。)gcc?-fPIC?-shared?test.c?-o?libtest.so??
#Step?3:??test.py
from?ctypes?import?*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)
在函數聲明加入前綴,如
__declspec(dllexport) int Fun(int a, int b)
否則在加載該dll時會提示找不到該符號
在windows下可以通過vs自帶的dumpbin工具查看可被調用符號
dumpbin /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類型的對照,如下:
使用Python的ctypes,我們可以直接調用由C直接編譯出來的函數。其實就是調用動態鏈接庫中的函數。為什么我們需要這樣做呢,因為有些時候,我們可能需要一個性能上比較講究的算法,有些時候,我們可以在Python中使用已經有了的現成的被封閉在動態鏈接庫中的函數。下面是如何調用的示例。
首先,我們用一個乘法來表示一個算法功能。下面是C的程序:
int?multiply(int?num1,?int?num2){???
return?num1?*?num2;
}????
如果在Windows下,你可能需要寫成下面這個樣子:
#include?windows.h?
BOOL?APIENTRYDll
Main(HANDLE?hModule,?DWORD?dwReason,?LPVOID?lpReserved){????
return?TRUE;
}?
__declspec(dllexport)?
intmultiply(int?num1,?int?num2){?
return?num1?*?num2;
}????
然后,自然是把這個C文件編成動態鏈接庫:
Linux下的編譯:
gcc?-c?-fPIC?libtest.c
gcc?-shared?libtest.o?-o?libtest.so????
Windows下的編譯:
cl?-LD?libtest.c?-libtest.dll????
于是在我們的Python中可以這樣使用:
(其中的libtest.so在Windows下改成libtest.dll即可)
from?ctypes?import?*
import?os
libtest?=?cdll.LoadLibrary(os.getcwd()?+?'/libtest.so')
print?libtest.multiply(2,?2)4????
注意:上面的Python腳本中需要把動態鏈接庫放到當前目錄中。
分享名稱:python調用c函數 python調用c函數獲取變量值
標題網址:http://vcdvsql.cn/article36/dooossg.html
成都網站建設公司_創新互聯,為您提供網站設計、網站建設、網站制作、網頁設計公司、品牌網站設計、服務器托管
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯