我有一个带有原型的DLL函数如下:
short Connect(HANDLE* pHandle, UINT* pTimerID, LPCTSTR strDestination, LPCTSTR strServiceName, int nProtocol, int nType)
功能描述如下:
pHandle: socket handle.[out]
pTimerID: Timer ID using sending alive packet to a camera.[out]
strDestination: camera network IP.[in]
strServiceName: camera network port.[in]
nProtocol: address family(AF_INET).[in]
nType: Socket type(SOCK_STREAM or SCOK_DGRAM).[in]
我尝试从python中调用DLL,如下所示:
DLL = windll.LoadLibrary('myDll.dll')
self.UserID = 0
self.keepAliveID = 0
DLL.Connect.restype = ctypes.c_short
DLL.Connect.argtypes = [c_void_p, c_ulong, c_wchar_p, c_wchar_p, c_int, c_int]
try:
err = DLL.Connect(self.UserID,self.keepAliveID,self.ip,self.port,2,1)
if err == -1:
print "connect ErrorCode = ", err
except:
print "connect Exception = ", sys.exc_info()
运行程序后,我遇到了这个例外:
connect Exception = (<type 'exceptions.WindowsError'>, WindowsError('exception: access violation writing 0x00000000',), <traceback object at 0x0262C300>)
第二个问题是当我按如下方式更改argtypes
时:
DLL.Connect.argtypes = [c_void_p, POINTER(c_ulong), c_wchar_p, c_wchar_p, c_int, c_int]
然后我得到另一个例外:
connect Exception = (<class 'ctypes.ArgumentError'>, ArgumentError("argument 2: <type 'exceptions.TypeError'>: expected LP_c_ulong instance instead of int",), <traceback object at 0x0261A328>)
请帮忙!
答案 0 :(得分:0)
尝试重新定义函数调用,如下所示:
from ctypes import *
from ctypes.wintypes import *
dll = WinDLL('myDll.dll')
connect = dll.Connect
connect.restype = c_short
connect.argtypes = [POINTER(HANDLE), POINTER(UINT), LPCWSTR, LPCWSTR, c_int, c_int)
并且这样调用,使用byref
通过引用传递:
self.user_id = HANDLE()
self.keep_alive_id = UINT()
err = connect(byref(self.user_id), byref(self.keep_alive_id), self.ip, self.port, 2, 1)
当然未经测试,但至少应该让你更接近。