cpython/Modules/_ctypes/_ctypes.c

/*
  ToDo:

  Get rid of the checker (and also the converters) field in PyCFuncPtrObject and
  StgInfo, and replace them by slot functions in StgInfo.

  think about a buffer-like object (memory? bytes?)

  Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
  What about c_char and c_wchar arrays then?

  Add from_mmap, from_file, from_string metaclass methods.

  Maybe we can get away with from_file (calls read) and with a from_buffer
  method?

  And what about the to_mmap, to_file, to_str(?) methods?  They would clobber
  the namespace, probably. So, functions instead? And we already have memmove...
*/

/*

Name                    methods, members, getsets
==============================================================================

PyCStructType_Type              __new__(), from_address(), __mul__(), from_param()
UnionType_Type                  __new__(), from_address(), __mul__(), from_param()
PyCPointerType_Type             __new__(), from_address(), __mul__(), from_param(), set_type()
PyCArrayType_Type               __new__(), from_address(), __mul__(), from_param()
PyCSimpleType_Type              __new__(), from_address(), __mul__(), from_param()

PyCData_Type
  Struct_Type                   __new__(), __init__()
  PyCPointer_Type               __new__(), __init__(), _as_parameter_, contents
  PyCArray_Type                 __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
  Simple_Type                   __new__(), __init__(), _as_parameter_

PyCField_Type

==============================================================================

class methods
-------------

It has some similarity to the byref() construct compared to pointer()
from_address(addr)
    - construct an instance from a given memory block (sharing this memory block)

from_param(obj)
    - typecheck and convert a Python object into a C function call parameter
      The result may be an instance of the type, or an integer or tuple
      (typecode, value[, obj])

instance methods/properties
---------------------------

_as_parameter_
    - convert self into a C function call parameter
      This is either an integer, or a 3-tuple (typecode, value, obj)

functions
---------

sizeof(cdata)
    - return the number of bytes the buffer contains

sizeof(ctype)
    - return the number of bytes the buffer of an instance would contain

byref(cdata)

addressof(cdata)

pointer(cdata)

POINTER(ctype)

bytes(cdata)
    - return the buffer contents as a sequence of bytes (which is currently a string)

*/

/*
 * PyCStructType_Type
 * UnionType_Type
 * PyCPointerType_Type
 * PyCArrayType_Type
 * PyCSimpleType_Type
 *
 * PyCData_Type
 * Struct_Type
 * Union_Type
 * PyCArray_Type
 * Simple_Type
 * PyCPointer_Type
 * PyCField_Type
 *
 */
#ifndef Py_BUILD_CORE_BUILTIN
#define Py_BUILD_CORE_MODULE
#endif

#include "Python.h"
// windows.h must be included before pycore internal headers
#ifdef MS_WIN32
#  include <windows.h>
#endif

#include "pycore_call.h"          // _PyObject_CallNoArgs()
#include "pycore_ceval.h"         // _Py_EnterRecursiveCall()
#ifdef MS_WIN32
#  include "pycore_modsupport.h"  // _PyArg_NoKeywords()
#endif


#include <ffi.h>
#ifdef MS_WIN32
#include <malloc.h>
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE
#endif
#else
#include <dlfcn.h>
#endif
#include "ctypes.h"

#include "pycore_long.h"          // _PyLong_GetZero()

/*[clinic input]
module _ctypes
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=476a19c49b31a75c]*/

#define clinic_state
#define clinic_state_sub
#include "clinic/_ctypes.c.h"
#undef clinic_state
#undef clinic_state_sub

/****************************************************************/

DictRemoverObject;

static int
_DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg)
{}

static int
_DictRemover_clear(DictRemoverObject *self)
{}

static void
_DictRemover_dealloc(PyObject *myself)
{}

static PyObject *
_DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
{}

PyDoc_STRVAR(dictremover_doc, "deletes a key from a dictionary");

static PyType_Slot dictremover_slots[] =;

static PyType_Spec dictremover_spec =;

int
PyDict_SetItemProxy(ctypes_state *st, PyObject *dict, PyObject *key, PyObject *item)
{}

static int
_PyDict_GetItemProxy(PyObject *dict, PyObject *key, PyObject **presult)
{}

/******************************************************************/

/*
  Allocate a memory block for a pep3118 format string, filled with
  a suitable PEP 3118 type code corresponding to the given ctypes
  type. Returns NULL on failure, with the error indicator set.

  This produces type codes in the standard size mode (cf. struct module),
  since the endianness may need to be swapped to a non-native one
  later on.
 */
static char *
_ctypes_alloc_format_string_for_type(char code, int big_endian)
{}

/*
  Allocate a memory block for a pep3118 format string, copy prefix (if
  non-null) and suffix into it.  Returns NULL on failure, with the error
  indicator set.  If called with a suffix of NULL the error indicator must
  already be set.
 */
static char *
_ctypes_alloc_format_string(const char *prefix, const char *suffix)
{}

/*
  Allocate a memory block for a pep3118 format string, adding
  the given prefix (if non-null), an additional shape prefix, and a suffix.
  Returns NULL on failure, with the error indicator set.  If called with
  a suffix of NULL the error indicator must already be set.
 */
static char *
_ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
                                       const char *prefix, const char *suffix)
{}

/* StructParamObject and StructParam_Type are used in _ctypes_callproc()
   for argument.keep to call PyMem_Free(ptr) on Py_DECREF(argument).

   StructUnionType_paramfunc() creates such object when a ctypes Structure is
   passed by copy to a C function. */
StructParamObject;

static int
StructParam_traverse(StructParamObject *self, visitproc visit, void *arg)
{}

static int
StructParam_clear(StructParamObject *self)
{}

static void
StructParam_dealloc(PyObject *myself)
{}

static PyType_Slot structparam_slots[] =;

static PyType_Spec structparam_spec =;

/*
  CType_Type - a base metaclass. Its instances (classes) have a StgInfo.
  */

/*[clinic input]
class _ctypes.CType_Type "PyObject *" "clinic_state()->CType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8389fc5b74a84f2a]*/

static int
CType_Type_traverse(PyObject *self, visitproc visit, void *arg)
{}

void
ctype_clear_stginfo(StgInfo *info)
{}

static int
CType_Type_clear(PyObject *self)
{}

static void
CType_Type_dealloc(PyObject *self)
{}

/*[clinic input]
_ctypes.CType_Type.__sizeof__

    cls: defining_class
    /
Return memory consumption of the type object.
[clinic start generated code]*/

static PyObject *
_ctypes_CType_Type___sizeof___impl(PyObject *self, PyTypeObject *cls)
/*[clinic end generated code: output=c68c235be84d03f3 input=d064433b6110d1ce]*/
{}

static PyObject *
CType_Type_repeat(PyObject *self, Py_ssize_t length);


static PyMethodDef ctype_methods[] =;

static PyType_Slot ctype_type_slots[] =;

PyType_Spec pyctype_type_spec =;

/*
  PyCStructType_Type - a meta type/class.  Creating a new class using this one as
  __metaclass__ will call the constructor StructUnionType_new.
  It initializes the C accessible fields somehow.
*/

static PyCArgObject *
StructUnionType_paramfunc(ctypes_state *st, CDataObject *self)
{}

static int
StructUnionType_init(PyObject *self, PyObject *args, PyObject *kwds, int isStruct)
{}

static int
PyCStructType_init(PyObject *self, PyObject *args, PyObject *kwds)
{}

static int
UnionType_init(PyObject *self, PyObject *args, PyObject *kwds)
{}

/*[clinic input]
class _ctypes.CDataType "PyObject *" "clinic_state()->CType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=466a505a93d73156]*/


/*[clinic input]
_ctypes.CDataType.from_address as CDataType_from_address

    type: self
    cls: defining_class
    value: object
    /

C.from_address(integer) -> C instance

Access a C instance at the specified address.
[clinic start generated code]*/

static PyObject *
CDataType_from_address_impl(PyObject *type, PyTypeObject *cls,
                            PyObject *value)
/*[clinic end generated code: output=5be4a7c0d9aa6c74 input=827a22cefe380c01]*/
{}

static int
KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);

/*[clinic input]
_ctypes.CDataType.from_buffer as CDataType_from_buffer

    type: self
    cls: defining_class
    obj: object
    offset: Py_ssize_t = 0
    /

C.from_buffer(object, offset=0) -> C instance

Create a C instance from a writeable buffer.
[clinic start generated code]*/

static PyObject *
CDataType_from_buffer_impl(PyObject *type, PyTypeObject *cls, PyObject *obj,
                           Py_ssize_t offset)
/*[clinic end generated code: output=57604e99635abd31 input=0f36cedd105ca28d]*/
{}

static inline PyObject *
generic_pycdata_new(ctypes_state *st,
                    PyTypeObject *type, PyObject *args, PyObject *kwds);

static PyObject *
GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

/*[clinic input]
_ctypes.CDataType.from_buffer_copy as CDataType_from_buffer_copy

    type: self
    cls: defining_class
    buffer: Py_buffer
    offset: Py_ssize_t = 0
    /

C.from_buffer_copy(object, offset=0) -> C instance

Create a C instance from a readable buffer.
[clinic start generated code]*/

static PyObject *
CDataType_from_buffer_copy_impl(PyObject *type, PyTypeObject *cls,
                                Py_buffer *buffer, Py_ssize_t offset)
/*[clinic end generated code: output=c8fc62b03e5cc6fa input=2a81e11b765a6253]*/
{}

/*[clinic input]
_ctypes.CDataType.in_dll as CDataType_in_dll

    type: self
    cls: defining_class
    dll: object
    name: str
    /

C.in_dll(dll, name) -> C instance

Access a C instance in a dll.
[clinic start generated code]*/

static PyObject *
CDataType_in_dll_impl(PyObject *type, PyTypeObject *cls, PyObject *dll,
                      const char *name)
/*[clinic end generated code: output=d0e5c43b66bfa21f input=f85bf281477042b4]*/
{}

/*[clinic input]
_ctypes.CDataType.from_param as CDataType_from_param

    type: self
    cls: defining_class
    value: object
    /

Convert a Python object into a function call parameter.
[clinic start generated code]*/

static PyObject *
CDataType_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
/*[clinic end generated code: output=8da9e34263309f9e input=275a52c4899ddff0]*/
{}

static PyMethodDef CDataType_methods[] =;

static PyObject *
CType_Type_repeat(PyObject *self, Py_ssize_t length)
{}

static int
_structunion_setattro(PyObject *self, PyObject *key, PyObject *value, int is_struct)
{}

static int
PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
{}

static int
UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
{}

static PyType_Slot pycstruct_type_slots[] =;

static PyType_Spec pycstruct_type_spec =;

static PyType_Slot union_type_slots[] =;

static PyType_Spec union_type_spec =;

/******************************************************************/

/*

The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be
created. It must check for a _type_ attribute in the class. Since are no
runtime created properties, a CField is probably *not* needed ?

class IntPointer(Pointer):
    _type_ = "i"

The PyCPointer_Type provides the functionality: a contents method/property, a
size property/method, and the sequence protocol.

*/

/*[clinic input]
class _ctypes.PyCPointerType "PyObject *" "clinic_state()->PyCPointerType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c45e96c1f7645ab7]*/


static int
PyCPointerType_SetProto(ctypes_state *st, StgInfo *stginfo, PyObject *proto)
{}

static PyCArgObject *
PyCPointerType_paramfunc(ctypes_state *st, CDataObject *self)
{}

static int
PyCPointerType_init(PyObject *self, PyObject *args, PyObject *kwds)
{}

/*[clinic input]
_ctypes.PyCPointerType.set_type as PyCPointerType_set_type

    self: self(type="PyTypeObject *")
    cls: defining_class
    type: object
    /
[clinic start generated code]*/

static PyObject *
PyCPointerType_set_type_impl(PyTypeObject *self, PyTypeObject *cls,
                             PyObject *type)
/*[clinic end generated code: output=51459d8f429a70ac input=67e1e8df921f123e]*/
{}

static PyObject *_byref(ctypes_state *, PyObject *);

/*[clinic input]
_ctypes.PyCPointerType.from_param as PyCPointerType_from_param

    type: self
    cls: defining_class
    value: object
    /

Convert a Python object into a function call parameter.
[clinic start generated code]*/

static PyObject *
PyCPointerType_from_param_impl(PyObject *type, PyTypeObject *cls,
                               PyObject *value)
/*[clinic end generated code: output=a4b32d929aabaf64 input=6c231276e3997884]*/
{}

static PyMethodDef PyCPointerType_methods[] =;

static PyType_Slot pycpointer_type_slots[] =;

static PyType_Spec pycpointer_type_spec =;


/******************************************************************/
/*
  PyCArrayType_Type
*/
/*
  PyCArrayType_init ensures that the new Array subclass created has a _length_
  attribute, and a _type_ attribute.
*/

static int
CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
{}

static PyObject *
CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
{}

static PyObject *
CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
{}

static int
CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
{}

static PyGetSetDef CharArray_getsets[] =;

static PyObject *
WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
{}

static int
WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
{}

static PyGetSetDef WCharArray_getsets[] =;

/*
  The next function is copied from Python's typeobject.c.

  It is used to attach getsets to a type *after* it
  has been created: Arrays of characters have additional getsets to treat them
  as strings.
 */

static int
add_getset(PyTypeObject *type, PyGetSetDef *gsp)
{}

static PyCArgObject *
PyCArrayType_paramfunc(ctypes_state *st, CDataObject *self)
{}

static int
PyCArrayType_init(PyObject *self, PyObject *args, PyObject *kwds)
{}

static PyType_Slot pycarray_type_slots[] =;

static PyType_Spec pycarray_type_spec =;

/******************************************************************/
/*
  PyCSimpleType_Type
*/
/*

PyCSimpleType_init ensures that the new Simple_Type subclass created has a valid
_type_ attribute.

*/

/*[clinic input]
class _ctypes.PyCSimpleType "PyObject *" "clinic_state()->PyCSimpleType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d5a45772668e7f49]*/

/*[clinic input]
class _ctypes.c_wchar_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=468de7283d622d47]*/

/*[clinic input]
class _ctypes.c_char_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e750865616e7dcea]*/

/*[clinic input]
class _ctypes.c_void_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd4d9646c56f43a9]*/

#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdCEFfuzZqQPXOv?g";
#else
static const char SIMPLE_TYPE_CHARS[] =;
#endif

/*[clinic input]
_ctypes.c_wchar_p.from_param as c_wchar_p_from_param

    type: self
    cls: defining_class
    value: object
    /
[clinic start generated code]*/

static PyObject *
c_wchar_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
/*[clinic end generated code: output=e453949a2f725a4c input=d322c7237a319607]*/
{}

/*[clinic input]
_ctypes.c_char_p.from_param as c_char_p_from_param

    type: self
    cls: defining_class
    value: object
    /
[clinic start generated code]*/

static PyObject *
c_char_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
/*[clinic end generated code: output=219652ab7c174aa1 input=6cf0d1b6bb4ede11]*/
{}

/*[clinic input]
_ctypes.c_void_p.from_param as c_void_p_from_param

    type: self
    cls: defining_class
    value: object
    /
[clinic start generated code]*/

static PyObject *
c_void_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
/*[clinic end generated code: output=984d0075b6038cc7 input=0e8b343fc19c77d4]*/
{}

static PyMethodDef c_void_p_methods[] =;
static PyMethodDef c_char_p_methods[] =;
static PyMethodDef c_wchar_p_methods[] =;

static PyObject *CreateSwappedType(ctypes_state *st, PyTypeObject *type,
                                   PyObject *args, PyObject *kwds,
                                   PyObject *proto, struct fielddesc *fmt)
{}

static PyCArgObject *
PyCSimpleType_paramfunc(ctypes_state *st, CDataObject *self)
{}

static int
PyCSimpleType_init(PyObject *self, PyObject *args, PyObject *kwds)
{}

/*
 * This is a *class method*.
 * Convert a parameter into something that ConvParam can handle.
 */

/*[clinic input]
_ctypes.PyCSimpleType.from_param as PyCSimpleType_from_param

    type: self
    cls: defining_class
    value: object
    /

Convert a Python object into a function call parameter.
[clinic start generated code]*/

static PyObject *
PyCSimpleType_from_param_impl(PyObject *type, PyTypeObject *cls,
                              PyObject *value)
/*[clinic end generated code: output=8a8453d9663e3a2e input=61cc48ce3a87a570]*/
{}

static PyMethodDef PyCSimpleType_methods[] =;

static PyType_Slot pycsimple_type_slots[] =;

static PyType_Spec pycsimple_type_spec =;

/******************************************************************/
/*
  PyCFuncPtrType_Type
 */

static PyObject *
converters_from_argtypes(ctypes_state *st, PyObject *ob)
{}

static int
make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
{}

static PyCArgObject *
PyCFuncPtrType_paramfunc(ctypes_state *st, CDataObject *self)
{}

static int
PyCFuncPtrType_init(PyObject *self, PyObject *args, PyObject *kwds)
{}

static PyType_Slot pycfuncptr_type_slots[] =;

static PyType_Spec pycfuncptr_type_spec =;


/*****************************************************************
 * Code to keep needed objects alive
 */

static CDataObject *
PyCData_GetContainer(CDataObject *self)
{}

static PyObject *
GetKeepedObjects(CDataObject *target)
{}

static PyObject *
unique_key(CDataObject *target, Py_ssize_t index)
{}

/*
 * Keep a reference to 'keep' in the 'target', at index 'index'.
 *
 * If 'keep' is None, do nothing.
 *
 * Otherwise create a dictionary (if it does not yet exist) id the root
 * objects 'b_objects' item, which will store the 'keep' object under a unique
 * key.
 *
 * The unique_key helper travels the target's b_base pointer down to the root,
 * building a string containing hex-formatted indexes found during traversal,
 * separated by colons.
 *
 * The index tuple is used as a key into the root object's b_objects dict.
 *
 * Note: This function steals a refcount of the third argument, even if it
 * fails!
 */
static int
KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
{}

/******************************************************************/
/*
  PyCData_Type
 */

/*[clinic input]
class _ctypes.PyCData "PyObject *" "clinic_state()->PyCData_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ac13df38dee3c22c]*/


static int
PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
{}

static int
PyCData_clear(CDataObject *self)
{}

static void
PyCData_dealloc(PyObject *self)
{}

static PyMemberDef PyCData_members[] =;

/* Find the innermost type of an array type, returning a borrowed reference */
static PyObject *
PyCData_item_type(ctypes_state *st, PyObject *type)
{}

static int
PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
{}

/*
 * CData objects are mutable, so they cannot be hashable!
 */
static Py_hash_t
PyCData_nohash(PyObject *self)
{}

/*[clinic input]
_ctypes.PyCData.__reduce__ as PyCData_reduce

    myself: self
    cls: defining_class
    /
[clinic start generated code]*/

static PyObject *
PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
/*[clinic end generated code: output=1a025ccfdd8c935d input=34097a5226ea63c1]*/
{}

static PyObject *
PyCData_setstate(PyObject *myself, PyObject *args)
{}

/*
 * default __ctypes_from_outparam__ method returns self.
 */
static PyObject *
PyCData_from_outparam(PyObject *self, PyObject *args)
{}

static PyMethodDef PyCData_methods[] =;

static PyType_Slot pycdata_slots[] =;

static PyType_Spec pycdata_spec =;

static int
PyCData_MallocBuffer(CDataObject *obj, StgInfo *info)
{}

PyObject *
PyCData_FromBaseObj(ctypes_state *st,
                    PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
{}

/*
 Box a memory block into a CData instance.
*/
PyObject *
PyCData_AtAddress(ctypes_state *st, PyObject *type, void *buf)
{}

/*
  This function returns TRUE for c_int, c_void_p, and these kind of
  classes.  FALSE otherwise FALSE also for subclasses of c_int and
  such.
*/
int _ctypes_simple_instance(ctypes_state *st, PyObject *obj)
{}

PyObject *
PyCData_get(ctypes_state *st, PyObject *type, GETFUNC getfunc, PyObject *src,
          Py_ssize_t index, Py_ssize_t size, char *adr)
{}

/*
  Helper function for PyCData_set below.
*/
static PyObject *
_PyCData_set(ctypes_state *st,
           CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
           Py_ssize_t size, char *ptr)
{}

/*
 * Set a slice in object 'dst', which has the type 'type',
 * to the value 'value'.
 */
int
PyCData_set(ctypes_state *st,
          PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
          Py_ssize_t index, Py_ssize_t size, char *ptr)
{}


/******************************************************************/
static PyObject *
GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{}

static inline PyObject *
generic_pycdata_new(ctypes_state *st,
                    PyTypeObject *type, PyObject *args, PyObject *kwds)
{}
/*****************************************************************/
/*
  PyCFuncPtr_Type
*/

static int
PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{}

static PyObject *
PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
{}

static int
PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{}

static PyObject *
PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
{}

static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{}

static PyObject *
PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
{}

static PyGetSetDef PyCFuncPtr_getsets[] =;

#ifdef MS_WIN32
static PPROC FindAddress(void *handle, const char *name, PyObject *type)
{
    PPROC address;
#ifdef MS_WIN64
    /* win64 has no stdcall calling conv, so it should
       also not have the name mangling of it.
    */
    Py_BEGIN_ALLOW_THREADS
    address = (PPROC)GetProcAddress(handle, name);
    Py_END_ALLOW_THREADS
    return address;
#else
    char *mangled_name;
    int i;

    Py_BEGIN_ALLOW_THREADS
    address = (PPROC)GetProcAddress(handle, name);
    Py_END_ALLOW_THREADS
    if (address)
        return address;
    if (((size_t)name & ~0xFFFF) == 0) {
        return NULL;
    }

    ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
    StgInfo *info;
    if (PyStgInfo_FromType(st, (PyObject *)type, &info) < 0) {
        return NULL;
    }
    /* It should not happen that info is NULL, but better be safe */
    if (info==NULL || info->flags & FUNCFLAG_CDECL)
        return address;

    /* for stdcall, try mangled names:
       funcname -> _funcname@<n>
       where n is 0, 4, 8, 12, ..., 128
     */
    mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
    if (!mangled_name)
        return NULL;
    for (i = 0; i < 32; ++i) {
        sprintf(mangled_name, "_%s@%d", name, i*4);
        Py_BEGIN_ALLOW_THREADS
        address = (PPROC)GetProcAddress(handle, mangled_name);
        Py_END_ALLOW_THREADS
        if (address)
            return address;
    }
    return NULL;
#endif
}
#endif

/* Return 1 if usable, 0 else and exception set. */
static int
_check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
{}

/* Returns 1 on success, 0 on error */
static int
_validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
{}

static int
_get_name(PyObject *obj, const char **pname)
{}


static PyObject *
PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
{}

#ifdef MS_WIN32
static PyObject *
PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyCFuncPtrObject *self;
    int index;
    char *name = NULL;
    PyObject *paramflags = NULL;
    GUID *iid = NULL;
    Py_ssize_t iid_len = 0;

    if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
        return NULL;
    if (paramflags == Py_None)
        paramflags = NULL;

    ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
    if (!_validate_paramflags(st, type, paramflags)) {
        return NULL;
    }
    self = (PyCFuncPtrObject *)generic_pycdata_new(st, type, args, kwds);
    self->index = index + 0x1000;
    self->paramflags = Py_XNewRef(paramflags);
    if (iid_len == sizeof(GUID))
        self->iid = iid;
    return (PyObject *)self;
}
#endif

/*
  PyCFuncPtr_new accepts different argument lists in addition to the standard
  _basespec_ keyword arg:

  one argument form
  "i" - function address
  "O" - must be a callable, creates a C callable function

  two or more argument forms (the third argument is a paramflags tuple)
  "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
  "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
  "is|..." - vtable index, method name, creates callable calling COM vtbl
*/
static PyObject *
PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{}


/*
  _byref consumes a refcount to its argument
*/
static PyObject *
_byref(ctypes_state *st, PyObject *obj)
{}

static PyObject *
_get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
{}

/*
 This function implements higher level functionality plus the ability to call
 functions with keyword arguments by looking at parameter flags.  parameter
 flags is a tuple of 1, 2 or 3-tuples.  The first entry in each is an integer
 specifying the direction of the data transfer for this parameter - 'in',
 'out' or 'inout' (zero means the same as 'in').  The second entry is the
 parameter name, and the third is the default value if the parameter is
 missing in the function call.

 This function builds and returns a new tuple 'callargs' which contains the
 parameters to use in the call.  Items on this tuple are copied from the
 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
 'argtypes' tuple for 'out' parameters.  It also calculates numretvals which
 is the number of return values for the function, outmask/inoutmask are
 bitmasks containing indexes into the callargs tuple specifying which
 parameters have to be returned.  _build_result builds the return value of the
 function.
*/
static PyObject *
_build_callargs(ctypes_state *st, PyCFuncPtrObject *self, PyObject *argtypes,
                PyObject *inargs, PyObject *kwds,
                int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
{}

/* See also:
   http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
*/
/*
  Build return value of a function.

  Consumes the refcount on result and callargs.
*/
static PyObject *
_build_result(PyObject *result, PyObject *callargs,
              int outmask, int inoutmask, unsigned int numretvals)
{}

static PyObject *
PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
{}

static int
PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
{}

static int
PyCFuncPtr_clear(PyCFuncPtrObject *self)
{}

static void
PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
{}

static PyObject *
PyCFuncPtr_repr(PyCFuncPtrObject *self)
{}

static int
PyCFuncPtr_bool(PyCFuncPtrObject *self)
{}

static PyType_Slot pycfuncptr_slots[] =;

static PyType_Spec pycfuncptr_spec =;

/*****************************************************************/
/*
  Struct_Type
*/
/*
  This function is called to initialize a Structure or Union with positional
  arguments. It calls itself recursively for all Structure or Union base
  classes, then retrieves the _fields_ member to associate the argument
  position with the correct field name.

  Returns -1 on error, or the index of next argument on success.
 */
static Py_ssize_t
_init_pos_args(PyObject *self, PyTypeObject *type,
               PyObject *args, PyObject *kwds,
               Py_ssize_t index)
{}

static int
Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
{}

static PyType_Slot pycstruct_slots[] =;

static PyType_Spec pycstruct_spec =;

static PyType_Slot pycunion_slots[] =;

static PyType_Spec pycunion_spec =;


/******************************************************************/
/*
  PyCArray_Type
*/
static int
Array_init(CDataObject *self, PyObject *args, PyObject *kw)
{}

static PyObject *
Array_item(PyObject *myself, Py_ssize_t index)
{}

static PyObject *
Array_subscript(PyObject *myself, PyObject *item)
{}

static int
Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
{}

static int
Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
{}

static Py_ssize_t
Array_length(PyObject *myself)
{}

static PyMethodDef Array_methods[] =;

PyDoc_STRVAR(array_doc,
"Abstract base class for arrays.\n"
"\n"
"The recommended way to create concrete array types is by multiplying any\n"
"ctypes data type with a non-negative integer. Alternatively, you can subclass\n"
"this type and define _length_ and _type_ class variables. Array elements can\n"
"be read and written using standard subscript and slice accesses for slice\n"
"reads, the resulting object is not itself an Array."
);

static PyType_Slot pycarray_slots[] =;

static PyType_Spec pycarray_spec =;

PyObject *
PyCArrayType_from_ctype(ctypes_state *st, PyObject *itemtype, Py_ssize_t length)
{}


/******************************************************************/
/*
  Simple_Type
*/

/*[clinic input]
class _ctypes.Simple "PyObject *" "clinic_state()->Simple_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=016c476c7aa8b8a8]*/


static int
Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
{}

static int
Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
{}

static PyObject *
Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
{}

static PyGetSetDef Simple_getsets[] =;

/*[clinic input]
_ctypes.Simple.__ctypes_from_outparam__ as Simple_from_outparm

    self: self
    cls: defining_class
    /
[clinic start generated code]*/

static PyObject *
Simple_from_outparm_impl(PyObject *self, PyTypeObject *cls)
/*[clinic end generated code: output=6c61d90da8aa9b4f input=0f362803fb4629d5]*/
{}

static PyMethodDef Simple_methods[] =;

static int Simple_bool(CDataObject *self)
{}

/* "%s(%s)" % (self.__class__.__name__, self.value) */
static PyObject *
Simple_repr(CDataObject *self)
{}

static PyType_Slot pycsimple_slots[] =;

static PyType_Spec pycsimple_spec =;


/******************************************************************/
/*
  PyCPointer_Type
*/
static PyObject *
Pointer_item(PyObject *myself, Py_ssize_t index)
{}

static int
Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
{}

static PyObject *
Pointer_get_contents(CDataObject *self, void *closure)
{}

static int
Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
{}

static PyGetSetDef Pointer_getsets[] =;

static int
Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
{}

static PyObject *
Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{}

static PyObject *
Pointer_subscript(PyObject *myself, PyObject *item)
{}

static int
Pointer_bool(CDataObject *self)
{}

static PyType_Slot pycpointer_slots[] =;

static PyType_Spec pycpointer_spec =;

/******************************************************************/
/*
 *  Module initialization.
 */

PyDoc_STRVAR(_ctypes__doc__,
"Create and manipulate C compatible data types in Python.");

#ifdef MS_WIN32

PyDoc_STRVAR(comerror_doc, "Raised when a COM method call failed.");

int
comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    PyObject *hresult, *text, *details;
    PyObject *a;
    int status;

    if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
        return -1;

    if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details))
        return -1;

    a = PySequence_GetSlice(args, 1, PyTuple_GET_SIZE(args));
    if (!a)
        return -1;
    status = PyObject_SetAttrString(self, "args", a);
    Py_DECREF(a);
    if (status < 0)
        return -1;

    if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
        return -1;

    if (PyObject_SetAttrString(self, "text", text) < 0)
        return -1;

    if (PyObject_SetAttrString(self, "details", details) < 0)
        return -1;

    Py_INCREF(args);
    Py_SETREF(((PyBaseExceptionObject *)self)->args, args);

    return 0;
}

static int
comerror_clear(PyObject *self)
{
    return ((PyTypeObject *)PyExc_BaseException)->tp_clear(self);
}

static int
comerror_traverse(PyObject *self, visitproc visit, void *arg)
{
    Py_VISIT(Py_TYPE(self));
    return ((PyTypeObject *)PyExc_BaseException)->tp_traverse(self, visit, arg);
}

static void
comerror_dealloc(PyObject *self)
{
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    (void)comerror_clear(self);
    tp->tp_free(self);
    Py_DECREF(tp);
}

static PyType_Slot comerror_slots[] = {
    {Py_tp_doc, (void *)PyDoc_STR(comerror_doc)},
    {Py_tp_init, comerror_init},
    {Py_tp_traverse, comerror_traverse},
    {Py_tp_dealloc, comerror_dealloc},
    {Py_tp_clear, comerror_clear},
    {0, NULL},
};

static PyType_Spec comerror_spec = {
    .name = "_ctypes.COMError",
    .basicsize = sizeof(PyBaseExceptionObject),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
              Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
    .slots = comerror_slots,
};

#endif  // MS_WIN32

static PyObject *
string_at(const char *ptr, int size)
{}

static int
cast_check_pointertype(ctypes_state *st, PyObject *arg)
{}

static PyObject *
cast(void *ptr, PyObject *src, PyObject *ctype)
{}


static PyObject *
wstring_at(const wchar_t *ptr, int size)
{}


static int
_ctypes_add_types(PyObject *mod)
{}


static int
_ctypes_add_objects(PyObject *mod)
{}


static int
_ctypes_mod_exec(PyObject *mod)
{}


static int
module_traverse(PyObject *module, visitproc visit, void *arg) {}

static int
module_clear(PyObject *module) {}

static void
module_free(void *module)
{}

static PyModuleDef_Slot module_slots[] =;

struct PyModuleDef _ctypesmodule =;

PyMODINIT_FUNC
PyInit__ctypes(void)
{}

/*
 Local Variables:
 compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
 End:
*/