From: Python調用Linux下的動態庫(.so)html
(1) 生成.so:.c to .sopython
lolo@-id:workme$ gcc -Wall -g -fPIC -c linuxany.c -o linuxany.o
lolo@-id:workme$ ls linux linuxany.c linuxany.o lolo@-id:workme$ gcc -shared linuxany.o -o linuxany.so
lolo@-id:workme$ ls libmax.so linux linuxany.c linuxany.o linuxany.so
(2) 調用.so:Python call .solinux
#!/usr/bin/python from ctypes import * import os
//參數爲生成的.so文件所在的絕對路徑 libtest = cdll.LoadLibrary(os.getcwd() + '/linuxany.so')
//直接用方法名進行調用 print libtest.display('Hello,I am linuxany.com') print libtest.add(2,2010)
(3) 可能遇到的問題:c++
version `GLIBC_2.27' not found數組
Download updated version from: https://mirror.freedif.org/GNU/libc/ 安全
Ref: python調用動態連接庫的基本過程【連接寫的不錯】app
python傳參給C函數時,可能會由於python傳入實參與C函數形參類型不一致會出現問題( 通常int, string不會有問題,float要注意 )函數
提早把array傳入,而後在C函數中修改。ui
import ctypes
pyarray = [1, 2, 3, 4, 5] carrary = (ctypes.c_int * len(pyarray)) (*pyarray) print so.sum_array(carray, len(pyarray))
返回值,其實同樣道理,只是:返回時再把 c array 轉換爲 np.arrayspa
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) // <----
"傳參" 前定義函數接口。
Ref: Python OpenCV pass mat ptr to c++ code
import ctypes import numpy as np from numpy.ctypeslib import ndpointer
pyarray = np.array([1,2,3,4,5,6,7,8], dtype="int32") # numpy中的數據類型指定很重要,即dtype的設定
so = ctypes.CDLL('./sum.so')
fun = so.modify_array
/* 告知對方,將要傳遞怎麼樣的參數 */ fun.argtypes = [ndpointer(ctypes.c_int), ctypes.c_int] fun.restype = None
fun(pyarray, len(pyarray))
print( np.array(pyarray) )
Python numpy image 轉換爲 C pointer 的方法。
因此,必定要確保numpy image是numpy array數據類型
image = cv2.imread("xxx.jpg");
(1) Crop以後的格式data有點問題,例如:
image = whl_img[y1:y2, x1:x2]
crop以後的numpy image的type雖然也爲numpy array,但實際傳入的image data卻不正確
(2) 統一解決方案:
image = numpy.array(image)
可見,即便參數解決,返回值依然是個問題。
static thread_local Mat tag; ImageWrapper ScanBuff(uint8_t* data, size_t Width, size_t Height) { Mat OldFrame= Mat(Height, Width, CV_8UC3, data);
... ...
}
一些有參考價值的代碼。
#!/usr/bin/python #import os import cv2 import numpy as np import numpy.ctypeslib as npct from ctypes import * import ctypes import numpy as np from numpy.ctypeslib import ndpointer objectPath = './lolo.bmp' img = cv2.imread(objectPath) img_row = img_height = img.shape[0] img_col = img_width = img.shape[1] print('img_row: %d, img_col: %d' % (img_row, img_col) ) ################################################################################## # https://stackoverflow.com/questions/37073399/python-opencv-pass-mat-ptr-to-c-code # https://www.cnblogs.com/fariver/p/6573112.html
# (1) 定義這是一個怎樣的指針 ucharPtr = npct.ndpointer(dtype=np.uint8, ndim=1, flags='CONTIGUOUS')
# (2) 加載動態庫和函數 CONST_LIB_PATH = '../lib/linux/libtagdetect.so' so = cdll.LoadLibrary( CONST_LIB_PATH ) #fun = so.ScanBuffer fun = so['ScanBuffer']
# (3) 定義參數的類型 fun.argtypes = [ucharPtr, ctypes.c_int, ctypes.c_int] fun.restype = None # (4) 自定義一個符合條件的fake image in_image = np.zeros( (img_row, img_col), np.uint8, order='C' ).ravel() print(in_image.shape)
# (5) 執行動態庫內的函數 fun(in_image, img_width, img_height)
由於python不能直接調用C++中的類,因此必須把C++中的類轉換爲C的接口
轉換原則
#ifdef __cplusplus extern "C" { #endif xxxxxx function declaration xxxxx #ifdef __cplusplus } #endif
End.