实例描述如何用python组件ctypes调用c的dll中的函数

工具:winpython,vc2010(我认为只要能生成dll的编译工具都行)

步骤1:

新建一个VC的DLL工程zm_funs,实现函数:

 1 #include "stdio.h"
 2 #include "string.h"
 3 
 4 typedef unsigned char uchar;
 5 //__declspec(dllexport)
 6 void gen_lbp59img(uchar *pu8Img, uchar *pu8LBP59Img, int dwW, int dwH, uchar *pu8LBP89Table)
 7 {
 8     int dwRI, dwCI, dwPI;
 9     int dwOft, dwVal;
10     int adwOffset8[8] = {-dwW - 1, -dwW, -dwW + 1, 1, dwW + 1, dwW, dwW - 1, -1};
11 
12     memset(pu8LBP59Img, 0, dwW * dwH);
13 
14     for (dwRI = 1; dwRI < dwH - 1; dwRI++)
15     {
16         for (dwCI = 1; dwCI < dwW - 1; dwCI++)
17         {
18             dwOft = dwRI * dwW + dwCI;
19             dwVal = 0;
20             for (dwPI = 0; dwPI < 8; dwPI++)
21             {
22                 if (pu8Img[dwOft + adwOffset8[dwPI]] > pu8Img[dwOft])
23                 {
24                     dwVal += 1 << (7 - dwPI);
25                 }
26             }
27             pu8LBP59Img[dwOft] = pu8LBP89Table[dwVal] - 1;
28         }
29     }
30 
31     return;
32 }
gen_lbp59img

用def文件或__declspec(dllexport)将函数名gen_lbp59img导出。然后编译成DLL(DLL的名字是zm_funs.dll)。

步骤2:

打开winpython,写一个同名的函数(之所以同名是为了好记)用来准备好要传给DLL中函数的数据:

 1 import scipy as sp
 2 import ctypes as ct
 3 
 4 zmfuns = ct.CDLL('zm_funs.dll')
 5 
 6 def gen_lbp59img(img, lbptable):
 7     sz = img.shape
 8     if len(sz) > 2:
 9         print 'can''t handle color image.'
10         return
11     imgh, imgw = sz
12     lbpimg = sp.zeros(sz, dtype = sp.uint8)
13 #    call gen_lbp59img of c
14     zmfuns.gen_lbp59img(img.ctypes, lbpimg.ctypes, imgw, imgh, lbptable.ctypes)
15     
16     return lbpimg
gen_lbp59img

注意,传进去的数据是array中的ctypes。实际上,array中的ctypes记录的是指向array数据的地址。

结果:

经过测度,用python实现gen_lbp59img处理QCIF的灰度图像,需要耗时200ms左右,而用C实现后,耗时不到1.5ms。这差距太大了吧!看来PYTHON虽然方便了编程,但是耗时太可观了!

原文地址:https://www.cnblogs.com/starimpact/p/3526539.html