python調(diào)用動(dòng)態(tài)鏈接庫(kù)的基本過(guò)程詳解
動(dòng)態(tài)鏈接庫(kù)在Windows中為.dll文件,在linux中為.so文件。以linux平臺(tái)為例說(shuō)明python調(diào)用.so文件的使用方法。
本例中默認(rèn)讀者已經(jīng)掌握動(dòng)態(tài)鏈接庫(kù)的生成方法,如果不太清楚的可以參考動(dòng)態(tài)鏈接庫(kù)的使用
調(diào)用上例動(dòng)態(tài)鏈接庫(kù)的使用中的sum.so
import ctypes so = ctypes.CDLL('./sum.so') print "so.sum(50) = %d" % so.sum(50) so.display("hello world!") print "so.add() = %d" % so.add(ctypes.c_float(2), ctypes.c_float(2010))
output
so.sum(50) = 1275 hello world! so.add() = 2012
注意:
- 如果python在調(diào)用C函數(shù)內(nèi)部出現(xiàn)了問(wèn)題,系統(tǒng)不會(huì)提示具體出現(xiàn)什么問(wèn)題,只會(huì)提示"segmentation fault"。所以最好是先用C語(yǔ)言調(diào)用該動(dòng)態(tài)庫(kù)驗(yàn)證沒(méi)有問(wèn)題了再提供給python調(diào)用。
- python傳參給C函數(shù)時(shí),可能會(huì)因?yàn)閜ython傳入實(shí)參與C函數(shù)形參類(lèi)型不一致會(huì)出現(xiàn)問(wèn)題( 一般int, string不會(huì)有問(wèn)題,float要注意 )。這時(shí)需要在python調(diào)用時(shí)傳入的實(shí)參做一個(gè)類(lèi)型轉(zhuǎn)換(見(jiàn)so.add(float, float)函數(shù)的調(diào)用)。轉(zhuǎn)換方式見(jiàn)下表:
數(shù)組的傳入傳出
如果將python中l(wèi)ist傳入C函數(shù)數(shù)組,則需要提前轉(zhuǎn)換。
import ctypes pyarray = [1, 2, 3, 4, 5] carrary = (ctypes.c_int * len(pyarray))(*pyarray) //有點(diǎn)類(lèi)似malloc的方式生成carray print so.sum_array(carray, len(pyarray))
如果如果需要將C array返回python,需要提前把a(bǔ)rray傳入,然后在C函數(shù)中修改,返回時(shí)再把c array轉(zhuǎn)換為np.array
pyarray = [1,2,3,4,5,6,7,8] carray = (ctypes.c_int*len(pyarray))(*pyarray) so.modify_array(carray, len(pyarray)) print np.array(carray)
output
[10 20 30 40 50 60 70 80]
也可以用形參方式提前定義函數(shù)接口,然后再傳入numpy結(jié)構(gòu)
import ctypes import numpy as np from numpy.ctypeslib import ndpointer so = ctypes.CDLL('./sum.so') pyarray = np.array([1,2,3,4,5,6,7,8], dtype="int32") fun = so.modify_array fun.argtypes = [ndpointer(ctypes.c_int), ctypes.c_int] fun.restype = None fun(pyarray, len(pyarray)) print np.array(pyarray)
注意:numpy中的數(shù)據(jù)類(lèi)型指定很重要,即dtype的設(shè)定
圖片的傳入傳出
轉(zhuǎn)遞數(shù)據(jù)域
背景知識(shí):
python中的opencv圖片是用numpy的方式保存的,而opencv3 C語(yǔ)言的圖片數(shù)據(jù)結(jié)構(gòu)為cvMat (IplImage已經(jīng)逐棄用)
所以需要把python中numpy圖片轉(zhuǎn)換為ctypes.POINTER(ctypes.c_ubyte)的指針轉(zhuǎn)入其數(shù)據(jù)域,再將其行列信息傳入,就可以在C中從最底層初始化一個(gè)CvMat,如果要初始化一個(gè)別數(shù)據(jù)結(jié)構(gòu)的圖片也是同理(如darknet的image,caffe的blob)
python numpy image 轉(zhuǎn)換為 C pointer的方法
python_frm.ctypes.data_as(C.POINTER(ctypes.c_ubyte))
注意:傳入numpy image前一定要確保numpy image是numpy array數(shù)據(jù)類(lèi)型
比如我遇到的bug
image = cv2.imread("xxx.jpg");
image傳入ctypes_so.fun之中圖片是有效的,但
image = cv2.imread("xxx.jpg");
這時(shí)候進(jìn)入ctypes_so.fun的圖片會(huì)變成一個(gè)亂碼
即,crop之后的numpy image的type雖然也為numpy array,但實(shí)際傳入的image data卻不正確
解決方法:
無(wú)論是何種方式得到的numpy image,都強(qiáng)行轉(zhuǎn)換為numpy array,再傳入ctypes_so.fun
image = numpy.array(image)
可以解決這個(gè)bug
如果使用opencv2 可以考慮直接將numpy image轉(zhuǎn)換為IplImage
opencv3 python已經(jīng)不支持cv2.cv的函數(shù)了
但Opencv2可能還可以嘗試以下方法
python調(diào)用C++中的類(lèi)
因?yàn)閜ython不能直接調(diào)用C++中的類(lèi),所以必須把C++中的類(lèi)轉(zhuǎn)換為C的接口
轉(zhuǎn)換原則
- 所有的C++關(guān)鍵字及其特有的使用方式均不能出現(xiàn)在.h文件里,.h中僅有C函數(shù)的包裝函數(shù)聲明
- 在class.cpp中實(shí)現(xiàn)對(duì)類(lèi)的成員函數(shù)接口轉(zhuǎn)換的函數(shù),包括對(duì)類(lèi)內(nèi)成員的讀寫(xiě)函數(shù)get() and set()
- 如果要在包裝函數(shù)中要實(shí)例化對(duì)象,盡量用new constructor()的將對(duì)象的內(nèi)存實(shí)例化在堆中,否則對(duì)象會(huì)被析構(gòu)
- 記得在所有包含函數(shù)聲明的文件中加入以下關(guān)鍵字,聲明該函數(shù)為C函數(shù),否則該函數(shù)的符號(hào)不會(huì)記錄在二進(jìn)制文件中
#ifdef __cplusplus extern "C" { #endif xxxxxx function declaration xxxxx #ifdef __cplusplus } #endif
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 用python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的驗(yàn)證碼
- Python利用Pillow(PIL)庫(kù)實(shí)現(xiàn)驗(yàn)證碼圖片的全過(guò)程
- python圖片驗(yàn)證碼識(shí)別最新模塊muggle_ocr的示例代碼
- Python實(shí)現(xiàn)驗(yàn)證碼識(shí)別
- 使用python創(chuàng)建生成動(dòng)態(tài)鏈接庫(kù)dll的方法
- ubuntu中python調(diào)用C/C++方法之動(dòng)態(tài)鏈接庫(kù)詳解
- Python在Windows和在Linux下調(diào)用動(dòng)態(tài)鏈接庫(kù)的教程
- Python調(diào)用易語(yǔ)言動(dòng)態(tài)鏈接庫(kù)實(shí)現(xiàn)驗(yàn)證碼功能
相關(guān)文章
python多進(jìn)程實(shí)現(xiàn)文件下載傳輸功能
這篇文章主要為大家詳細(xì)介紹了python多進(jìn)程實(shí)現(xiàn)文件下載傳輸功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Python學(xué)習(xí)思維導(dǎo)圖(必看篇)
下面小編就為大家?guī)?lái)一篇Python學(xué)習(xí)思維導(dǎo)圖(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06關(guān)于tf.TFRecordReader()函數(shù)的用法解析
今天小編就為大家分享一篇關(guān)于tf.TFRecordReader()函數(shù)的用法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02python常規(guī)方法實(shí)現(xiàn)數(shù)組的全排列
這篇文章主要介紹了python常規(guī)方法實(shí)現(xiàn)數(shù)組的全排列,實(shí)例分析了全排列的概念及Python常規(guī)實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-03-03python實(shí)現(xiàn)的正則表達(dá)式功能入門(mén)教程【經(jīng)典】
這篇文章主要介紹了python實(shí)現(xiàn)的正則表達(dá)式功能,詳細(xì)分析了Python正則表達(dá)式中常用的各種符號(hào)、函數(shù)等的使用方法與注意事項(xiàng),需要的朋友可以參考下2017-06-06Python-docx 實(shí)現(xiàn)整體修改或者部分修改文字的大小和字體類(lèi)型
這篇文章主要介紹了Python-docx 實(shí)現(xiàn)整體修改或者部分修改文字的大小和字體類(lèi)型,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03tensorflow指定GPU與動(dòng)態(tài)分配GPU memory設(shè)置
今天小編就為大家分享一篇tensorflow指定GPU與動(dòng)態(tài)分配GPU memory設(shè)置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02