定义结构体
'''
typedef struct pborca_direntry
{
/* Comments */
TCHAR szComments[PBORCA_MAXCOMMENT + 1];
LONG lCreateTime; /* Time of entry create/mod */
LONG lEntrySize; /* Size of entry */
LPTSTR lpszEntryName; /* Pointer to entry name */
PBORCA_TYPE otEntryType; /* Entry type */
} PBORCA_DIRENTRY
'''
class PBORCA_DIRENTRY(ctypes.Structure):
_fields_ = [('szComments' ,c_char*256),
('lCreateTime' ,c_long),
('lEntrySize' ,c_long),
('lpszEntryName',c_char_p),
('otEntryType' ,c_int)]
定义结构体指针
ctypes.POINTER(KBDLLHOOKSTRUCT)
stdcall调用约定
'''
void (__stdcall *pbcall )(PPBORCA_DIRENTRY,LPVOID);
'''
def pbcallback(pd, a):
print pd.contents.lpszEntryName
pbcall = ctypes.WINFUNCTYPE(ctypes.POINTER(PPBORCA_DIRENTRY),c_void_p)
c_pbcallback = KHOOK(pbcallback)
cdecl调用约定
CmpFuncType = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
def py_cmp_func(a, b):
if a[0] > b[0]:
return 1
elif a[0] < b[0]:
return -1
else:
return 0
cmpfunc = CmpFuncType(py_cmp_func)
调用dll
#stdcall
Objdll = ctypes.windll.LoadLibrary("dllpath")
Objdll = ctypes.WinDLL("dllpath")
#cdecl
Objdll = ctypes.cdll.LoadLibrary("dllpath")
Objdll = ctypes.CDLL("dllpath")
#调用函数
# 方法1
szPara = create_string_buffer('/0'*100)
dll.PrintInfo(byref(szPara), 100);
print szPara.value
# 方法2
sBuf = 'aaaaaaaaaabbbbbbbbbbbbbb'
pStr = c_char_p( )
pStr.value = sBuf
#pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value
dll.PrintInfo(pStr, len(pStr.value))
print pStr.value
# 方法3
strMa = "/0"*20
FunPrint = dll.PrintInfo
FunPrint.argtypes = [c_char_p, c_int]
#FunPrint.restypes = c_void_p
nRst = FunPrint(strMa, len(strMa))
print strMa,len(strMa)
# 方法4
pStr2 = c_char_p("/0")
print pStr2.value
#pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value
dll.PrintInfo(pStr2, len(pStr.value))
print pStr2.value
#参考https://blog.youkuaiyun.com/magictong/article/details/3075478/
pb通过pborca提取pbl中的对象
# -*- coding: cp936 -*-
import ctypes
from ctypes import *
class pborca_direntry(ctypes.Structure):
_fields_ = [
('szComments', ctypes.c_char*256),
('lCreateTime', ctypes.c_long),
('lEntrySize', ctypes.c_long),
('lpszEntryName', ctypes.c_char_p),
('otEntryType', ctypes.c_byte),
]
class pborca:
def __init__(self,dllPath):
self.pborc90= windll.LoadLibrary(dllPath)
def open(self):
self.pbs = self.pborc90.PBORCA_SessionOpen()
return self.pbs
def close(self):
self.pborc90.PBORCA_SessionClose(self.pbs)
self.pbs=None
def direntry_callback(self,callback):
CMPFUNC = WINFUNCTYPE(None, POINTER(pborca_direntry),c_void_p)
return CMPFUNC(callback)
def LibraryDirectory(self):
return self.pborc90.PBORCA_LibraryDirectory
# 遍历所有的对象
def LibraryDirectoryExt(self,pblPath):
ls_open=0
if not hasattr(self,'pbs'):
ls_open=self.open()
print self.pbs
res=[]
def def_callback(abc,a):
res.append(abc.contents)
_callback = self.direntry_callback(def_callback)
self.pborc90.PBORCA_LibraryDirectory(self.pbs,pblPath,'',0,_callback,0)
if ls_open!=0:
self.close()
return res
def callback(abc,a):
print 'callback by c++ in python... %s' % abc.contents.lpszEntryName
pb9 = pborca("R:\Sybase\Shared\PowerBuilder\pborc90.dll")
hORCASession = pb9.open()
_callback = pb9.direntry_callback(callback)
pb9.LibraryDirectory()(hORCASession,'D:\pb工具\pbfunction.pbl','',0,_callback,0)
pb9.close()
l = pb9.LibraryDirectoryExt('D:\pb工具\pbfunction.pbl')
print l
'''
pborc90 = windll.LoadLibrary("R:\Sybase\Shared\PowerBuilder\pborc90.dll")
CMPFUNC = WINFUNCTYPE(None, POINTER(pborca_direntry),c_void_p)
_callback = CMPFUNC(callback)
sOpen = pborc90.PBORCA_SessionOpen
sOpen.restype = c_void_p
hORCASession = sOpen()
listLib = pborc90.PBORCA_LibraryDirectory
listLib(hORCASession,'D:\pb工具\pbfunction.pbl','',0,_callback,0)
print hORCASession
sClose = pborc90.PBORCA_SessionClose
sClose.argtypes = [c_void_p]
sClose.restype = None
sClose(hORCASession)
'''
特别需要注意的是,在python3中:
Byte String:对应 C 中的一个字符串指针 char * ,指向一块内存区域。(字符串前面会加小b, b"helloworld")
Unicode String :对应 C 中一个宽字符串指针 wchar_t *,指向一块内存区域。(对应的就是字符串, "helloworld")
a = self.pborc90.PBORCA_LibraryDirectory(self.pbs,pblPath.encode('gb2312'),'',0,_callback,0)