在使用ctypes时,要对操作系统进行兼容性处理,主要是区分FUNCTYPE,DWORD的引入,在linux操作系统,要把c_ubyte 别名为DWORD,保证程序的可读性。
if sys.platform == 'win32':
from ctypes.wintypes import DWORD
from ctypes import WINFUNCTYPE
winfun_ctype = WINFUNCTYPE
elif sys.platform.startswith('linux'):
from ctypes import c_ubyte as DWORD
from ctypes import CFUNCTYPE
winfun_ctype = CFUNCTYPE
ctypes中的数据类型与c语言中的类型存在关联关系
比如,ctypes中的数据类型
class c_long(_SimpleCData):
_type_ = "l"
_check_size(c_long)
然后 父类 _SimpleCData
class _SimpleCData(_CData):
""" XXX to be provided """
def __init__(*args):
""" x.__init__(...) initializes x; see help(type(x)) for signature """
pass
value = property(None, None, None,
""" current value """
)
再查看_CData 类,就跟不下去了。_ctypes.pi 这个文件是自动生成的
class _SimpleCData(_CData):
""" XXX to be provided """
def __init__(*args):
""" x.__init__(...) initializes x; see help(type(x)) for signature """
pass
value = property(None, None, None,
""" current value """
)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
from ctypes import *
BYTE = c_ubyte
WORD = c_ushort
DWORD = c_ulong
WCHAR = c_wchar
UINT = c_uint
INT = c_int
DOUBLE = c_double
FLOAT = c_float
BOOLEAN = BYTE
BOOL = c_long
from ctypes import _SimpleCData
class democlass2(Structure):
pass
LPdemoclass2 = POINTER(democlass2)
democlass2._fields_ = [
# democlass.h 8531
('sSNumber', BYTE * 48),
('wDevType', WORD),
('bySupport3', BYTE),
('byRes2', BYTE),
]
def f():
try:
ip = '1.1.1.1'
port = 8000
username = 'admin'
password ='Abc123'
ip = str(ip)
port = int(port)
from ctypes import WinDLL
democlass = WinDLL("democlass.dll")
device_info = democlass2()
try:
democlass.NET_DVR_Init()
user_id = democlass.demofunction(ip, port, username, password, byref(device_info))
except Exception,e:
print e.message()
print "load dll sucess!",user_id
except WindowsError, e:
raise Exception("Unable to load the democlass.dll from windows, %e" %e.message)
if __name__=='__main__':
f()