中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python調用動態鏈接庫的基本過程詳解

發布時間:2020-10-02 21:40:24 來源:腳本之家 閱讀:206 作者:fariver 欄目:開發技術

動態鏈接庫在Windows中為.dll文件,在linux中為.so文件。以linux平臺為例說明python調用.so文件的使用方法。
本例中默認讀者已經掌握動態鏈接庫的生成方法,如果不太清楚的可以參考動態鏈接庫的使用

調用上例動態鏈接庫的使用中的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在調用C函數內部出現了問題,系統不會提示具體出現什么問題,只會提示"segmentation fault"。所以最好是先用C語言調用該動態庫驗證沒有問題了再提供給python調用。
  • python傳參給C函數時,可能會因為python傳入實參與C函數形參類型不一致會出現問題( 一般int, string不會有問題,float要注意 )。這時需要在python調用時傳入的實參做一個類型轉換(見so.add(float, float)函數的調用)。轉換方式見下表:

python調用動態鏈接庫的基本過程詳解

數組的傳入傳出

如果將python中list傳入C函數數組,則需要提前轉換。

import ctypes
pyarray = [1, 2, 3, 4, 5]
carrary = (ctypes.c_int * len(pyarray))(*pyarray) //有點類似malloc的方式生成carray
print so.sum_array(carray, len(pyarray))

refer

如果如果需要將C array返回python,需要提前把array傳入,然后在C函數中修改,返回時再把c array轉換為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]

也可以用形參方式提前定義函數接口,然后再傳入numpy結構

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中的數據類型指定很重要,即dtype的設定

圖片的傳入傳出

轉遞數據域

背景知識:

python中的opencv圖片是用numpy的方式保存的,而opencv3 C語言的圖片數據結構為cvMat (IplImage已經逐棄用)
所以需要把python中numpy圖片轉換為ctypes.POINTER(ctypes.c_ubyte)的指針轉入其數據域,再將其行列信息傳入,就可以在C中從最底層初始化一個CvMat,如果要初始化一個別數據結構的圖片也是同理(如darknet的image,caffe的blob)
python numpy image 轉換為 C pointer的方法

python_frm.ctypes.data_as(C.POINTER(ctypes.c_ubyte))

注意:傳入numpy image前一定要確保numpy image是numpy array數據類型

比如我遇到的bug

image = cv2.imread("xxx.jpg");

image傳入ctypes_so.fun之中圖片是有效的,但

image = cv2.imread("xxx.jpg");

這時候進入ctypes_so.fun的圖片會變成一個亂碼

即,crop之后的numpy image的type雖然也為numpy array,但實際傳入的image data卻不正確

解決方法:

無論是何種方式得到的numpy image,都強行轉換為numpy array,再傳入ctypes_so.fun

image = numpy.array(image)

可以解決這個bug

refence

如果使用opencv2 可以考慮直接將numpy image轉換為IplImage

opencv3 python已經不支持cv2.cv的函數了

但Opencv2可能還可以嘗試以下方法

numpy image to iplimage

python調用C++中的類

因為python不能直接調用C++中的類,所以必須把C++中的類轉換為C的接口

轉換原則

  • 所有的C++關鍵字及其特有的使用方式均不能出現在.h文件里,.h中僅有C函數的包裝函數聲明
  • 在class.cpp中實現對類的成員函數接口轉換的函數,包括對類內成員的讀寫函數get() and set()
  • 如果要在包裝函數中要實例化對象,盡量用new constructor()的將對象的內存實例化在堆中,否則對象會被析構
  • 記得在所有包含函數聲明的文件中加入以下關鍵字,聲明該函數為C函數,否則該函數的符號不會記錄在二進制文件中
#ifdef __cplusplus
extern "C" {
#endif
xxxxxx function declaration xxxxx
#ifdef __cplusplus
}
#endif

code
refer
refer

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

十堰市| 车险| 彰化市| 陆川县| 边坝县| 乐清市| 自治县| 微山县| 泸西县| 奎屯市| 普兰店市| 嵊州市| 蓬安县| 佛冈县| 绥宁县| 南阳市| 永泰县| 荆门市| 鄱阳县| 栖霞市| 舒兰市| 六枝特区| 孝感市| 浮山县| 临夏县| 潍坊市| 云林县| 德惠市| 东安县| 布尔津县| 延寿县| 马尔康县| 临城县| 昌黎县| 南康市| 宝丰县| 临澧县| 德安县| 孟津县| 绍兴市| 鄂伦春自治旗|