X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 90 additions & 10 deletions Lib/ctypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
from _ctypes import ArgumentError
from _ctypes import SIZEOF_TIME_T
from _ctypes import CField

from struct import calcsize as _calcsize

if __version__ != _ctypes_version:
raise Exception("Version number mismatch", __version__, _ctypes_version)

if _os.name == "nt":
from _ctypes import FormatError
from _ctypes import COMError, CopyComPointer, FormatError

DEFAULT_MODE = RTLD_LOCAL
if _os.name == "posix" and _sys.platform == "darwin":
Expand Down Expand Up @@ -208,6 +209,18 @@ class c_longdouble(_SimpleCData):
if sizeof(c_longdouble) == sizeof(c_double):
c_longdouble = c_double

try:
class c_double_complex(_SimpleCData):
_type_ = "D"
_check_size(c_double_complex)
class c_float_complex(_SimpleCData):
_type_ = "F"
_check_size(c_float_complex)
class c_longdouble_complex(_SimpleCData):
_type_ = "G"
except AttributeError:
pass

if _calcsize("l") == _calcsize("q"):
# if long and long long have the same size, make c_longlong an alias for c_long
c_longlong = c_long
Expand Down Expand Up @@ -255,7 +268,72 @@ class c_void_p(_SimpleCData):
class c_bool(_SimpleCData):
_type_ = "?"

from _ctypes import POINTER, pointer, _pointer_type_cache
def POINTER(cls):
"""Create and return a new ctypes pointer type.

Pointer types are cached and reused internally,
so calling this function repeatedly is cheap.
"""
if cls is None:
return c_void_p
try:
return cls.__pointer_type__
except AttributeError:
pass
if isinstance(cls, str):
# handle old-style incomplete types (see test_ctypes.test_incomplete)
import warnings
warnings._deprecated("ctypes.POINTER with string", remove=(3, 19))
try:
return _pointer_type_cache_fallback[cls]
except KeyError:
result = type(f'LP_{cls}', (_Pointer,), {})
_pointer_type_cache_fallback[cls] = result
return result

# create pointer type and set __pointer_type__ for cls
return type(f'LP_{cls.__name__}', (_Pointer,), {'_type_': cls})

def pointer(obj):
"""Create a new pointer instance, pointing to 'obj'.

The returned object is of the type POINTER(type(obj)). Note that if you
just want to pass a pointer to an object to a foreign function call, you
should use byref(obj) which is much faster.
"""
typ = POINTER(type(obj))
return typ(obj)

class _PointerTypeCache:
def __setitem__(self, cls, pointer_type):
import warnings
warnings._deprecated("ctypes._pointer_type_cache", remove=(3, 19))
try:
cls.__pointer_type__ = pointer_type
except AttributeError:
_pointer_type_cache_fallback[cls] = pointer_type

def __getitem__(self, cls):
import warnings
warnings._deprecated("ctypes._pointer_type_cache", remove=(3, 19))
try:
return cls.__pointer_type__
except AttributeError:
return _pointer_type_cache_fallback[cls]

def get(self, cls, default=None):
import warnings
warnings._deprecated("ctypes._pointer_type_cache", remove=(3, 19))
try:
return cls.__pointer_type__
except AttributeError:
return _pointer_type_cache_fallback.get(cls, default)

def __contains__(self, cls):
return hasattr(cls, '__pointer_type__')

_pointer_type_cache_fallback = {}
_pointer_type_cache = _PointerTypeCache()

class c_wchar_p(_SimpleCData):
_type_ = "Z"
Expand All @@ -266,15 +344,14 @@ class c_wchar(_SimpleCData):
_type_ = "u"

def _reset_cache():
_pointer_type_cache.clear()
_pointer_type_cache_fallback.clear()
_c_functype_cache.clear()
if _os.name == "nt":
_win_functype_cache.clear()
# _SimpleCData.c_wchar_p_from_param
POINTER(c_wchar).from_param = c_wchar_p.from_param
# _SimpleCData.c_char_p_from_param
POINTER(c_char).from_param = c_char_p.from_param
_pointer_type_cache[None] = c_void_p

def create_unicode_buffer(init, size=None):
"""create_unicode_buffer(aString) -> character array
Expand Down Expand Up @@ -308,13 +385,7 @@ def create_unicode_buffer(init, size=None):
def SetPointerType(pointer, cls):
import warnings
warnings._deprecated("ctypes.SetPointerType", remove=(3, 15))
if _pointer_type_cache.get(cls, None) is not None:
raise RuntimeError("This type already exists in the cache")
if id(pointer) not in _pointer_type_cache:
raise RuntimeError("What's this???")
pointer.set_type(cls)
_pointer_type_cache[cls] = pointer
del _pointer_type_cache[id(pointer)]

def ARRAY(typ, len):
return typ * len
Expand Down Expand Up @@ -521,6 +592,7 @@ def WinError(code=None, descr=None):
# functions

from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
from _ctypes import _memoryview_at_addr

## void *memmove(void *, const void *, size_t);
memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
Expand All @@ -546,6 +618,14 @@ def string_at(ptr, size=-1):
Return the byte string at void *ptr."""
return _string_at(ptr, size)

_memoryview_at = PYFUNCTYPE(
py_object, c_void_p, c_ssize_t, c_int)(_memoryview_at_addr)
def memoryview_at(ptr, size, readonly=False):
"""memoryview_at(ptr, size[, readonly]) -> memoryview

Return a memoryview representing the memory at void *ptr."""
return _memoryview_at(ptr, size, bool(readonly))

try:
from _ctypes import _wstring_at_addr
except ImportError:
Expand Down
Loading
Loading
X Tutup