用python做一个windows平台的工具,纯python缺乏接口,因此想用ctypes模块调用Windows API来实现,碰到了下列问题:
用python封装Windows 中的SystemTimeToFileTime,调用过程中提示参数不对。
Windows API 原型
BOOL WINAPI SystemTimeToFileTime(
__in const SYSTEMTIME* lpSystemTime,
__out LPFILETIME lpFileTime
);
python 封装代码:
from ctypes import *
from ctypes.wintyps import *
#封装 SYSTEMTIME 类型
class SYSTEMTIME(Structure):
fields = [("Year", WORD),
("Month", WORD),
("DayOfWeek", WORD),
("Day", WORD),
("Hour", WORD),
("Min", WORD),
("Sec", WORD),
("MillSec", WORD)]
class FILETIME(Structure):
fields = [("dwLowDateTime", DWORD),
("dwHighDateTime", DWORD)]
proto_systm2filetm = WINFUNCTYPE(BOOL, POINTER(SYSTEMTIME), POINTER(FILETIME))
paramflags = (1, "systime", None), (2, "filetime", None)
SystemTimeToFileTime = proto_systm2filetm(("SystemTimeToFileTime", windll.kernel32),
paramflags)
#测试
atime = FILETIME()
atime.dwLowDateTime = 0
atime.dwHighDateTime = 100
systm = SYSTEMTIME()
systm.Year = 2015
systm.Month = 1
systm.Day = 5
systm.DayOfWeek = 1
systm.Hour = 1
systm.Min = 17
systm.Sec = 0
print SystemTimeToFileTime(systime = pointer(systm), filetime=pointer(atime))
print "error:%d" % GetLastError()
#结果:
提示 print SystemTimeToFileTime(systime = pointer(systm), filetime=pointer(atime))
TypeError: call takes exactly 1 arguments (2 given)
疑问:SystemTimeToFileTime明明声明了2个参数,为啥提示只接受一个参数?
尝试修改,将paramflags该成:
paramflags = (1, "systime", None), (1, "filetime", None)
这下没有提示参数个数不对了,但是函数执行返回FALSE, GetLastError == 87(参数不正确)。
请各位帮忙把把脉,API中的 IN, OUT参数,用ctypes应该如何包装? 使用时如何传实参?
万分感谢!
evntrace不需要关心,重点是调用方式
class TestEventClass(event.EventClass):
_fields_ = [('TestString', field.String),
('TestInt32', field.Int32),
('TestInt64', field.Int64)]
time_s = int(time.time())
date_time = datetime.datetime.utcfromtimestamp(time_s)
sys_time = evntrace.SYSTEMTIME(
date_time.year, date_time.month, 0, date_time.day,
date_time.hour, date_time.minute, date_time.second,
date_time.microsecond / 1000)
file_time = ctypes.wintypes.FILETIME()
ctypes.windll.kernel32.SystemTimeToFileTime(ctypes.byref(sys_time),
ctypes.byref(file_time))
time_stamp = file_time.dwHighDateTime
time_stamp <<= 32
time_stamp |= file_time.dwLowDateTime