Use also `@ctypes.util.wrap_dll_function()` decorator.
#
try:
- from ctypes import Structure, c_int, c_double, c_longlong
+ from ctypes.util import struct as ctypes_struct
+ from ctypes import c_int, c_double, c_longlong
except ImportError:
- Structure = object
+ def ctypes_struct(cls): return cls
c_int = c_double = c_longlong = None
#
#
-class _Foo(Structure):
- _fields_ = [
- ('x', c_int),
- ('y', c_double),
- ('z', c_longlong,)
- ]
+@ctypes_struct
+class _Foo:
+ x: c_int
+ y: c_double
+ z: c_longlong
class _TestSharedCTypes(BaseTestCase):
# if Python is running as a service (such as the buildbot service),
# gui interaction may be disallowed
import ctypes
+ import ctypes.util
import ctypes.wintypes
+
UOI_FLAGS = 1
WSF_VISIBLE = 0x0001
- class USEROBJECTFLAGS(ctypes.Structure):
- _fields_ = [("fInherit", ctypes.wintypes.BOOL),
- ("fReserved", ctypes.wintypes.BOOL),
- ("dwFlags", ctypes.wintypes.DWORD)]
- dll = ctypes.windll.user32
- h = dll.GetProcessWindowStation()
+
+ @ctypes.util.struct
+ class USEROBJECTFLAGS:
+ fInherit: ctypes.wintypes.BOOL
+ fReserved: ctypes.wintypes.BOOL
+ dwFlags: ctypes.wintypes.DWORD
+
+ user32 = ctypes.windll.user32
+
+ @ctypes.util.wrap_dll_function(user32)
+ def GetProcessWindowStation() -> ctypes.wintypes.HANDLE:
+ ...
+
+ h = GetProcessWindowStation()
if not h:
raise ctypes.WinError()
+
+ @ctypes.util.wrap_dll_function(user32)
+ def GetUserObjectInformationW(
+ hObj: ctypes.wintypes.HANDLE,
+ nIndex: ctypes.c_int,
+ pvInfo: ctypes.c_void_p,
+ nLength: ctypes.wintypes.DWORD,
+ lpnLengthNeeded: ctypes.POINTER(ctypes.wintypes.DWORD),
+ ) -> ctypes.wintypes.BOOL:
+ ...
+
uof = USEROBJECTFLAGS()
needed = ctypes.wintypes.DWORD()
- res = dll.GetUserObjectInformationW(h,
+ res = GetUserObjectInformationW(h,
UOI_FLAGS,
ctypes.byref(uof),
ctypes.sizeof(uof),
try:
import ctypes
+ import ctypes.util
except ImportError:
ctypes = None
if ctypes:
# format: "T{>l:x:>d:y:}"
- class BEPoint(ctypes.BigEndianStructure):
- _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_double)]
+ @ctypes.util.struct(endian='big')
+ class BEPoint:
+ x: ctypes.c_long
+ y: ctypes.c_double
+
point = BEPoint(100, 200.1)
m1 = memoryview(point)
m2 = m1.cast('B')
# Some ctypes format strings are unknown to the struct module.
if ctypes:
# format: "T{>l:x:>l:y:}"
- class BEPoint(ctypes.BigEndianStructure):
- _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]
+ @ctypes.util.struct(endian='big')
+ class BEPoint:
+ x: ctypes.c_long
+ y: ctypes.c_long
+
point = BEPoint(100, 200)
a = memoryview(point)
b = memoryview(point)
# Unknown formats are handled: tobytes() purely depends on itemsize.
if ctypes:
# format: "T{>l:x:>l:y:}"
- class BEPoint(ctypes.BigEndianStructure):
- _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]
+ @ctypes.util.struct(endian='big')
+ class BEPoint:
+ x: ctypes.c_long
+ y: ctypes.c_long
+
point = BEPoint(100, 200)
a = memoryview(point)
self.assertEqual(a.tobytes(), bytes(point))
self.assertEqual(coder(input), (expect, len(input)))
return check
-# On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present
+# On small versions of Windows like Windows IoT or Windows Nano Server,
+# not all codepages are present
def is_code_page_present(cp):
- from ctypes import POINTER, WINFUNCTYPE, WinDLL, Structure
+ from ctypes import POINTER, WINFUNCTYPE, WinDLL
+ from ctypes.util import struct
from ctypes.wintypes import BOOL, BYTE, WCHAR, UINT, DWORD
MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term.
MAX_DEFAULTCHAR = 2 # single or double byte
MAX_PATH = 260
- class CPINFOEXW(Structure):
- _fields_ = [("MaxCharSize", UINT),
- ("DefaultChar", BYTE*MAX_DEFAULTCHAR),
- ("LeadByte", BYTE*MAX_LEADBYTES),
- ("UnicodeDefaultChar", WCHAR),
- ("CodePage", UINT),
- ("CodePageName", WCHAR*MAX_PATH)]
+
+ @struct
+ class CPINFOEXW:
+ MaxCharSize: UINT
+ DefaultChar: BYTE * MAX_DEFAULTCHAR
+ LeadByte: BYTE * MAX_LEADBYTES
+ UnicodeDefaultChar: WCHAR
+ CodePage: UINT
+ CodePageName: WCHAR * MAX_PATH
prototype = WINFUNCTYPE(BOOL, UINT, DWORD, POINTER(CPINFOEXW))
GetCPInfoEx = prototype(("GetCPInfoExW", WinDLL("kernel32")))
gc.collect()
self.assertEqual(sys.getrefcount(func), orig_refcount)
- class X(ctypes.Structure):
- _fields_ = [("a", OtherCallback)]
+ @ctypes.util.struct
+ class X:
+ a: OtherCallback
+
x = X()
x.a = OtherCallback(func)
-import ctypes
+import ctypes.util
import unittest
from test.support import import_helper
_ctypes_test = import_helper.import_module("_ctypes_test")
self.assertEqual(buf[6:5:-1], "")
def test_embedded_null(self):
- class TestStruct(ctypes.Structure):
- _fields_ = [("unicode", ctypes.c_wchar_p)]
+ @ctypes.util.struct
+ class TestStruct:
+ unicode: ctypes.c_wchar_p
+
t = TestStruct()
# This would raise a ValueError:
t.unicode = "foo\0bar\0\0"
-import ctypes
+import ctypes.util
import gc
import sys
import unittest
E_NOINTERFACE = -2147467262
-class GUID(ctypes.Structure):
+@ctypes.util.struct
+class GUID:
# https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid
- _fields_ = [
- ("Data1", DWORD),
- ("Data2", WORD),
- ("Data3", WORD),
- ("Data4", BYTE * 8),
- ]
+ Data1: DWORD
+ Data2: WORD
+ Data3: WORD
+ Data4: BYTE * 8
def create_proto_com_method(name, index, restype, *argtypes):
try:
- import ctypes
+ import ctypes.util
except ImportError:
def byteslike(*pos, **kw):
return array.array("b", bytes(*pos, **kw))
else:
- class EmptyStruct(ctypes.Structure):
+ @ctypes.util.struct
+ class EmptyStruct:
pass
def byteslike(*pos, **kw):