ctypes:? 可直接調(diào)用c語言動態(tài)鏈接庫。
10余年的安寧網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整安寧建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。成都創(chuàng)新互聯(lián)從事“安寧網(wǎng)站設(shè)計”,“安寧網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。
使用步驟:
1 編譯好自己的動態(tài)連接庫
2 利用ctypes載入動態(tài)連接庫
3 用ctype調(diào)用C函數(shù)接口時,需要將python變量類型做轉(zhuǎn)換后才能作為函數(shù)參數(shù),轉(zhuǎn)換原則見下圖:
4 Python若想獲取ctypes調(diào)用的C函數(shù)返回值,需要先指定返回值類型。我們將在接下來的完整Sample中看到如何使用。
#Step?1:??test.c#include?stdio.h
int?add(int?a,?int?b)
{
return?a?+?b;
}#Step?2:?編譯動態(tài)鏈接庫?(?如何編譯動態(tài)鏈接庫在本文不詳解,網(wǎng)上資料一大堆。)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]?#?參數(shù)類型,兩個int(c_int是ctypes類型,見上表)
add.restype?=?c_int?#?返回值類型,int?(c_int?是ctypes類型,見上表)
sum?=?add(3,?6)
在函數(shù)聲明加入前綴,如
__declspec(dllexport) int Fun(int a, int b)
否則在加載該dll時會提示找不到該符號
在windows下可以通過vs自帶的dumpbin工具查看可被調(diào)用符號
dumpbin /exports test.dll
C函數(shù)在調(diào)用過程中關(guān)于參數(shù)傳遞和壓棧由多種規(guī)定,作為dll提供給其他程序調(diào)用時,必須明確并統(tǒng)一為同一種調(diào)用規(guī)定,否則會導(dǎo)致棧破壞,編譯器負(fù)責(zé)具體實現(xiàn)調(diào)用規(guī)定,主要有以下幾種調(diào)用規(guī)定
python下調(diào)用C庫有多種方式,ctypes是其中一種比較方便的,調(diào)用時首先需要加載dll文件,根據(jù)C dll的調(diào)用規(guī)定不同需要使用不同接口,使用ctypes需要 import ctypes 庫
對于簡單的C函數(shù),例如 int add(int a, int b) , 此時就可以直接調(diào)用了,如
對于較復(fù)雜的C函數(shù)的參數(shù)情況,ctypes調(diào)用時對入?yún)⒑统霾妥鲆欢ㄌ幚?,這里分情況討論
以上包含了幾種主要的參數(shù)傳遞情況,ctypes也提供了一個較為完整的python類型和C類型的對照,如下:
二、Python調(diào)用C/C++\x0d\x0a\x0d\x0a\x0d\x0a1、Python調(diào)用C動態(tài)鏈接庫\x0d\x0a\x0d\x0a Python調(diào)用C庫比較簡單,不經(jīng)過任何封裝打包成so,再使用python的ctypes調(diào)用即可。\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編譯生成動態(tài)庫libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++編譯生成C動態(tài)庫的代碼中的函數(shù)或者方法時,需要使用extern "C"來進(jìn)行編譯。\x0d\x0a(3)Python調(diào)用動態(tài)庫的文件: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)運行結(jié)果:\x0d\x0a\x0d\x0a\x0d\x0a2、Python調(diào)用C++(類)動態(tài)鏈接庫 \x0d\x0a\x0d\x0a 需要extern "C"來輔助,也就是說還是只能調(diào)用C函數(shù),不能直接調(diào)用方法,但是能解析C++方法。不是用extern "C",構(gòu)建后的動態(tài)鏈接庫沒有這些函數(shù)的符號表。\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
回答于?2022-11-16
Python可以調(diào)用VC的模塊。
Python調(diào)用C++在Python腳本里添加其中ctypes是Python的一個庫,提供和C語言兼容的數(shù)據(jù)類型,可以很方便地調(diào)用CDLL中的函數(shù)。運行以上腳本得到:顯示調(diào)用C++程序成功。
采用這個方法,我們不用進(jìn)行大量的改寫,也能在Python中使用我們積累的各種C++程序了。