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.