/*
  ToDo:

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

  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
PyCStgDict_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)

*/

/*
 * PyCStgDict_Type
 * PyCStructType_Type
 * UnionType_Type
 * PyCPointerType_Type
 * PyCArrayType_Type
 * PyCSimpleType_Type
 *
 * PyCData_Type
 * Struct_Type
 * Union_Type
 * PyCArray_Type
 * Simple_Type
 * PyCPointer_Type
 * PyCField_Type
 *
 */

#define PY_SSIZE_T_CLEAN

#include "Python.h"
#include "structmember.h"

#include <ffi.h>
#ifdef MS_WIN32
#include <windows.h>
#include <malloc.h>
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
#endif
# ifdef _WIN32_WCE
/* Unlike desktop Windows, WinCE has both W and A variants of
   GetProcAddress, but the default W version is not what we want */
#  undef GetProcAddress
#  define GetProcAddress GetProcAddressA
# endif
#else
#include "ctypes_dlfcn.h"
#endif
#include "ctypes.h"

PyObject *PyExc_ArgError;

/* This dict maps ctypes types to POINTER types */
PyObject *_ctypes_ptrtype_cache;

static PyTypeObject Simple_Type;

/* a callable object used for unpickling */
static PyObject *_unpickle;



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

typedef struct {
    PyObject_HEAD
    PyObject *key;
    PyObject *dict;
} DictRemoverObject;

static void
_DictRemover_dealloc(PyObject *myself)
{
    DictRemoverObject *self = (DictRemoverObject *)myself;
    Py_XDECREF(self->key);
    Py_XDECREF(self->dict);
    Py_TYPE(self)->tp_free(myself);
}

static PyObject *
_DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
{
    DictRemoverObject *self = (DictRemoverObject *)myself;
    if (self->key && self->dict) {
        if (-1 == PyDict_DelItem(self->dict, self->key))
            /* XXX Error context */
            PyErr_WriteUnraisable(Py_None);
        Py_DECREF(self->key);
        self->key = NULL;
        Py_DECREF(self->dict);
        self->dict = NULL;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static PyTypeObject DictRemover_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.DictRemover",                      /* tp_name */
    sizeof(DictRemoverObject),                  /* tp_basicsize */
    0,                                          /* tp_itemsize */
    _DictRemover_dealloc,                       /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    _DictRemover_call,                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
/* XXX should participate in GC? */
    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
    "deletes a key from a dictionary",          /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    0,                                          /* tp_new */
    0,                                          /* tp_free */
};

int
PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
{
    PyObject *obj;
    DictRemoverObject *remover;
    PyObject *proxy;
    int result;

    obj = PyObject_CallObject((PyObject *)&DictRemover_Type, NULL);
    if (obj == NULL)
        return -1;

    remover = (DictRemoverObject *)obj;
    assert(remover->key == NULL);
    assert(remover->dict == NULL);
    Py_INCREF(key);
    remover->key = key;
    Py_INCREF(dict);
    remover->dict = dict;

    proxy = PyWeakref_NewProxy(item, obj);
    Py_DECREF(obj);
    if (proxy == NULL)
        return -1;

    result = PyDict_SetItem(dict, key, proxy);
    Py_DECREF(proxy);
    return result;
}

PyObject *
PyDict_GetItemProxy(PyObject *dict, PyObject *key)
{
    PyObject *result;
    PyObject *item = PyDict_GetItem(dict, key);

    if (item == NULL)
        return NULL;
    if (!PyWeakref_CheckProxy(item))
        return item;
    result = PyWeakref_GET_OBJECT(item);
    if (result == Py_None)
        return NULL;
    return result;
}

/******************************************************************/
/*
  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.
 */
char *
_ctypes_alloc_format_string(const char *prefix, const char *suffix)
{
    size_t len;
    char *result;

    if (suffix == NULL) {
        assert(PyErr_Occurred());
        return NULL;
    }
    len = strlen(suffix);
    if (prefix)
        len += strlen(prefix);
    result = PyMem_Malloc(len + 1);
    if (result == NULL)
        return NULL;
    if (prefix)
        strcpy(result, prefix);
    else
        result[0] = '\0';
    strcat(result, suffix);
    return result;
}

/*
  PyCStructType_Type - a meta type/class.  Creating a new class using this one as
  __metaclass__ will call the contructor StructUnionType_new.  It replaces the
  tp_dict member with a new instance of StgDict, and initializes the C
  accessible fields somehow.
*/

static PyCArgObject *
StructUnionType_paramfunc(CDataObject *self)
{
    PyCArgObject *parg;
    StgDictObject *stgdict;

    parg = PyCArgObject_new();
    if (parg == NULL)
        return NULL;

    parg->tag = 'V';
    stgdict = PyObject_stgdict((PyObject *)self);
    assert(stgdict); /* Cannot be NULL for structure/union instances */
    parg->pffi_type = &stgdict->ffi_type_pointer;
    /* For structure parameters (by value), parg->value doesn't contain the structure
       data itself, instead parg->value.p *points* to the structure's data
       See also _ctypes.c, function _call_function_pointer().
    */
    parg->value.p = self->b_ptr;
    parg->size = self->b_size;
    Py_INCREF(self);
    parg->obj = (PyObject *)self;
    return parg;
}

static PyObject *
StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
{
    PyTypeObject *result;
    PyObject *fields;
    StgDictObject *dict;

    /* create the new instance (which is a class,
       since we are a metatype!) */
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
    if (!result)
        return NULL;

    /* keep this for bw compatibility */
    if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
        return (PyObject *)result;

    dict = (StgDictObject *)PyObject_CallObject((PyObject *)&PyCStgDict_Type, NULL);
    if (!dict) {
        Py_DECREF(result);
        return NULL;
    }
    /* replace the class dict by our updated stgdict, which holds info
       about storage requirements of the instances */
    if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
        Py_DECREF(result);
        Py_DECREF((PyObject *)dict);
        return NULL;
    }
    Py_DECREF(result->tp_dict);
    result->tp_dict = (PyObject *)dict;
    dict->format = _ctypes_alloc_format_string(NULL, "B");
    if (dict->format == NULL) {
        Py_DECREF(result);
        return NULL;
    }

    dict->paramfunc = StructUnionType_paramfunc;

    fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
    if (!fields) {
        StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);

        if (basedict == NULL)
            return (PyObject *)result;
        /* copy base dict */
        if (-1 == PyCStgDict_clone(dict, basedict)) {
            Py_DECREF(result);
            return NULL;
        }
        dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
        basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
        return (PyObject *)result;
    }

    if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
        Py_DECREF(result);
        return NULL;
    }
    return (PyObject *)result;
}

static PyObject *
PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    return StructUnionType_new(type, args, kwds, 1);
}

static PyObject *
UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    return StructUnionType_new(type, args, kwds, 0);
}

static char from_address_doc[] =
"C.from_address(integer) -> C instance\naccess a C instance at the specified address";

static PyObject *
CDataType_from_address(PyObject *type, PyObject *value)
{
    void *buf;
    if (!PyLong_Check(value)) {
        PyErr_SetString(PyExc_TypeError,
                        "integer expected");
        return NULL;
    }
    buf = (void *)PyLong_AsVoidPtr(value);
    if (PyErr_Occurred())
        return NULL;
    return PyCData_AtAddress(type, buf);
}

static char from_buffer_doc[] =
"C.from_buffer(object, offset=0) -> C instance\ncreate a C instance from a writeable buffer";

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

static PyObject *
CDataType_from_buffer(PyObject *type, PyObject *args)
{
    void *buffer;
    Py_ssize_t buffer_len;
    Py_ssize_t offset = 0;
    PyObject *obj, *result;
    StgDictObject *dict = PyType_stgdict(type);
    assert (dict);

    if (!PyArg_ParseTuple(args,
#if (PY_VERSION_HEX < 0x02050000)
                          "O|i:from_buffer",
#else
                          "O|n:from_buffer",
#endif
                          &obj, &offset))
        return NULL;

    if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len))
        return NULL;

    if (offset < 0) {
        PyErr_SetString(PyExc_ValueError,
                        "offset cannot be negative");
        return NULL;
    }
    if (dict->size > buffer_len - offset) {
        PyErr_Format(PyExc_ValueError,
#if (PY_VERSION_HEX < 0x02050000)
                     "Buffer size too small (%d instead of at least %d bytes)",
#else
                     "Buffer size too small (%zd instead of at least %zd bytes)",
#endif
                     buffer_len, dict->size + offset);
        return NULL;
    }

    result = PyCData_AtAddress(type, (char *)buffer + offset);
    if (result == NULL)
        return NULL;

    Py_INCREF(obj);
    if (-1 == KeepRef((CDataObject *)result, -1, obj)) {
        Py_DECREF(result);
        return NULL;
    }
    return result;
}

static char from_buffer_copy_doc[] =
"C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer";

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

static PyObject *
CDataType_from_buffer_copy(PyObject *type, PyObject *args)
{
    const void *buffer;
    Py_ssize_t buffer_len;
    Py_ssize_t offset = 0;
    PyObject *obj, *result;
    StgDictObject *dict = PyType_stgdict(type);
    assert (dict);

    if (!PyArg_ParseTuple(args,
#if (PY_VERSION_HEX < 0x02050000)
                          "O|i:from_buffer",
#else
                          "O|n:from_buffer",
#endif
                          &obj, &offset))
        return NULL;

    if (-1 == PyObject_AsReadBuffer(obj, (const void**)&buffer, &buffer_len))
        return NULL;

    if (offset < 0) {
        PyErr_SetString(PyExc_ValueError,
                        "offset cannot be negative");
        return NULL;
    }

    if (dict->size > buffer_len - offset) {
        PyErr_Format(PyExc_ValueError,
#if (PY_VERSION_HEX < 0x02050000)
                     "Buffer size too small (%d instead of at least %d bytes)",
#else
                     "Buffer size too small (%zd instead of at least %zd bytes)",
#endif
                     buffer_len, dict->size + offset);
        return NULL;
    }

    result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL);
    if (result == NULL)
        return NULL;
    memcpy(((CDataObject *)result)->b_ptr,
           (char *)buffer+offset, dict->size);
    return result;
}

static char in_dll_doc[] =
"C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";

static PyObject *
CDataType_in_dll(PyObject *type, PyObject *args)
{
    PyObject *dll;
    char *name;
    PyObject *obj;
    void *handle;
    void *address;

    if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
        return NULL;

    obj = PyObject_GetAttrString(dll, "_handle");
    if (!obj)
        return NULL;
    if (!PyLong_Check(obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "the _handle attribute of the second argument must be an integer");
        Py_DECREF(obj);
        return NULL;
    }
    handle = (void *)PyLong_AsVoidPtr(obj);
    Py_DECREF(obj);
    if (PyErr_Occurred()) {
        PyErr_SetString(PyExc_ValueError,
                        "could not convert the _handle attribute to a pointer");
        return NULL;
    }

#ifdef MS_WIN32
    address = (void *)GetProcAddress(handle, name);
    if (!address) {
        PyErr_Format(PyExc_ValueError,
                     "symbol '%s' not found",
                     name);
        return NULL;
    }
#else
    address = (void *)ctypes_dlsym(handle, name);
    if (!address) {
#ifdef __CYGWIN__
/* dlerror() isn't very helpful on cygwin */
        PyErr_Format(PyExc_ValueError,
                     "symbol '%s' not found (%s) ",
                     name);
#else
        PyErr_SetString(PyExc_ValueError, ctypes_dlerror());
#endif
        return NULL;
    }
#endif
    return PyCData_AtAddress(type, address);
}

static char from_param_doc[] =
"Convert a Python object into a function call parameter.";

static PyObject *
CDataType_from_param(PyObject *type, PyObject *value)
{
    PyObject *as_parameter;
    int res = PyObject_IsInstance(value, type);
    if (res == -1)
        return NULL;
    if (res) {
        Py_INCREF(value);
        return value;
    }
    if (PyCArg_CheckExact(value)) {
        PyCArgObject *p = (PyCArgObject *)value;
        PyObject *ob = p->obj;
        const char *ob_name;
        StgDictObject *dict;
        dict = PyType_stgdict(type);

        /* If we got a PyCArgObject, we must check if the object packed in it
           is an instance of the type's dict->proto */
        if(dict && ob) {
            res = PyObject_IsInstance(ob, dict->proto);
            if (res == -1)
                return NULL;
            if (res) {
                Py_INCREF(value);
                return value;
            }
        }
        ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
        PyErr_Format(PyExc_TypeError,
                     "expected %s instance instead of pointer to %s",
                     ((PyTypeObject *)type)->tp_name, ob_name);
        return NULL;
    }

    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
    if (as_parameter) {
        value = CDataType_from_param(type, as_parameter);
        Py_DECREF(as_parameter);
        return value;
    }
    PyErr_Format(PyExc_TypeError,
                 "expected %s instance instead of %s",
                 ((PyTypeObject *)type)->tp_name,
                 Py_TYPE(value)->tp_name);
    return NULL;
}

static PyMethodDef CDataType_methods[] = {
    { "from_param", CDataType_from_param, METH_O, from_param_doc },
    { "from_address", CDataType_from_address, METH_O, from_address_doc },
    { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
    { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
    { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
    { NULL, NULL },
};

static PyObject *
CDataType_repeat(PyObject *self, Py_ssize_t length)
{
    if (length < 0)
        return PyErr_Format(PyExc_ValueError,
                            "Array length must be >= 0, not %zd",
                            length);
    return PyCArrayType_from_ctype(self, length);
}

static PySequenceMethods CDataType_as_sequence = {
    0,                          /* inquiry sq_length; */
    0,                          /* binaryfunc sq_concat; */
    CDataType_repeat,           /* intargfunc sq_repeat; */
    0,                          /* intargfunc sq_item; */
    0,                          /* intintargfunc sq_slice; */
    0,                          /* intobjargproc sq_ass_item; */
    0,                          /* intintobjargproc sq_ass_slice; */
    0,                          /* objobjproc sq_contains; */

    0,                          /* binaryfunc sq_inplace_concat; */
    0,                          /* intargfunc sq_inplace_repeat; */
};

static int
CDataType_clear(PyTypeObject *self)
{
    StgDictObject *dict = PyType_stgdict((PyObject *)self);
    if (dict)
        Py_CLEAR(dict->proto);
    return PyType_Type.tp_clear((PyObject *)self);
}

static int
CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
{
    StgDictObject *dict = PyType_stgdict((PyObject *)self);
    if (dict)
        Py_VISIT(dict->proto);
    return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
}

static int
PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
{
    /* XXX Should we disallow deleting _fields_? */
    if (-1 == PyType_Type.tp_setattro(self, key, value))
        return -1;

    if (value && PyUnicode_Check(key) &&
        /* XXX struni _PyUnicode_AsString can fail (also in other places)! */
        0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
        return PyCStructUnionType_update_stgdict(self, value, 1);
    return 0;
}


static int
UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
{
    /* XXX Should we disallow deleting _fields_? */
    if (-1 == PyObject_GenericSetAttr(self, key, value))
        return -1;

    if (PyUnicode_Check(key) &&
        0 == strcmp(_PyUnicode_AsString(key), "_fields_"))
        return PyCStructUnionType_update_stgdict(self, value, 0);
    return 0;
}


PyTypeObject PyCStructType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.PyCStructType",                            /* tp_name */
    0,                                          /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    &CDataType_as_sequence,                     /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    PyCStructType_setattro,                     /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
    "metatype for the CData Objects",           /* tp_doc */
    (traverseproc)CDataType_traverse,           /* tp_traverse */
    (inquiry)CDataType_clear,                   /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    CDataType_methods,                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    PyCStructType_new,                                  /* tp_new */
    0,                                          /* tp_free */
};

static PyTypeObject UnionType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.UnionType",                        /* tp_name */
    0,                                          /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    &CDataType_as_sequence,             /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    UnionType_setattro,                         /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
    "metatype for the CData Objects",           /* tp_doc */
    (traverseproc)CDataType_traverse,           /* tp_traverse */
    (inquiry)CDataType_clear,                   /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    CDataType_methods,                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    UnionType_new,                              /* tp_new */
    0,                                          /* tp_free */
};


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

/*

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.

*/

static int
PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
{
    if (!proto || !PyType_Check(proto)) {
        PyErr_SetString(PyExc_TypeError,
                        "_type_ must be a type");
        return -1;
    }
    if (!PyType_stgdict(proto)) {
        PyErr_SetString(PyExc_TypeError,
                        "_type_ must have storage info");
        return -1;
    }
    Py_INCREF(proto);
    Py_XDECREF(stgdict->proto);
    stgdict->proto = proto;
    return 0;
}

static PyCArgObject *
PyCPointerType_paramfunc(CDataObject *self)
{
    PyCArgObject *parg;

    parg = PyCArgObject_new();
    if (parg == NULL)
        return NULL;

    parg->tag = 'P';
    parg->pffi_type = &ffi_type_pointer;
    Py_INCREF(self);
    parg->obj = (PyObject *)self;
    parg->value.p = *(void **)self->b_ptr;
    return parg;
}

static PyObject *
PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyTypeObject *result;
    StgDictObject *stgdict;
    PyObject *proto;
    PyObject *typedict;

    typedict = PyTuple_GetItem(args, 2);
    if (!typedict)
        return NULL;
/*
  stgdict items size, align, length contain info about pointers itself,
  stgdict->proto has info about the pointed to type!
*/
    stgdict = (StgDictObject *)PyObject_CallObject(
        (PyObject *)&PyCStgDict_Type, NULL);
    if (!stgdict)
        return NULL;
    stgdict->size = sizeof(void *);
    stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
    stgdict->length = 1;
    stgdict->ffi_type_pointer = ffi_type_pointer;
    stgdict->paramfunc = PyCPointerType_paramfunc;
    stgdict->flags |= TYPEFLAG_ISPOINTER;

    proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
    if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) {
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }

    if (proto) {
        StgDictObject *itemdict = PyType_stgdict(proto);
        assert(itemdict);
        /* If itemdict->format is NULL, then this is a pointer to an
           incomplete type.  We create a generic format string
           'pointer to bytes' in this case.  XXX Better would be to
           fix the format string later...
        */
        stgdict->format = _ctypes_alloc_format_string("&",
                      itemdict->format ? itemdict->format : "B");
        if (stgdict->format == NULL) {
            Py_DECREF((PyObject *)stgdict);
            return NULL;
        }
    }

    /* create the new instance (which is a class,
       since we are a metatype!) */
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
    if (result == NULL) {
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }

    /* replace the class dict by our updated spam dict */
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
        Py_DECREF(result);
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }
    Py_DECREF(result->tp_dict);
    result->tp_dict = (PyObject *)stgdict;

    return (PyObject *)result;
}


static PyObject *
PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
{
    StgDictObject *dict;

    dict = PyType_stgdict((PyObject *)self);
    assert(dict);

    if (-1 == PyCPointerType_SetProto(dict, type))
        return NULL;

    if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
        return NULL;

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *_byref(PyObject *);

static PyObject *
PyCPointerType_from_param(PyObject *type, PyObject *value)
{
    StgDictObject *typedict;

    if (value == Py_None) {
        /* ConvParam will convert to a NULL pointer later */
        Py_INCREF(value);
        return value;
    }

    typedict = PyType_stgdict(type);
    assert(typedict); /* Cannot be NULL for pointer types */

    /* If we expect POINTER(<type>), but receive a <type> instance, accept
       it by calling byref(<type>).
    */
    switch (PyObject_IsInstance(value, typedict->proto)) {
    case 1:
        Py_INCREF(value); /* _byref steals a refcount */
        return _byref(value);
    case -1:
        return NULL;
    default:
        break;
    }

    if (PointerObject_Check(value) || ArrayObject_Check(value)) {
        /* Array instances are also pointers when
           the item types are the same.
        */
        StgDictObject *v = PyObject_stgdict(value);
        assert(v); /* Cannot be NULL for pointer or array objects */
        if (PyObject_IsSubclass(v->proto, typedict->proto)) {
            Py_INCREF(value);
            return value;
        }
    }
    return CDataType_from_param(type, value);
}

static PyMethodDef PyCPointerType_methods[] = {
    { "from_address", CDataType_from_address, METH_O, from_address_doc },
    { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
    { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
    { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
    { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc},
    { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O },
    { NULL, NULL },
};

PyTypeObject PyCPointerType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.PyCPointerType",                                   /* tp_name */
    0,                                          /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    &CDataType_as_sequence,             /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
    "metatype for the Pointer Objects",         /* tp_doc */
    (traverseproc)CDataType_traverse,           /* tp_traverse */
    (inquiry)CDataType_clear,                   /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    PyCPointerType_methods,                     /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    PyCPointerType_new,                         /* tp_new */
    0,                                          /* tp_free */
};


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

static int
CharArray_set_raw(CDataObject *self, PyObject *value)
{
    char *ptr;
    Py_ssize_t size;
    Py_buffer view;

    if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
        return -1;
    size = view.len;
    ptr = view.buf;
    if (size > self->b_size) {
        PyErr_SetString(PyExc_ValueError,
                        "string too long");
        goto fail;
    }

    memcpy(self->b_ptr, ptr, size);

    PyBuffer_Release(&view);
    return 0;
 fail:
    PyBuffer_Release(&view);
    return -1;
}

static PyObject *
CharArray_get_raw(CDataObject *self)
{
    return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
}

static PyObject *
CharArray_get_value(CDataObject *self)
{
    int i;
    char *ptr = self->b_ptr;
    for (i = 0; i < self->b_size; ++i)
        if (*ptr++ == '\0')
            break;
    return PyBytes_FromStringAndSize(self->b_ptr, i);
}

static int
CharArray_set_value(CDataObject *self, PyObject *value)
{
    char *ptr;
    Py_ssize_t size;

    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "can't delete attribute");
        return -1;
    }

    if (!PyBytes_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                     "bytes expected instead of %s instance",
                     Py_TYPE(value)->tp_name);
        return -1;
    } else
        Py_INCREF(value);
    size = PyBytes_GET_SIZE(value);
    if (size > self->b_size) {
        PyErr_SetString(PyExc_ValueError,
                        "string too long");
        Py_DECREF(value);
        return -1;
    }

    ptr = PyBytes_AS_STRING(value);
    memcpy(self->b_ptr, ptr, size);
    if (size < self->b_size)
        self->b_ptr[size] = '\0';
    Py_DECREF(value);

    return 0;
}

static PyGetSetDef CharArray_getsets[] = {
    { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
      "value", NULL },
    { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
      "string value"},
    { NULL, NULL }
};

#ifdef CTYPES_UNICODE
static PyObject *
WCharArray_get_value(CDataObject *self)
{
    unsigned int i;
    wchar_t *ptr = (wchar_t *)self->b_ptr;
    for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
        if (*ptr++ == (wchar_t)0)
            break;
    return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
}

static int
WCharArray_set_value(CDataObject *self, PyObject *value)
{
    Py_ssize_t result = 0;
    Py_UNICODE *wstr;
    Py_ssize_t len;

    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "can't delete attribute");
        return -1;
    }
    if (!PyUnicode_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                        "unicode string expected instead of %s instance",
                        Py_TYPE(value)->tp_name);
        return -1;
    } else
        Py_INCREF(value);

    wstr = PyUnicode_AsUnicodeAndSize(value, &len);
    if (wstr == NULL)
        return -1;
    if ((unsigned)len > self->b_size/sizeof(wchar_t)) {
        PyErr_SetString(PyExc_ValueError,
                        "string too long");
        result = -1;
        goto done;
    }
    result = PyUnicode_AsWideChar(value,
                                  (wchar_t *)self->b_ptr,
                                  self->b_size/sizeof(wchar_t));
    if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
        ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
  done:
    Py_DECREF(value);

    return result >= 0 ? 0 : -1;
}

static PyGetSetDef WCharArray_getsets[] = {
    { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
      "string value"},
    { NULL, NULL }
};
#endif

/*
  The next three functions copied from Python's typeobject.c.

  They are used to attach methods, members, or getsets to a type *after* it
  has been created: Arrays of characters have additional getsets to treat them
  as strings.
 */
/*
static int
add_methods(PyTypeObject *type, PyMethodDef *meth)
{
    PyObject *dict = type->tp_dict;
    for (; meth->ml_name != NULL; meth++) {
        PyObject *descr;
        descr = PyDescr_NewMethod(type, meth);
        if (descr == NULL)
            return -1;
        if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
            return -1;
        Py_DECREF(descr);
    }
    return 0;
}

static int
add_members(PyTypeObject *type, PyMemberDef *memb)
{
    PyObject *dict = type->tp_dict;
    for (; memb->name != NULL; memb++) {
        PyObject *descr;
        descr = PyDescr_NewMember(type, memb);
        if (descr == NULL)
            return -1;
        if (PyDict_SetItemString(dict, memb->name, descr) < 0)
            return -1;
        Py_DECREF(descr);
    }
    return 0;
}
*/

static int
add_getset(PyTypeObject *type, PyGetSetDef *gsp)
{
    PyObject *dict = type->tp_dict;
    for (; gsp->name != NULL; gsp++) {
        PyObject *descr;
        descr = PyDescr_NewGetSet(type, gsp);
        if (descr == NULL)
            return -1;
        if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
            return -1;
        Py_DECREF(descr);
    }
    return 0;
}

static PyCArgObject *
PyCArrayType_paramfunc(CDataObject *self)
{
    PyCArgObject *p = PyCArgObject_new();
    if (p == NULL)
        return NULL;
    p->tag = 'P';
    p->pffi_type = &ffi_type_pointer;
    p->value.p = (char *)self->b_ptr;
    Py_INCREF(self);
    p->obj = (PyObject *)self;
    return p;
}

static PyObject *
PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyTypeObject *result;
    StgDictObject *stgdict;
    StgDictObject *itemdict;
    PyObject *length_attr, *type_attr;
    long length;
    int overflow;
    Py_ssize_t itemsize, itemalign;
    char buf[32];

    /* create the new instance (which is a class,
       since we are a metatype!) */
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
    if (result == NULL)
        return NULL;

    /* Initialize these variables to NULL so that we can simplify error
       handling by using Py_XDECREF.  */
    stgdict = NULL;
    type_attr = NULL;

    length_attr = PyObject_GetAttrString((PyObject *)result, "_length_");
    if (!length_attr || !PyLong_Check(length_attr)) {
        PyErr_SetString(PyExc_AttributeError,
                        "class must define a '_length_' attribute, "
                        "which must be a positive integer");
        Py_XDECREF(length_attr);
        goto error;
    }
    length = PyLong_AsLongAndOverflow(length_attr, &overflow);
    if (overflow) {
        PyErr_SetString(PyExc_OverflowError,
                        "The '_length_' attribute is too large");
        Py_DECREF(length_attr);
        goto error;
    }
    Py_DECREF(length_attr);

    type_attr = PyObject_GetAttrString((PyObject *)result, "_type_");
    if (!type_attr) {
        PyErr_SetString(PyExc_AttributeError,
                        "class must define a '_type_' attribute");
        goto error;
    }

    stgdict = (StgDictObject *)PyObject_CallObject(
        (PyObject *)&PyCStgDict_Type, NULL);
    if (!stgdict)
        goto error;

    itemdict = PyType_stgdict(type_attr);
    if (!itemdict) {
        PyErr_SetString(PyExc_TypeError,
                        "_type_ must have storage info");
        goto error;
    }

    assert(itemdict->format);
    if (itemdict->format[0] == '(') {
        sprintf(buf, "(%ld,", length);
        stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1);
    } else {
        sprintf(buf, "(%ld)", length);
        stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format);
    }
    if (stgdict->format == NULL)
        goto error;
    stgdict->ndim = itemdict->ndim + 1;
    stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
    if (stgdict->shape == NULL)
        goto error;
    stgdict->shape[0] = length;
    memmove(&stgdict->shape[1], itemdict->shape,
        sizeof(Py_ssize_t) * (stgdict->ndim - 1));

    itemsize = itemdict->size;
    if (length * itemsize < 0) {
        PyErr_SetString(PyExc_OverflowError,
                        "array too large");
        goto error;
    }

    itemalign = itemdict->align;

    if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
        stgdict->flags |= TYPEFLAG_HASPOINTER;

    stgdict->size = itemsize * length;
    stgdict->align = itemalign;
    stgdict->length = length;
    stgdict->proto = type_attr;

    stgdict->paramfunc = &PyCArrayType_paramfunc;

    /* Arrays are passed as pointers to function calls. */
    stgdict->ffi_type_pointer = ffi_type_pointer;

    /* replace the class dict by our updated spam dict */
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict))
        goto error;
    Py_DECREF(result->tp_dict);
    result->tp_dict = (PyObject *)stgdict;

    /* Special case for character arrays.
       A permanent annoyance: char arrays are also strings!
    */
    if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
        if (-1 == add_getset(result, CharArray_getsets))
            goto error;
#ifdef CTYPES_UNICODE
    } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
        if (-1 == add_getset(result, WCharArray_getsets))
            goto error;
#endif
    }

    return (PyObject *)result;
error:
    Py_XDECREF((PyObject*)stgdict);
    Py_XDECREF(type_attr);
    Py_DECREF(result);
    return NULL;
}

PyTypeObject PyCArrayType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.PyCArrayType",                     /* tp_name */
    0,                                          /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    &CDataType_as_sequence,                     /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "metatype for the Array Objects",           /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    CDataType_methods,                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    PyCArrayType_new,                                   /* tp_new */
    0,                                          /* tp_free */
};


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

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

*/

static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv?g";

static PyObject *
c_wchar_p_from_param(PyObject *type, PyObject *value)
{
    PyObject *as_parameter;
    int res;
    if (value == Py_None) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    if (PyUnicode_Check(value) || PyBytes_Check(value)) {
        PyCArgObject *parg;
        struct fielddesc *fd = _ctypes_get_fielddesc("Z");

        parg = PyCArgObject_new();
        if (parg == NULL)
            return NULL;
        parg->pffi_type = &ffi_type_pointer;
        parg->tag = 'Z';
        parg->obj = fd->setfunc(&parg->value, value, 0);
        if (parg->obj == NULL) {
            Py_DECREF(parg);
            return NULL;
        }
        return (PyObject *)parg;
    }
    res = PyObject_IsInstance(value, type);
    if (res == -1)
        return NULL;
    if (res) {
        Py_INCREF(value);
        return value;
    }
    if (ArrayObject_Check(value) || PointerObject_Check(value)) {
        /* c_wchar array instance or pointer(c_wchar(...)) */
        StgDictObject *dt = PyObject_stgdict(value);
        StgDictObject *dict;
        assert(dt); /* Cannot be NULL for pointer or array objects */
        dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
            Py_INCREF(value);
            return value;
        }
    }
    if (PyCArg_CheckExact(value)) {
        /* byref(c_char(...)) */
        PyCArgObject *a = (PyCArgObject *)value;
        StgDictObject *dict = PyObject_stgdict(a->obj);
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
            Py_INCREF(value);
            return value;
        }
    }

    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
    if (as_parameter) {
        value = c_wchar_p_from_param(type, as_parameter);
        Py_DECREF(as_parameter);
        return value;
    }
    /* XXX better message */
    PyErr_SetString(PyExc_TypeError,
                    "wrong type");
    return NULL;
}

static PyObject *
c_char_p_from_param(PyObject *type, PyObject *value)
{
    PyObject *as_parameter;
    int res;
    if (value == Py_None) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    if (PyBytes_Check(value)) {
        PyCArgObject *parg;
        struct fielddesc *fd = _ctypes_get_fielddesc("z");

        parg = PyCArgObject_new();
        if (parg == NULL)
            return NULL;
        parg->pffi_type = &ffi_type_pointer;
        parg->tag = 'z';
        parg->obj = fd->setfunc(&parg->value, value, 0);
        if (parg->obj == NULL) {
            Py_DECREF(parg);
            return NULL;
        }
        return (PyObject *)parg;
    }
    res = PyObject_IsInstance(value, type);
    if (res == -1)
        return NULL;
    if (res) {
        Py_INCREF(value);
        return value;
    }
    if (ArrayObject_Check(value) || PointerObject_Check(value)) {
        /* c_char array instance or pointer(c_char(...)) */
        StgDictObject *dt = PyObject_stgdict(value);
        StgDictObject *dict;
        assert(dt); /* Cannot be NULL for pointer or array objects */
        dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
            Py_INCREF(value);
            return value;
        }
    }
    if (PyCArg_CheckExact(value)) {
        /* byref(c_char(...)) */
        PyCArgObject *a = (PyCArgObject *)value;
        StgDictObject *dict = PyObject_stgdict(a->obj);
        if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
            Py_INCREF(value);
            return value;
        }
    }

    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
    if (as_parameter) {
        value = c_char_p_from_param(type, as_parameter);
        Py_DECREF(as_parameter);
        return value;
    }
    /* XXX better message */
    PyErr_SetString(PyExc_TypeError,
                    "wrong type");
    return NULL;
}

static PyObject *
c_void_p_from_param(PyObject *type, PyObject *value)
{
    StgDictObject *stgd;
    PyObject *as_parameter;
    int res;

/* None */
    if (value == Py_None) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    /* Should probably allow buffer interface as well */
/* int, long */
    if (PyLong_Check(value)) {
        PyCArgObject *parg;
        struct fielddesc *fd = _ctypes_get_fielddesc("P");

        parg = PyCArgObject_new();
        if (parg == NULL)
            return NULL;
        parg->pffi_type = &ffi_type_pointer;
        parg->tag = 'P';
        parg->obj = fd->setfunc(&parg->value, value, 0);
        if (parg->obj == NULL) {
            Py_DECREF(parg);
            return NULL;
        }
        return (PyObject *)parg;
    }
    /* XXX struni: remove later */
/* string */
    if (PyBytes_Check(value)) {
        PyCArgObject *parg;
        struct fielddesc *fd = _ctypes_get_fielddesc("z");

        parg = PyCArgObject_new();
        if (parg == NULL)
            return NULL;
        parg->pffi_type = &ffi_type_pointer;
        parg->tag = 'z';
        parg->obj = fd->setfunc(&parg->value, value, 0);
        if (parg->obj == NULL) {
            Py_DECREF(parg);
            return NULL;
        }
        return (PyObject *)parg;
    }
/* bytes */
    if (PyByteArray_Check(value)) {
        PyCArgObject *parg;
        struct fielddesc *fd = _ctypes_get_fielddesc("z");

        parg = PyCArgObject_new();
        if (parg == NULL)
            return NULL;
        parg->pffi_type = &ffi_type_pointer;
        parg->tag = 'z';
        parg->obj = fd->setfunc(&parg->value, value, 0);
        if (parg->obj == NULL) {
            Py_DECREF(parg);
            return NULL;
        }
        return (PyObject *)parg;
    }
/* unicode */
    if (PyUnicode_Check(value)) {
        PyCArgObject *parg;
        struct fielddesc *fd = _ctypes_get_fielddesc("Z");

        parg = PyCArgObject_new();
        if (parg == NULL)
            return NULL;
        parg->pffi_type = &ffi_type_pointer;
        parg->tag = 'Z';
        parg->obj = fd->setfunc(&parg->value, value, 0);
        if (parg->obj == NULL) {
            Py_DECREF(parg);
            return NULL;
        }
        return (PyObject *)parg;
    }
/* c_void_p instance (or subclass) */
    res = PyObject_IsInstance(value, type);
    if (res == -1)
        return NULL;
    if (res) {
        /* c_void_p instances */
        Py_INCREF(value);
        return value;
    }
/* ctypes array or pointer instance */
    if (ArrayObject_Check(value) || PointerObject_Check(value)) {
        /* Any array or pointer is accepted */
        Py_INCREF(value);
        return value;
    }
/* byref(...) */
    if (PyCArg_CheckExact(value)) {
        /* byref(c_xxx()) */
        PyCArgObject *a = (PyCArgObject *)value;
        if (a->tag == 'P') {
            Py_INCREF(value);
            return value;
        }
    }
/* function pointer */
    if (PyCFuncPtrObject_Check(value)) {
        PyCArgObject *parg;
        PyCFuncPtrObject *func;
        func = (PyCFuncPtrObject *)value;
        parg = PyCArgObject_new();
        if (parg == NULL)
            return NULL;
        parg->pffi_type = &ffi_type_pointer;
        parg->tag = 'P';
        Py_INCREF(value);
        parg->value.p = *(void **)func->b_ptr;
        parg->obj = value;
        return (PyObject *)parg;
    }
/* c_char_p, c_wchar_p */
    stgd = PyObject_stgdict(value);
    if (stgd && CDataObject_Check(value) && stgd->proto && PyUnicode_Check(stgd->proto)) {
        PyCArgObject *parg;

        switch (_PyUnicode_AsString(stgd->proto)[0]) {
        case 'z': /* c_char_p */
        case 'Z': /* c_wchar_p */
            parg = PyCArgObject_new();
            if (parg == NULL)
                return NULL;
            parg->pffi_type = &ffi_type_pointer;
            parg->tag = 'Z';
            Py_INCREF(value);
            parg->obj = value;
            /* Remember: b_ptr points to where the pointer is stored! */
            parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
            return (PyObject *)parg;
        }
    }

    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
    if (as_parameter) {
        value = c_void_p_from_param(type, as_parameter);
        Py_DECREF(as_parameter);
        return value;
    }
    /* XXX better message */
    PyErr_SetString(PyExc_TypeError,
                    "wrong type");
    return NULL;
}

static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };

static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
                                   PyObject *proto, struct fielddesc *fmt)
{
    PyTypeObject *result;
    StgDictObject *stgdict;
    PyObject *name = PyTuple_GET_ITEM(args, 0);
    PyObject *newname;
    PyObject *swapped_args;
    static PyObject *suffix;
    Py_ssize_t i;

    swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
    if (!swapped_args)
        return NULL;

    if (suffix == NULL)
#ifdef WORDS_BIGENDIAN
        suffix = PyUnicode_InternFromString("_le");
#else
        suffix = PyUnicode_InternFromString("_be");
#endif

    newname = PyUnicode_Concat(name, suffix);
    if (newname == NULL) {
        return NULL;
    }

    PyTuple_SET_ITEM(swapped_args, 0, newname);
    for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
        PyObject *v = PyTuple_GET_ITEM(args, i);
        Py_INCREF(v);
        PyTuple_SET_ITEM(swapped_args, i, v);
    }

    /* create the new instance (which is a class,
       since we are a metatype!) */
    result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
    Py_DECREF(swapped_args);
    if (result == NULL)
        return NULL;

    stgdict = (StgDictObject *)PyObject_CallObject(
        (PyObject *)&PyCStgDict_Type, NULL);
    if (!stgdict) /* XXX leaks result! */
        return NULL;

    stgdict->ffi_type_pointer = *fmt->pffi_type;
    stgdict->align = fmt->pffi_type->alignment;
    stgdict->length = 0;
    stgdict->size = fmt->pffi_type->size;
    stgdict->setfunc = fmt->setfunc_swapped;
    stgdict->getfunc = fmt->getfunc_swapped;

    Py_INCREF(proto);
    stgdict->proto = proto;

    /* replace the class dict by our updated spam dict */
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
        Py_DECREF(result);
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }
    Py_DECREF(result->tp_dict);
    result->tp_dict = (PyObject *)stgdict;

    return (PyObject *)result;
}

static PyCArgObject *
PyCSimpleType_paramfunc(CDataObject *self)
{
    StgDictObject *dict;
    char *fmt;
    PyCArgObject *parg;
    struct fielddesc *fd;

    dict = PyObject_stgdict((PyObject *)self);
    assert(dict); /* Cannot be NULL for CDataObject instances */
    fmt = _PyUnicode_AsString(dict->proto);
    assert(fmt);

    fd = _ctypes_get_fielddesc(fmt);
    assert(fd);

    parg = PyCArgObject_new();
    if (parg == NULL)
        return NULL;

    parg->tag = fmt[0];
    parg->pffi_type = fd->pffi_type;
    Py_INCREF(self);
    parg->obj = (PyObject *)self;
    memcpy(&parg->value, self->b_ptr, self->b_size);
    return parg;
}

static PyObject *
PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyTypeObject *result;
    StgDictObject *stgdict;
    PyObject *proto;
    const char *proto_str;
    Py_ssize_t proto_len;
    PyMethodDef *ml;
    struct fielddesc *fmt;

    /* create the new instance (which is a class,
       since we are a metatype!) */
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
    if (result == NULL)
        return NULL;

    proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
    if (!proto) {
        PyErr_SetString(PyExc_AttributeError,
                        "class must define a '_type_' attribute");
  error:
        Py_XDECREF(proto);
        Py_XDECREF(result);
        return NULL;
    }
    if (PyUnicode_Check(proto)) {
        proto_str = PyUnicode_AsUTF8AndSize(proto, &proto_len);
        if (!proto_str)
            goto error;
    } else {
        PyErr_SetString(PyExc_TypeError,
            "class must define a '_type_' string attribute");
        goto error;
    }
    if (proto_len != 1) {
        PyErr_SetString(PyExc_ValueError,
                        "class must define a '_type_' attribute "
                        "which must be a string of length 1");
        goto error;
    }
    if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
        PyErr_Format(PyExc_AttributeError,
                     "class must define a '_type_' attribute which must be\n"
                     "a single character string containing one of '%s'.",
                     SIMPLE_TYPE_CHARS);
        goto error;
    }
    fmt = _ctypes_get_fielddesc(proto_str);
    if (fmt == NULL) {
        PyErr_Format(PyExc_ValueError,
                     "_type_ '%s' not supported", proto_str);
        goto error;
    }

    stgdict = (StgDictObject *)PyObject_CallObject(
        (PyObject *)&PyCStgDict_Type, NULL);
    if (!stgdict)
        goto error;

    stgdict->ffi_type_pointer = *fmt->pffi_type;
    stgdict->align = fmt->pffi_type->alignment;
    stgdict->length = 0;
    stgdict->size = fmt->pffi_type->size;
    stgdict->setfunc = fmt->setfunc;
    stgdict->getfunc = fmt->getfunc;
#ifdef WORDS_BIGENDIAN
    stgdict->format = _ctypes_alloc_format_string(">", proto_str);
#else
    stgdict->format = _ctypes_alloc_format_string("<", proto_str);
#endif
    if (stgdict->format == NULL) {
        Py_DECREF(result);
        Py_DECREF(proto);
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }

    stgdict->paramfunc = PyCSimpleType_paramfunc;
/*
    if (result->tp_base != &Simple_Type) {
        stgdict->setfunc = NULL;
        stgdict->getfunc = NULL;
    }
*/

    /* This consumes the refcount on proto which we have */
    stgdict->proto = proto;

    /* replace the class dict by our updated spam dict */
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
        Py_DECREF(result);
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }
    Py_DECREF(result->tp_dict);
    result->tp_dict = (PyObject *)stgdict;

    /* Install from_param class methods in ctypes base classes.
       Overrides the PyCSimpleType_from_param generic method.
     */
    if (result->tp_base == &Simple_Type) {
        switch (*proto_str) {
        case 'z': /* c_char_p */
            ml = &c_char_p_method;
            stgdict->flags |= TYPEFLAG_ISPOINTER;
            break;
        case 'Z': /* c_wchar_p */
            ml = &c_wchar_p_method;
            stgdict->flags |= TYPEFLAG_ISPOINTER;
            break;
        case 'P': /* c_void_p */
            ml = &c_void_p_method;
            stgdict->flags |= TYPEFLAG_ISPOINTER;
            break;
        case 's':
        case 'X':
        case 'O':
            ml = NULL;
            stgdict->flags |= TYPEFLAG_ISPOINTER;
            break;
        default:
            ml = NULL;
            break;
        }

        if (ml) {
            PyObject *meth;
            int x;
            meth = PyDescr_NewClassMethod(result, ml);
            if (!meth)
                return NULL;
            x = PyDict_SetItemString(result->tp_dict,
                                     ml->ml_name,
                                     meth);
            Py_DECREF(meth);
            if (x == -1) {
                Py_DECREF(result);
                return NULL;
            }
        }
    }

    if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
        PyObject *swapped = CreateSwappedType(type, args, kwds,
                                              proto, fmt);
        StgDictObject *sw_dict;
        if (swapped == NULL) {
            Py_DECREF(result);
            return NULL;
        }
        sw_dict = PyType_stgdict(swapped);
#ifdef WORDS_BIGENDIAN
        PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
        PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
        PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
        PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
        /* We are creating the type for the OTHER endian */
        sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1);
#else
        PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
        PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
        PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
        PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
        /* We are creating the type for the OTHER endian */
        sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1);
#endif
        Py_DECREF(swapped);
        if (PyErr_Occurred()) {
            Py_DECREF(result);
            return NULL;
        }
    };

    return (PyObject *)result;
}

/*
 * This is a *class method*.
 * Convert a parameter into something that ConvParam can handle.
 */
static PyObject *
PyCSimpleType_from_param(PyObject *type, PyObject *value)
{
    StgDictObject *dict;
    char *fmt;
    PyCArgObject *parg;
    struct fielddesc *fd;
    PyObject *as_parameter;
    int res;

    /* If the value is already an instance of the requested type,
       we can use it as is */
    res = PyObject_IsInstance(value, type);
    if (res == -1)
        return NULL;
    if (res) {
        Py_INCREF(value);
        return value;
    }

    dict = PyType_stgdict(type);
    assert(dict);

    /* I think we can rely on this being a one-character string */
    fmt = _PyUnicode_AsString(dict->proto);
    assert(fmt);

    fd = _ctypes_get_fielddesc(fmt);
    assert(fd);

    parg = PyCArgObject_new();
    if (parg == NULL)
        return NULL;

    parg->tag = fmt[0];
    parg->pffi_type = fd->pffi_type;
    parg->obj = fd->setfunc(&parg->value, value, 0);
    if (parg->obj)
        return (PyObject *)parg;
    PyErr_Clear();
    Py_DECREF(parg);

    as_parameter = PyObject_GetAttrString(value, "_as_parameter_");
    if (as_parameter) {
        if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
            Py_DECREF(as_parameter);
            return NULL;
        }
        value = PyCSimpleType_from_param(type, as_parameter);
        Py_LeaveRecursiveCall();
        Py_DECREF(as_parameter);
        return value;
    }
    PyErr_SetString(PyExc_TypeError,
                    "wrong type");
    return NULL;
}

static PyMethodDef PyCSimpleType_methods[] = {
    { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc },
    { "from_address", CDataType_from_address, METH_O, from_address_doc },
    { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, },
    { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, },
    { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
    { NULL, NULL },
};

PyTypeObject PyCSimpleType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.PyCSimpleType",                                    /* tp_name */
    0,                                          /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    &CDataType_as_sequence,             /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "metatype for the PyCSimpleType Objects",           /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    PyCSimpleType_methods,                      /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    PyCSimpleType_new,                                  /* tp_new */
    0,                                          /* tp_free */
};

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

static PyObject *
converters_from_argtypes(PyObject *ob)
{
    PyObject *converters;
    Py_ssize_t i;
    Py_ssize_t nArgs;

    ob = PySequence_Tuple(ob); /* new reference */
    if (!ob) {
        PyErr_SetString(PyExc_TypeError,
                        "_argtypes_ must be a sequence of types");
        return NULL;
    }

    nArgs = PyTuple_GET_SIZE(ob);
    converters = PyTuple_New(nArgs);
    if (!converters)
        return NULL;

    /* I have to check if this is correct. Using c_char, which has a size
       of 1, will be assumed to be pushed as only one byte!
       Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
    */

    for (i = 0; i < nArgs; ++i) {
        PyObject *tp = PyTuple_GET_ITEM(ob, i);
        PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
        if (!cnv)
            goto argtypes_error_1;
        PyTuple_SET_ITEM(converters, i, cnv);
    }
    Py_DECREF(ob);
    return converters;

  argtypes_error_1:
    Py_XDECREF(converters);
    Py_DECREF(ob);
    PyErr_Format(PyExc_TypeError,
                 "item %zd in _argtypes_ has no from_param method",
                 i+1);
    return NULL;
}

static int
make_funcptrtype_dict(StgDictObject *stgdict)
{
    PyObject *ob;
    PyObject *converters = NULL;

    stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
    stgdict->length = 1;
    stgdict->size = sizeof(void *);
    stgdict->setfunc = NULL;
    stgdict->getfunc = NULL;
    stgdict->ffi_type_pointer = ffi_type_pointer;

    ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
    if (!ob || !PyLong_Check(ob)) {
        PyErr_SetString(PyExc_TypeError,
            "class must define _flags_ which must be an integer");
        return -1;
    }
    stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER;

    /* _argtypes_ is optional... */
    ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
    if (ob) {
        converters = converters_from_argtypes(ob);
        if (!converters)
            goto error;
        Py_INCREF(ob);
        stgdict->argtypes = ob;
        stgdict->converters = converters;
    }

    ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
    if (ob) {
        if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
            PyErr_SetString(PyExc_TypeError,
                "_restype_ must be a type, a callable, or None");
            return -1;
        }
        Py_INCREF(ob);
        stgdict->restype = ob;
        stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
        if (stgdict->checker == NULL)
            PyErr_Clear();
    }
/* XXX later, maybe.
    ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
    if (ob) {
        if (!PyCallable_Check(ob)) {
            PyErr_SetString(PyExc_TypeError,
                "_errcheck_ must be callable");
            return -1;
        }
        Py_INCREF(ob);
        stgdict->errcheck = ob;
    }
*/
    return 0;

  error:
    Py_XDECREF(converters);
    return -1;

}

static PyCArgObject *
PyCFuncPtrType_paramfunc(CDataObject *self)
{
    PyCArgObject *parg;

    parg = PyCArgObject_new();
    if (parg == NULL)
        return NULL;

    parg->tag = 'P';
    parg->pffi_type = &ffi_type_pointer;
    Py_INCREF(self);
    parg->obj = (PyObject *)self;
    parg->value.p = *(void **)self->b_ptr;
    return parg;
}

static PyObject *
PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyTypeObject *result;
    StgDictObject *stgdict;

    stgdict = (StgDictObject *)PyObject_CallObject(
        (PyObject *)&PyCStgDict_Type, NULL);
    if (!stgdict)
        return NULL;

    stgdict->paramfunc = PyCFuncPtrType_paramfunc;
    /* We do NOT expose the function signature in the format string.  It
       is impossible, generally, because the only requirement for the
       argtypes items is that they have a .from_param method - we do not
       know the types of the arguments (although, in practice, most
       argtypes would be a ctypes type).
    */
    stgdict->format = _ctypes_alloc_format_string(NULL, "X{}");
    stgdict->flags |= TYPEFLAG_ISPOINTER;

    /* create the new instance (which is a class,
       since we are a metatype!) */
    result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
    if (result == NULL) {
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }

    /* replace the class dict by our updated storage dict */
    if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
        Py_DECREF(result);
        Py_DECREF((PyObject *)stgdict);
        return NULL;
    }
    Py_DECREF(result->tp_dict);
    result->tp_dict = (PyObject *)stgdict;

    if (-1 == make_funcptrtype_dict(stgdict)) {
        Py_DECREF(result);
        return NULL;
    }

    return (PyObject *)result;
}

PyTypeObject PyCFuncPtrType_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.PyCFuncPtrType",                           /* tp_name */
    0,                                          /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    &CDataType_as_sequence,                     /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
    "metatype for C function pointers",         /* tp_doc */
    (traverseproc)CDataType_traverse,           /* tp_traverse */
    (inquiry)CDataType_clear,                   /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    CDataType_methods,                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    PyCFuncPtrType_new,                         /* tp_new */
    0,                                          /* tp_free */
};


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

static CDataObject *
PyCData_GetContainer(CDataObject *self)
{
    while (self->b_base)
        self = self->b_base;
    if (self->b_objects == NULL) {
        if (self->b_length) {
            self->b_objects = PyDict_New();
        } else {
            Py_INCREF(Py_None);
            self->b_objects = Py_None;
        }
    }
    return self;
}

static PyObject *
GetKeepedObjects(CDataObject *target)
{
    return PyCData_GetContainer(target)->b_objects;
}

static PyObject *
unique_key(CDataObject *target, Py_ssize_t index)
{
    char string[256];
    char *cp = string;
    size_t bytes_left;

    assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
    cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
    while (target->b_base) {
        bytes_left = sizeof(string) - (cp - string) - 1;
        /* Hex format needs 2 characters per byte */
        if (bytes_left < sizeof(Py_ssize_t) * 2) {
            PyErr_SetString(PyExc_ValueError,
                            "ctypes object structure too deep");
            return NULL;
        }
        cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
        target = target->b_base;
    }
    return PyUnicode_FromStringAndSize(string, cp-string);
}

/*
 * 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)
{
    int result;
    CDataObject *ob;
    PyObject *key;

/* Optimization: no need to store None */
    if (keep == Py_None) {
        Py_DECREF(Py_None);
        return 0;
    }
    ob = PyCData_GetContainer(target);
    if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
        Py_XDECREF(ob->b_objects);
        ob->b_objects = keep; /* refcount consumed */
        return 0;
    }
    key = unique_key(target, index);
    if (key == NULL) {
        Py_DECREF(keep);
        return -1;
    }
    result = PyDict_SetItem(ob->b_objects, key, keep);
    Py_DECREF(key);
    Py_DECREF(keep);
    return result;
}

/******************************************************************/
/*
  PyCData_Type
 */
static int
PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
{
    Py_VISIT(self->b_objects);
    Py_VISIT((PyObject *)self->b_base);
    return 0;
}

static int
PyCData_clear(CDataObject *self)
{
    Py_CLEAR(self->b_objects);
    if ((self->b_needsfree)
        && _CDataObject_HasExternalBuffer(self))
        PyMem_Free(self->b_ptr);
    self->b_ptr = NULL;
    Py_CLEAR(self->b_base);
    return 0;
}

static void
PyCData_dealloc(PyObject *self)
{
    PyCData_clear((CDataObject *)self);
    Py_TYPE(self)->tp_free(self);
}

static PyMemberDef PyCData_members[] = {
    { "_b_base_", T_OBJECT,
      offsetof(CDataObject, b_base), READONLY,
      "the base object" },
    { "_b_needsfree_", T_INT,
      offsetof(CDataObject, b_needsfree), READONLY,
      "whether the object owns the memory or not" },
    { "_objects", T_OBJECT,
      offsetof(CDataObject, b_objects), READONLY,
      "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
    { NULL },
};

static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
{
    CDataObject *self = (CDataObject *)myself;
    StgDictObject *dict = PyObject_stgdict(myself);
    Py_ssize_t i;

    if (view == NULL) return 0;

    view->buf = self->b_ptr;
    view->obj = myself;
    Py_INCREF(myself);
    view->len = self->b_size;
    view->readonly = 0;
    /* use default format character if not set */
    view->format = dict->format ? dict->format : "B";
    view->ndim = dict->ndim;
    view->shape = dict->shape;
    view->itemsize = self->b_size;
    if (view->itemsize) {
        for (i = 0; i < view->ndim; ++i) {
            view->itemsize /= dict->shape[i];
        }
    }
    view->strides = NULL;
    view->suboffsets = NULL;
    view->internal = NULL;
    return 0;
}

static PyBufferProcs PyCData_as_buffer = {
    PyCData_NewGetBuffer,
    NULL,
};

/*
 * CData objects are mutable, so they cannot be hashable!
 */
static Py_hash_t
PyCData_nohash(PyObject *self)
{
    PyErr_SetString(PyExc_TypeError, "unhashable type");
    return -1;
}

static PyObject *
PyCData_reduce(PyObject *myself, PyObject *args)
{
    CDataObject *self = (CDataObject *)myself;

    if (PyObject_stgdict(myself)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
        PyErr_SetString(PyExc_ValueError,
                        "ctypes objects containing pointers cannot be pickled");
        return NULL;
    }
    return Py_BuildValue("O(O(NN))",
                         _unpickle,
                         Py_TYPE(myself),
                         PyObject_GetAttrString(myself, "__dict__"),
                         PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
}

static PyObject *
PyCData_setstate(PyObject *myself, PyObject *args)
{
    void *data;
    Py_ssize_t len;
    int res;
    PyObject *dict, *mydict;
    CDataObject *self = (CDataObject *)myself;
    if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
        return NULL;
    if (len > self->b_size)
        len = self->b_size;
    memmove(self->b_ptr, data, len);
    mydict = PyObject_GetAttrString(myself, "__dict__");
    res = PyDict_Update(mydict, dict);
    Py_DECREF(mydict);
    if (res == -1)
        return NULL;
    Py_INCREF(Py_None);
    return Py_None;
}

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

static PyMethodDef PyCData_methods[] = {
    { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
    { "__reduce__", PyCData_reduce, METH_NOARGS, },
    { "__setstate__", PyCData_setstate, METH_VARARGS, },
    { NULL, NULL },
};

PyTypeObject PyCData_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes._CData",
    sizeof(CDataObject),                        /* tp_basicsize */
    0,                                          /* tp_itemsize */
    PyCData_dealloc,                                    /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    PyCData_nohash,                             /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    &PyCData_as_buffer,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "XXX to be provided",                       /* tp_doc */
    (traverseproc)PyCData_traverse,             /* tp_traverse */
    (inquiry)PyCData_clear,                     /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    PyCData_methods,                                    /* tp_methods */
    PyCData_members,                                    /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    0,                                          /* tp_new */
    0,                                          /* tp_free */
};

static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
{
    if ((size_t)dict->size <= sizeof(obj->b_value)) {
        /* No need to call malloc, can use the default buffer */
        obj->b_ptr = (char *)&obj->b_value;
        /* The b_needsfree flag does not mean that we actually did
           call PyMem_Malloc to allocate the memory block; instead it
           means we are the *owner* of the memory and are responsible
           for freeing resources associated with the memory.  This is
           also the reason that b_needsfree is exposed to Python.
         */
        obj->b_needsfree = 1;
    } else {
        /* In python 2.4, and ctypes 0.9.6, the malloc call took about
           33% of the creation time for c_int().
        */
        obj->b_ptr = (char *)PyMem_Malloc(dict->size);
        if (obj->b_ptr == NULL) {
            PyErr_NoMemory();
            return -1;
        }
        obj->b_needsfree = 1;
        memset(obj->b_ptr, 0, dict->size);
    }
    obj->b_size = dict->size;
    return 0;
}

PyObject *
PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
{
    CDataObject *cmem;
    StgDictObject *dict;

    assert(PyType_Check(type));
    dict = PyType_stgdict(type);
    if (!dict) {
        PyErr_SetString(PyExc_TypeError,
                        "abstract class");
        return NULL;
    }
    dict->flags |= DICTFLAG_FINAL;
    cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
    if (cmem == NULL)
        return NULL;
    assert(CDataObject_Check(cmem));

    cmem->b_length = dict->length;
    cmem->b_size = dict->size;
    if (base) { /* use base's buffer */
        assert(CDataObject_Check(base));
        cmem->b_ptr = adr;
        cmem->b_needsfree = 0;
        Py_INCREF(base);
        cmem->b_base = (CDataObject *)base;
        cmem->b_index = index;
    } else { /* copy contents of adr */
        if (-1 == PyCData_MallocBuffer(cmem, dict)) {
            Py_DECREF(cmem);
            return NULL;
        }
        memcpy(cmem->b_ptr, adr, dict->size);
        cmem->b_index = index;
    }
    return (PyObject *)cmem;
}

/*
 Box a memory block into a CData instance.
*/
PyObject *
PyCData_AtAddress(PyObject *type, void *buf)
{
    CDataObject *pd;
    StgDictObject *dict;

    assert(PyType_Check(type));
    dict = PyType_stgdict(type);
    if (!dict) {
        PyErr_SetString(PyExc_TypeError,
                        "abstract class");
        return NULL;
    }
    dict->flags |= DICTFLAG_FINAL;

    pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
    if (!pd)
        return NULL;
    assert(CDataObject_Check(pd));
    pd->b_ptr = (char *)buf;
    pd->b_length = dict->length;
    pd->b_size = dict->size;
    return (PyObject *)pd;
}

/*
  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(PyObject *obj)
{
    PyTypeObject *type = (PyTypeObject *)obj;

    if (PyCSimpleTypeObject_Check(type))
        return type->tp_base != &Simple_Type;
    return 0;
}

PyObject *
PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
          Py_ssize_t index, Py_ssize_t size, char *adr)
{
    StgDictObject *dict;
    if (getfunc)
        return getfunc(adr, size);
    assert(type);
    dict = PyType_stgdict(type);
    if (dict && dict->getfunc && !_ctypes_simple_instance(type))
        return dict->getfunc(adr, size);
    return PyCData_FromBaseObj(type, src, index, adr);
}

/*
  Helper function for PyCData_set below.
*/
static PyObject *
_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
           Py_ssize_t size, char *ptr)
{
    CDataObject *src;
    int err;

    if (setfunc)
        return setfunc(ptr, value, size);

    if (!CDataObject_Check(value)) {
        StgDictObject *dict = PyType_stgdict(type);
        if (dict && dict->setfunc)
            return dict->setfunc(ptr, value, size);
        /*
           If value is a tuple, we try to call the type with the tuple
           and use the result!
        */
        assert(PyType_Check(type));
        if (PyTuple_Check(value)) {
            PyObject *ob;
            PyObject *result;
            ob = PyObject_CallObject(type, value);
            if (ob == NULL) {
                _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
                                  ((PyTypeObject *)type)->tp_name);
                return NULL;
            }
            result = _PyCData_set(dst, type, setfunc, ob,
                                size, ptr);
            Py_DECREF(ob);
            return result;
        } else if (value == Py_None && PyCPointerTypeObject_Check(type)) {
            *(void **)ptr = NULL;
            Py_INCREF(Py_None);
            return Py_None;
        } else {
            PyErr_Format(PyExc_TypeError,
                         "expected %s instance, got %s",
                         ((PyTypeObject *)type)->tp_name,
                         Py_TYPE(value)->tp_name);
            return NULL;
        }
    }
    src = (CDataObject *)value;

    err = PyObject_IsInstance(value, type);
    if (err == -1)
        return NULL;
    if (err) {
        memcpy(ptr,
               src->b_ptr,
               size);

        if (PyCPointerTypeObject_Check(type))
            /* XXX */;

        value = GetKeepedObjects(src);
        Py_INCREF(value);
        return value;
    }

    if (PyCPointerTypeObject_Check(type)
        && ArrayObject_Check(value)) {
        StgDictObject *p1, *p2;
        PyObject *keep;
        p1 = PyObject_stgdict(value);
        assert(p1); /* Cannot be NULL for array instances */
        p2 = PyType_stgdict(type);
        assert(p2); /* Cannot be NULL for pointer types */

        if (p1->proto != p2->proto) {
            PyErr_Format(PyExc_TypeError,
                         "incompatible types, %s instance instead of %s instance",
                         Py_TYPE(value)->tp_name,
                         ((PyTypeObject *)type)->tp_name);
            return NULL;
        }
        *(void **)ptr = src->b_ptr;

        keep = GetKeepedObjects(src);
        /*
          We are assigning an array object to a field which represents
          a pointer. This has the same effect as converting an array
          into a pointer. So, again, we have to keep the whole object
          pointed to (which is the array in this case) alive, and not
          only it's object list.  So we create a tuple, containing
          b_objects list PLUS the array itself, and return that!
        */
        return PyTuple_Pack(2, keep, value);
    }
    PyErr_Format(PyExc_TypeError,
                 "incompatible types, %s instance instead of %s instance",
                 Py_TYPE(value)->tp_name,
                 ((PyTypeObject *)type)->tp_name);
    return NULL;
}

/*
 * Set a slice in object 'dst', which has the type 'type',
 * to the value 'value'.
 */
int
PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
          Py_ssize_t index, Py_ssize_t size, char *ptr)
{
    CDataObject *mem = (CDataObject *)dst;
    PyObject *result;

    if (!CDataObject_Check(dst)) {
        PyErr_SetString(PyExc_TypeError,
                        "not a ctype instance");
        return -1;
    }

    result = _PyCData_set(mem, type, setfunc, value,
                        size, ptr);
    if (result == NULL)
        return -1;

    /* KeepRef steals a refcount from it's last argument */
    /* If KeepRef fails, we are stumped.  The dst memory block has already
       been changed */
    return KeepRef(mem, index, result);
}


/******************************************************************/
static PyObject *
GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    CDataObject *obj;
    StgDictObject *dict;

    dict = PyType_stgdict((PyObject *)type);
    if (!dict) {
        PyErr_SetString(PyExc_TypeError,
                        "abstract class");
        return NULL;
    }
    dict->flags |= DICTFLAG_FINAL;

    obj = (CDataObject *)type->tp_alloc(type, 0);
    if (!obj)
        return NULL;

    obj->b_base = NULL;
    obj->b_index = 0;
    obj->b_objects = NULL;
    obj->b_length = dict->length;

    if (-1 == PyCData_MallocBuffer(obj, dict)) {
        Py_DECREF(obj);
        return NULL;
    }
    return (PyObject *)obj;
}
/*****************************************************************/
/*
  PyCFuncPtr_Type
*/

static int
PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob)
{
    if (ob && !PyCallable_Check(ob)) {
        PyErr_SetString(PyExc_TypeError,
                        "the errcheck attribute must be callable");
        return -1;
    }
    Py_XDECREF(self->errcheck);
    Py_XINCREF(ob);
    self->errcheck = ob;
    return 0;
}

static PyObject *
PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self)
{
    if (self->errcheck) {
        Py_INCREF(self->errcheck);
        return self->errcheck;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static int
PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob)
{
    if (ob == NULL) {
        Py_XDECREF(self->restype);
        self->restype = NULL;
        Py_XDECREF(self->checker);
        self->checker = NULL;
        return 0;
    }
    if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
        PyErr_SetString(PyExc_TypeError,
                        "restype must be a type, a callable, or None");
        return -1;
    }
    Py_XDECREF(self->checker);
    Py_XDECREF(self->restype);
    Py_INCREF(ob);
    self->restype = ob;
    self->checker = PyObject_GetAttrString(ob, "_check_retval_");
    if (self->checker == NULL)
        PyErr_Clear();
    return 0;
}

static PyObject *
PyCFuncPtr_get_restype(PyCFuncPtrObject *self)
{
    StgDictObject *dict;
    if (self->restype) {
        Py_INCREF(self->restype);
        return self->restype;
    }
    dict = PyObject_stgdict((PyObject *)self);
    assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
    if (dict->restype) {
        Py_INCREF(dict->restype);
        return dict->restype;
    } else {
        Py_INCREF(Py_None);
        return Py_None;
    }
}

static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob)
{
    PyObject *converters;

    if (ob == NULL || ob == Py_None) {
        Py_XDECREF(self->converters);
        self->converters = NULL;
        Py_XDECREF(self->argtypes);
        self->argtypes = NULL;
    } else {
        converters = converters_from_argtypes(ob);
        if (!converters)
            return -1;
        Py_XDECREF(self->converters);
        self->converters = converters;
        Py_XDECREF(self->argtypes);
        Py_INCREF(ob);
        self->argtypes = ob;
    }
    return 0;
}

static PyObject *
PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self)
{
    StgDictObject *dict;
    if (self->argtypes) {
        Py_INCREF(self->argtypes);
        return self->argtypes;
    }
    dict = PyObject_stgdict((PyObject *)self);
    assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
    if (dict->argtypes) {
        Py_INCREF(dict->argtypes);
        return dict->argtypes;
    } else {
        Py_INCREF(Py_None);
        return Py_None;
    }
}

static PyGetSetDef PyCFuncPtr_getsets[] = {
    { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
      "a function to check for errors", NULL },
    { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
      "specify the result type", NULL },
    { "argtypes", (getter)PyCFuncPtr_get_argtypes,
      (setter)PyCFuncPtr_set_argtypes,
      "specify the argument types", NULL },
    { NULL, NULL }
};

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

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

    dict = PyType_stgdict((PyObject *)type);
    /* It should not happen that dict is NULL, but better be safe */
    if (dict==NULL || dict->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);
        address = (PPROC)GetProcAddress(handle, mangled_name);
        if (address)
            return address;
    }
    return NULL;
#endif
}
#endif

/* Return 1 if usable, 0 else and exception set. */
static int
_check_outarg_type(PyObject *arg, Py_ssize_t index)
{
    StgDictObject *dict;

    if (PyCPointerTypeObject_Check(arg))
        return 1;

    if (PyCArrayTypeObject_Check(arg))
        return 1;

    dict = PyType_stgdict(arg);
    if (dict
        /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
        && PyUnicode_Check(dict->proto)
/* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
        && (strchr("PzZ", _PyUnicode_AsString(dict->proto)[0]))) {
        return 1;
    }

    PyErr_Format(PyExc_TypeError,
                 "'out' parameter %d must be a pointer type, not %s",
                 Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
                 PyType_Check(arg) ?
                 ((PyTypeObject *)arg)->tp_name :
             Py_TYPE(arg)->tp_name);
    return 0;
}

/* Returns 1 on success, 0 on error */
static int
_validate_paramflags(PyTypeObject *type, PyObject *paramflags)
{
    Py_ssize_t i, len;
    StgDictObject *dict;
    PyObject *argtypes;

    dict = PyType_stgdict((PyObject *)type);
    assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */
    argtypes = dict->argtypes;

    if (paramflags == NULL || dict->argtypes == NULL)
        return 1;

    if (!PyTuple_Check(paramflags)) {
        PyErr_SetString(PyExc_TypeError,
                        "paramflags must be a tuple or None");
        return 0;
    }

    len = PyTuple_GET_SIZE(paramflags);
    if (len != PyTuple_GET_SIZE(dict->argtypes)) {
        PyErr_SetString(PyExc_ValueError,
                        "paramflags must have the same length as argtypes");
        return 0;
    }

    for (i = 0; i < len; ++i) {
        PyObject *item = PyTuple_GET_ITEM(paramflags, i);
        int flag;
        char *name;
        PyObject *defval;
        PyObject *typ;
        if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
            PyErr_SetString(PyExc_TypeError,
                   "paramflags must be a sequence of (int [,string [,value]]) tuples");
            return 0;
        }
        typ = PyTuple_GET_ITEM(argtypes, i);
        switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
        case 0:
        case PARAMFLAG_FIN:
        case PARAMFLAG_FIN | PARAMFLAG_FLCID:
        case PARAMFLAG_FIN | PARAMFLAG_FOUT:
            break;
        case PARAMFLAG_FOUT:
            if (!_check_outarg_type(typ, i+1))
                return 0;
            break;
        default:
            PyErr_Format(PyExc_TypeError,
                         "paramflag value %d not supported",
                         flag);
            return 0;
        }
    }
    return 1;
}

static int
_get_name(PyObject *obj, char **pname)
{
#ifdef MS_WIN32
    if (PyLong_Check(obj)) {
        /* We have to use MAKEINTRESOURCEA for Windows CE.
           Works on Windows as well, of course.
        */
        *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
        return 1;
    }
#endif
    if (PyBytes_Check(obj)) {
        *pname = PyBytes_AS_STRING(obj);
        return *pname ? 1 : 0;
    }
    if (PyUnicode_Check(obj)) {
        *pname = _PyUnicode_AsString(obj);
        return *pname ? 1 : 0;
    }
    PyErr_SetString(PyExc_TypeError,
                    "function name must be string or integer");
    return 0;
}


static PyObject *
PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    char *name;
    int (* address)(void);
    PyObject *ftuple;
    PyObject *dll;
    PyObject *obj;
    PyCFuncPtrObject *self;
    void *handle;
    PyObject *paramflags = NULL;

    if (!PyArg_ParseTuple(args, "O|O", &ftuple, &paramflags))
        return NULL;
    if (paramflags == Py_None)
        paramflags = NULL;

    ftuple = PySequence_Tuple(ftuple);
    if (!ftuple)
        /* Here ftuple is a borrowed reference */
        return NULL;

    if (!PyArg_ParseTuple(ftuple, "O&O", _get_name, &name, &dll)) {
        Py_DECREF(ftuple);
        return NULL;
    }

    obj = PyObject_GetAttrString(dll, "_handle");
    if (!obj) {
        Py_DECREF(ftuple);
        return NULL;
    }
    if (!PyLong_Check(obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "the _handle attribute of the second argument must be an integer");
        Py_DECREF(ftuple);
        Py_DECREF(obj);
        return NULL;
    }
    handle = (void *)PyLong_AsVoidPtr(obj);
    Py_DECREF(obj);
    if (PyErr_Occurred()) {
        PyErr_SetString(PyExc_ValueError,
                        "could not convert the _handle attribute to a pointer");
        Py_DECREF(ftuple);
        return NULL;
    }

#ifdef MS_WIN32
    address = FindAddress(handle, name, (PyObject *)type);
    if (!address) {
        if (!IS_INTRESOURCE(name))
            PyErr_Format(PyExc_AttributeError,
                         "function '%s' not found",
                         name);
        else
            PyErr_Format(PyExc_AttributeError,
                         "function ordinal %d not found",
                         (WORD)(size_t)name);
        Py_DECREF(ftuple);
        return NULL;
    }
#else
    address = (PPROC)ctypes_dlsym(handle, name);
    if (!address) {
#ifdef __CYGWIN__
/* dlerror() isn't very helpful on cygwin */
        PyErr_Format(PyExc_AttributeError,
                     "function '%s' not found (%s) ",
                     name);
#else
        PyErr_SetString(PyExc_AttributeError, ctypes_dlerror());
#endif
        Py_DECREF(ftuple);
        return NULL;
    }
#endif
    Py_INCREF(dll); /* for KeepRef */
    Py_DECREF(ftuple);
    if (!_validate_paramflags(type, paramflags))
        return NULL;

    self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
    if (!self)
        return NULL;

    Py_XINCREF(paramflags);
    self->paramflags = paramflags;

    *(void **)self->b_ptr = address;

    if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
        Py_DECREF((PyObject *)self);
        return NULL;
    }

    Py_INCREF(self);
    self->callable = (PyObject *)self;
    return (PyObject *)self;
}

#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;

    if (!_validate_paramflags(type, paramflags))
        return NULL;

    self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
    self->index = index + 0x1000;
    Py_XINCREF(paramflags);
    self->paramflags = 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)
{
    PyCFuncPtrObject *self;
    PyObject *callable;
    StgDictObject *dict;
    CThunkObject *thunk;

    if (PyTuple_GET_SIZE(args) == 0)
        return GenericPyCData_new(type, args, kwds);

    if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
        return PyCFuncPtr_FromDll(type, args, kwds);

#ifdef MS_WIN32
    if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
        return PyCFuncPtr_FromVtblIndex(type, args, kwds);
#endif

    if (1 == PyTuple_GET_SIZE(args)
        && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
        CDataObject *ob;
        void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
        if (ptr == NULL && PyErr_Occurred())
            return NULL;
        ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
        if (ob == NULL)
            return NULL;
        *(void **)ob->b_ptr = ptr;
        return (PyObject *)ob;
    }

    if (!PyArg_ParseTuple(args, "O", &callable))
        return NULL;
    if (!PyCallable_Check(callable)) {
        PyErr_SetString(PyExc_TypeError,
                        "argument must be callable or integer function address");
        return NULL;
    }

    /* XXX XXX This would allow to pass additional options.  For COM
       method *implementations*, we would probably want different
       behaviour than in 'normal' callback functions: return a HRESULT if
       an exception occurs in the callback, and print the traceback not
       only on the console, but also to OutputDebugString() or something
       like that.
    */
/*
    if (kwds && PyDict_GetItemString(kwds, "options")) {
        ...
    }
*/

    dict = PyType_stgdict((PyObject *)type);
    /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
    if (!dict || !dict->argtypes) {
        PyErr_SetString(PyExc_TypeError,
               "cannot construct instance of this class:"
            " no argtypes");
        return NULL;
    }

    thunk = _ctypes_alloc_callback(callable,
                                  dict->argtypes,
                                  dict->restype,
                                  dict->flags);
    if (!thunk)
        return NULL;

    self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds);
    if (self == NULL) {
        Py_DECREF(thunk);
        return NULL;
    }

    Py_INCREF(callable);
    self->callable = callable;

    self->thunk = thunk;
    *(void **)self->b_ptr = (void *)thunk->pcl_exec;

    Py_INCREF((PyObject *)thunk); /* for KeepRef */
    if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
        Py_DECREF((PyObject *)self);
        return NULL;
    }
    return (PyObject *)self;
}


/*
  _byref consumes a refcount to its argument
*/
static PyObject *
_byref(PyObject *obj)
{
    PyCArgObject *parg;
    if (!CDataObject_Check(obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "expected CData instance");
        return NULL;
    }

    parg = PyCArgObject_new();
    if (parg == NULL) {
        Py_DECREF(obj);
        return NULL;
    }

    parg->tag = 'P';
    parg->pffi_type = &ffi_type_pointer;
    parg->obj = obj;
    parg->value.p = ((CDataObject *)obj)->b_ptr;
    return (PyObject *)parg;
}

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

    if (*pindex < PyTuple_GET_SIZE(inargs)) {
        v = PyTuple_GET_ITEM(inargs, *pindex);
        ++*pindex;
        Py_INCREF(v);
        return v;
    }
    if (kwds && name && (v = PyDict_GetItem(kwds, name))) {
        ++*pindex;
        Py_INCREF(v);
        return v;
    }
    if (defval) {
        Py_INCREF(defval);
        return defval;
    }
    /* we can't currently emit a better error message */
    if (name)
        PyErr_Format(PyExc_TypeError,
                     "required argument '%S' missing", name);
    else
        PyErr_Format(PyExc_TypeError,
                     "not enough arguments");
    return NULL;
}

/*
 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(PyCFuncPtrObject *self, PyObject *argtypes,
                PyObject *inargs, PyObject *kwds,
                int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
{
    PyObject *paramflags = self->paramflags;
    PyObject *callargs;
    StgDictObject *dict;
    Py_ssize_t i, len;
    int inargs_index = 0;
    /* It's a little bit difficult to determine how many arguments the
    function call requires/accepts.  For simplicity, we count the consumed
    args and compare this to the number of supplied args. */
    Py_ssize_t actual_args;

    *poutmask = 0;
    *pinoutmask = 0;
    *pnumretvals = 0;

    /* Trivial cases, where we either return inargs itself, or a slice of it. */
    if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
#ifdef MS_WIN32
        if (self->index)
            return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
#endif
        Py_INCREF(inargs);
        return inargs;
    }

    len = PyTuple_GET_SIZE(argtypes);
    callargs = PyTuple_New(len); /* the argument tuple we build */
    if (callargs == NULL)
        return NULL;

#ifdef MS_WIN32
    /* For a COM method, skip the first arg */
    if (self->index) {
        inargs_index = 1;
    }
#endif
    for (i = 0; i < len; ++i) {
        PyObject *item = PyTuple_GET_ITEM(paramflags, i);
        PyObject *ob;
        int flag;
        PyObject *name = NULL;
        PyObject *defval = NULL;

        /* This way seems to be ~2 us faster than the PyArg_ParseTuple
           calls below. */
        /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
        Py_ssize_t tsize = PyTuple_GET_SIZE(item);
        flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0));
        name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
        defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;

        switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
        case PARAMFLAG_FIN | PARAMFLAG_FLCID:
            /* ['in', 'lcid'] parameter.  Always taken from defval,
             if given, else the integer 0. */
            if (defval == NULL) {
                defval = PyLong_FromLong(0);
                if (defval == NULL)
                    goto error;
            } else
                Py_INCREF(defval);
            PyTuple_SET_ITEM(callargs, i, defval);
            break;
        case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
            *pinoutmask |= (1 << i); /* mark as inout arg */
            (*pnumretvals)++;
            /* fall through to PARAMFLAG_FIN... */
        case 0:
        case PARAMFLAG_FIN:
            /* 'in' parameter.  Copy it from inargs. */
            ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
            if (ob == NULL)
                goto error;
            PyTuple_SET_ITEM(callargs, i, ob);
            break;
        case PARAMFLAG_FOUT:
            /* XXX Refactor this code into a separate function. */
            /* 'out' parameter.
               argtypes[i] must be a POINTER to a c type.

               Cannot by supplied in inargs, but a defval will be used
               if available.  XXX Should we support getting it from kwds?
            */
            if (defval) {
                /* XXX Using mutable objects as defval will
                   make the function non-threadsafe, unless we
                   copy the object in each invocation */
                Py_INCREF(defval);
                PyTuple_SET_ITEM(callargs, i, defval);
                *poutmask |= (1 << i); /* mark as out arg */
                (*pnumretvals)++;
                break;
            }
            ob = PyTuple_GET_ITEM(argtypes, i);
            dict = PyType_stgdict(ob);
            if (dict == NULL) {
                /* Cannot happen: _validate_paramflags()
                  would not accept such an object */
                PyErr_Format(PyExc_RuntimeError,
                             "NULL stgdict unexpected");
                goto error;
            }
            if (PyUnicode_Check(dict->proto)) {
                PyErr_Format(
                    PyExc_TypeError,
                    "%s 'out' parameter must be passed as default value",
                    ((PyTypeObject *)ob)->tp_name);
                goto error;
            }
            if (PyCArrayTypeObject_Check(ob))
                ob = PyObject_CallObject(ob, NULL);
            else
                /* Create an instance of the pointed-to type */
                ob = PyObject_CallObject(dict->proto, NULL);
            /*
               XXX Is the following correct any longer?
               We must not pass a byref() to the array then but
               the array instance itself. Then, we cannot retrive
               the result from the PyCArgObject.
            */
            if (ob == NULL)
                goto error;
            /* The .from_param call that will ocurr later will pass this
               as a byref parameter. */
            PyTuple_SET_ITEM(callargs, i, ob);
            *poutmask |= (1 << i); /* mark as out arg */
            (*pnumretvals)++;
            break;
        default:
            PyErr_Format(PyExc_ValueError,
                         "paramflag %d not yet implemented", flag);
            goto error;
            break;
        }
    }

    /* We have counted the arguments we have consumed in 'inargs_index'.  This
       must be the same as len(inargs) + len(kwds), otherwise we have
       either too much or not enough arguments. */

    actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
    if (actual_args != inargs_index) {
        /* When we have default values or named parameters, this error
           message is misleading.  See unittests/test_paramflags.py
         */
        PyErr_Format(PyExc_TypeError,
                     "call takes exactly %d arguments (%zd given)",
                     inargs_index, actual_args);
        goto error;
    }

    /* outmask is a bitmask containing indexes into callargs.  Items at
       these indexes contain values to return.
     */
    return callargs;
  error:
    Py_DECREF(callargs);
    return NULL;
}

/* 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)
{
    unsigned int i, index;
    int bit;
    PyObject *tup = NULL;

    if (callargs == NULL)
        return result;
    if (result == NULL || numretvals == 0) {
        Py_DECREF(callargs);
        return result;
    }
    Py_DECREF(result);

    /* tup will not be allocated if numretvals == 1 */
    /* allocate tuple to hold the result */
    if (numretvals > 1) {
        tup = PyTuple_New(numretvals);
        if (tup == NULL) {
            Py_DECREF(callargs);
            return NULL;
        }
    }

    index = 0;
    for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
        PyObject *v;
        if (bit & inoutmask) {
            v = PyTuple_GET_ITEM(callargs, i);
            Py_INCREF(v);
            if (numretvals == 1) {
                Py_DECREF(callargs);
                return v;
            }
            PyTuple_SET_ITEM(tup, index, v);
            index++;
        } else if (bit & outmask) {
            _Py_IDENTIFIER(__ctypes_from_outparam__);

            v = PyTuple_GET_ITEM(callargs, i);
            v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL);
            if (v == NULL || numretvals == 1) {
                Py_DECREF(callargs);
                return v;
            }
            PyTuple_SET_ITEM(tup, index, v);
            index++;
        }
        if (index == numretvals)
            break;
    }

    Py_DECREF(callargs);
    return tup;
}

static PyObject *
PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
{
    PyObject *restype;
    PyObject *converters;
    PyObject *checker;
    PyObject *argtypes;
    StgDictObject *dict = PyObject_stgdict((PyObject *)self);
    PyObject *result;
    PyObject *callargs;
    PyObject *errcheck;
#ifdef MS_WIN32
    IUnknown *piunk = NULL;
#endif
    void *pProc = NULL;

    int inoutmask;
    int outmask;
    unsigned int numretvals;

    assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */
    restype = self->restype ? self->restype : dict->restype;
    converters = self->converters ? self->converters : dict->converters;
    checker = self->checker ? self->checker : dict->checker;
    argtypes = self->argtypes ? self->argtypes : dict->argtypes;
/* later, we probably want to have an errcheck field in stgdict */
    errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;


    pProc = *(void **)self->b_ptr;
#ifdef MS_WIN32
    if (self->index) {
        /* It's a COM method */
        CDataObject *this;
        this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
        if (!this) {
            PyErr_SetString(PyExc_ValueError,
                            "native com method call without 'this' parameter");
            return NULL;
        }
        if (!CDataObject_Check(this)) {
            PyErr_SetString(PyExc_TypeError,
                            "Expected a COM this pointer as first argument");
            return NULL;
        }
        /* there should be more checks? No, in Python */
        /* First arg is an pointer to an interface instance */
        if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
            PyErr_SetString(PyExc_ValueError,
                            "NULL COM pointer access");
            return NULL;
        }
        piunk = *(IUnknown **)this->b_ptr;
        if (NULL == piunk->lpVtbl) {
            PyErr_SetString(PyExc_ValueError,
                            "COM method call without VTable");
            return NULL;
        }
        pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
    }
#endif
    callargs = _build_callargs(self, argtypes,
                               inargs, kwds,
                               &outmask, &inoutmask, &numretvals);
    if (callargs == NULL)
        return NULL;

    if (converters) {
        int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
                                        Py_ssize_t, int);
        int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
                                      Py_ssize_t, int);

        if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
            /* For cdecl functions, we allow more actual arguments
               than the length of the argtypes tuple.
            */
            if (required > actual) {
                Py_DECREF(callargs);
                PyErr_Format(PyExc_TypeError,
              "this function takes at least %d argument%s (%d given)",
                                 required,
                                 required == 1 ? "" : "s",
                                 actual);
                return NULL;
            }
        } else if (required != actual) {
            Py_DECREF(callargs);
            PyErr_Format(PyExc_TypeError,
                 "this function takes %d argument%s (%d given)",
                     required,
                     required == 1 ? "" : "s",
                     actual);
            return NULL;
        }
    }

    result = _ctypes_callproc(pProc,
                       callargs,
#ifdef MS_WIN32
                       piunk,
                       self->iid,
#endif
                       dict->flags,
                       converters,
                       restype,
                       checker);
/* The 'errcheck' protocol */
    if (result != NULL && errcheck) {
        PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
                                                   result,
                                                   self,
                                                   callargs,
                                                   NULL);
        /* If the errcheck funtion failed, return NULL.
           If the errcheck function returned callargs unchanged,
           continue normal processing.
           If the errcheck function returned something else,
           use that as result.
        */
        if (v == NULL || v != callargs) {
            Py_DECREF(result);
            Py_DECREF(callargs);
            return v;
        }
        Py_DECREF(v);
    }

    return _build_result(result, callargs,
                         outmask, inoutmask, numretvals);
}

static int
PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
{
    Py_VISIT(self->callable);
    Py_VISIT(self->restype);
    Py_VISIT(self->checker);
    Py_VISIT(self->errcheck);
    Py_VISIT(self->argtypes);
    Py_VISIT(self->converters);
    Py_VISIT(self->paramflags);
    Py_VISIT(self->thunk);
    return PyCData_traverse((CDataObject *)self, visit, arg);
}

static int
PyCFuncPtr_clear(PyCFuncPtrObject *self)
{
    Py_CLEAR(self->callable);
    Py_CLEAR(self->restype);
    Py_CLEAR(self->checker);
    Py_CLEAR(self->errcheck);
    Py_CLEAR(self->argtypes);
    Py_CLEAR(self->converters);
    Py_CLEAR(self->paramflags);
    Py_CLEAR(self->thunk);
    return PyCData_clear((CDataObject *)self);
}

static void
PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
{
    PyCFuncPtr_clear(self);
    Py_TYPE(self)->tp_free((PyObject *)self);
}

static PyObject *
PyCFuncPtr_repr(PyCFuncPtrObject *self)
{
#ifdef MS_WIN32
    if (self->index)
        return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
                                   self->index - 0x1000,
                                   Py_TYPE(self)->tp_name,
                                   self);
#endif
    return PyUnicode_FromFormat("<%s object at %p>",
                               Py_TYPE(self)->tp_name,
                               self);
}

static int
PyCFuncPtr_bool(PyCFuncPtrObject *self)
{
    return ((*(void **)self->b_ptr != NULL)
#ifdef MS_WIN32
        || (self->index != 0)
#endif
        );
}

static PyNumberMethods PyCFuncPtr_as_number = {
    0, /* nb_add */
    0, /* nb_subtract */
    0, /* nb_multiply */
    0, /* nb_remainder */
    0, /* nb_divmod */
    0, /* nb_power */
    0, /* nb_negative */
    0, /* nb_positive */
    0, /* nb_absolute */
    (inquiry)PyCFuncPtr_bool, /* nb_bool */
};

PyTypeObject PyCFuncPtr_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.PyCFuncPtr",
    sizeof(PyCFuncPtrObject),                           /* tp_basicsize */
    0,                                          /* tp_itemsize */
    (destructor)PyCFuncPtr_dealloc,             /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc)PyCFuncPtr_repr,                  /* tp_repr */
    &PyCFuncPtr_as_number,                      /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    (ternaryfunc)PyCFuncPtr_call,               /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    &PyCData_as_buffer,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "Function Pointer",                         /* tp_doc */
    (traverseproc)PyCFuncPtr_traverse,          /* tp_traverse */
    (inquiry)PyCFuncPtr_clear,                  /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    PyCFuncPtr_getsets,                         /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    PyCFuncPtr_new,                             /* tp_new */
    0,                                          /* tp_free */
};

/*****************************************************************/
/*
  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)
{
    StgDictObject *dict;
    PyObject *fields;
    Py_ssize_t i;

    if (PyType_stgdict((PyObject *)type->tp_base)) {
        index = _init_pos_args(self, type->tp_base,
                               args, kwds,
                               index);
        if (index == -1)
            return -1;
    }

    dict = PyType_stgdict((PyObject *)type);
    fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
    if (fields == NULL)
        return index;

    for (i = 0;
         i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
         ++i) {
        PyObject *pair = PySequence_GetItem(fields, i);
        PyObject *name, *val;
        int res;
        if (!pair)
            return -1;
        name = PySequence_GetItem(pair, 0);
        if (!name) {
            Py_DECREF(pair);
            return -1;
        }
        val = PyTuple_GET_ITEM(args, i + index);
        if (kwds && PyDict_GetItem(kwds, name)) {
            char *field = PyBytes_AsString(name);
            if (field == NULL) {
                PyErr_Clear();
                field = "???";
            }
            PyErr_Format(PyExc_TypeError,
                         "duplicate values for field '%s'",
                         field);
            Py_DECREF(pair);
            Py_DECREF(name);
            return -1;
        }

        res = PyObject_SetAttr(self, name, val);
        Py_DECREF(pair);
        Py_DECREF(name);
        if (res == -1)
            return -1;
    }
    return index + dict->length;
}

static int
Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
{
/* Optimization possible: Store the attribute names _fields_[x][0]
 * in C accessible fields somewhere ?
 */
    if (!PyTuple_Check(args)) {
        PyErr_SetString(PyExc_TypeError,
                        "args not a tuple?");
        return -1;
    }
    if (PyTuple_GET_SIZE(args)) {
        int res = _init_pos_args(self, Py_TYPE(self),
                                 args, kwds, 0);
        if (res == -1)
            return -1;
        if (res < PyTuple_GET_SIZE(args)) {
            PyErr_SetString(PyExc_TypeError,
                            "too many initializers");
            return -1;
        }
    }

    if (kwds) {
        PyObject *key, *value;
        Py_ssize_t pos = 0;
        while(PyDict_Next(kwds, &pos, &key, &value)) {
            if (-1 == PyObject_SetAttr(self, key, value))
                return -1;
        }
    }
    return 0;
}

static PyTypeObject Struct_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.Structure",
    sizeof(CDataObject),                        /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    &PyCData_as_buffer,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "Structure base class",                     /* tp_doc */
    (traverseproc)PyCData_traverse,             /* tp_traverse */
    (inquiry)PyCData_clear,                     /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    Struct_init,                                /* tp_init */
    0,                                          /* tp_alloc */
    GenericPyCData_new,                         /* tp_new */
    0,                                          /* tp_free */
};

static PyTypeObject Union_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.Union",
    sizeof(CDataObject),                        /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    &PyCData_as_buffer,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "Union base class",                         /* tp_doc */
    (traverseproc)PyCData_traverse,             /* tp_traverse */
    (inquiry)PyCData_clear,                     /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    Struct_init,                                /* tp_init */
    0,                                          /* tp_alloc */
    GenericPyCData_new,                         /* tp_new */
    0,                                          /* tp_free */
};


/******************************************************************/
/*
  PyCArray_Type
*/
static int
Array_init(CDataObject *self, PyObject *args, PyObject *kw)
{
    Py_ssize_t i;
    Py_ssize_t n;

    if (!PyTuple_Check(args)) {
        PyErr_SetString(PyExc_TypeError,
                        "args not a tuple?");
        return -1;
    }
    n = PyTuple_GET_SIZE(args);
    for (i = 0; i < n; ++i) {
        PyObject *v;
        v = PyTuple_GET_ITEM(args, i);
        if (-1 == PySequence_SetItem((PyObject *)self, i, v))
            return -1;
    }
    return 0;
}

static PyObject *
Array_item(PyObject *myself, Py_ssize_t index)
{
    CDataObject *self = (CDataObject *)myself;
    Py_ssize_t offset, size;
    StgDictObject *stgdict;


    if (index < 0 || index >= self->b_length) {
        PyErr_SetString(PyExc_IndexError,
                        "invalid index");
        return NULL;
    }

    stgdict = PyObject_stgdict((PyObject *)self);
    assert(stgdict); /* Cannot be NULL for array instances */
    /* Would it be clearer if we got the item size from
       stgdict->proto's stgdict?
    */
    size = stgdict->size / stgdict->length;
    offset = index * size;

    return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
                     index, size, self->b_ptr + offset);
}

static PyObject *
Array_subscript(PyObject *myself, PyObject *item)
{
    CDataObject *self = (CDataObject *)myself;

    if (PyIndex_Check(item)) {
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);

        if (i == -1 && PyErr_Occurred())
            return NULL;
        if (i < 0)
            i += self->b_length;
        return Array_item(myself, i);
    }
    else if PySlice_Check(item) {
        StgDictObject *stgdict, *itemdict;
        PyObject *proto;
        PyObject *np;
        Py_ssize_t start, stop, step, slicelen, cur, i;

        if (PySlice_GetIndicesEx(item,
                                 self->b_length, &start, &stop,
                                 &step, &slicelen) < 0) {
            return NULL;
        }

        stgdict = PyObject_stgdict((PyObject *)self);
        assert(stgdict); /* Cannot be NULL for array object instances */
        proto = stgdict->proto;
        itemdict = PyType_stgdict(proto);
        assert(itemdict); /* proto is the item type of the array, a
                             ctypes type, so this cannot be NULL */

        if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
            char *ptr = (char *)self->b_ptr;
            char *dest;

            if (slicelen <= 0)
                return PyBytes_FromStringAndSize("", 0);
            if (step == 1) {
                return PyBytes_FromStringAndSize(ptr + start,
                                                 slicelen);
            }
            dest = (char *)PyMem_Malloc(slicelen);

            if (dest == NULL)
                return PyErr_NoMemory();

            for (cur = start, i = 0; i < slicelen;
                 cur += step, i++) {
                dest[i] = ptr[cur];
            }

            np = PyBytes_FromStringAndSize(dest, slicelen);
            PyMem_Free(dest);
            return np;
        }
#ifdef CTYPES_UNICODE
        if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
            wchar_t *ptr = (wchar_t *)self->b_ptr;
            wchar_t *dest;

            if (slicelen <= 0)
                return PyUnicode_New(0, 0);
            if (step == 1) {
                return PyUnicode_FromWideChar(ptr + start,
                                              slicelen);
            }

            dest = (wchar_t *)PyMem_Malloc(
                                    slicelen * sizeof(wchar_t));

            for (cur = start, i = 0; i < slicelen;
                 cur += step, i++) {
                dest[i] = ptr[cur];
            }

            np = PyUnicode_FromWideChar(dest, slicelen);
            PyMem_Free(dest);
            return np;
        }
#endif

        np = PyList_New(slicelen);
        if (np == NULL)
            return NULL;

        for (cur = start, i = 0; i < slicelen;
             cur += step, i++) {
            PyObject *v = Array_item(myself, cur);
            PyList_SET_ITEM(np, i, v);
        }
        return np;
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "indices must be integers");
        return NULL;
    }

}

static int
Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
{
    CDataObject *self = (CDataObject *)myself;
    Py_ssize_t size, offset;
    StgDictObject *stgdict;
    char *ptr;

    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "Array does not support item deletion");
        return -1;
    }

    stgdict = PyObject_stgdict((PyObject *)self);
    assert(stgdict); /* Cannot be NULL for array object instances */
    if (index < 0 || index >= stgdict->length) {
        PyErr_SetString(PyExc_IndexError,
                        "invalid index");
        return -1;
    }
    size = stgdict->size / stgdict->length;
    offset = index * size;
    ptr = self->b_ptr + offset;

    return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
                     index, size, ptr);
}

static int
Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
{
    CDataObject *self = (CDataObject *)myself;

    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "Array does not support item deletion");
        return -1;
    }

    if (PyIndex_Check(item)) {
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);

        if (i == -1 && PyErr_Occurred())
            return -1;
        if (i < 0)
            i += self->b_length;
        return Array_ass_item(myself, i, value);
    }
    else if (PySlice_Check(item)) {
        Py_ssize_t start, stop, step, slicelen, otherlen, i, cur;

        if (PySlice_GetIndicesEx(item,
                                 self->b_length, &start, &stop,
                                 &step, &slicelen) < 0) {
            return -1;
        }
        if ((step < 0 && start < stop) ||
            (step > 0 && start > stop))
            stop = start;

        otherlen = PySequence_Length(value);
        if (otherlen != slicelen) {
            PyErr_SetString(PyExc_ValueError,
                "Can only assign sequence of same size");
            return -1;
        }
        for (cur = start, i = 0; i < otherlen; cur += step, i++) {
            PyObject *item = PySequence_GetItem(value, i);
            int result;
            if (item == NULL)
                return -1;
            result = Array_ass_item(myself, cur, item);
            Py_DECREF(item);
            if (result == -1)
                return -1;
        }
        return 0;
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "indices must be integer");
        return -1;
    }
}

static Py_ssize_t
Array_length(PyObject *myself)
{
    CDataObject *self = (CDataObject *)myself;
    return self->b_length;
}

static PySequenceMethods Array_as_sequence = {
    Array_length,                               /* sq_length; */
    0,                                          /* sq_concat; */
    0,                                          /* sq_repeat; */
    Array_item,                                 /* sq_item; */
    0,                                          /* sq_slice; */
    Array_ass_item,                             /* sq_ass_item; */
    0,                                          /* sq_ass_slice; */
    0,                                          /* sq_contains; */

    0,                                          /* sq_inplace_concat; */
    0,                                          /* sq_inplace_repeat; */
};

static PyMappingMethods Array_as_mapping = {
    Array_length,
    Array_subscript,
    Array_ass_subscript,
};

PyTypeObject PyCArray_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.Array",
    sizeof(CDataObject),                        /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    &Array_as_sequence,                         /* tp_as_sequence */
    &Array_as_mapping,                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    &PyCData_as_buffer,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "XXX to be provided",                       /* tp_doc */
    (traverseproc)PyCData_traverse,             /* tp_traverse */
    (inquiry)PyCData_clear,                     /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    0,                                          /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    (initproc)Array_init,                       /* tp_init */
    0,                                          /* tp_alloc */
    GenericPyCData_new,                         /* tp_new */
    0,                                          /* tp_free */
};

PyObject *
PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
{
    static PyObject *cache;
    PyObject *key;
    PyObject *result;
    char name[256];
    PyObject *len;

    if (cache == NULL) {
        cache = PyDict_New();
        if (cache == NULL)
            return NULL;
    }
    len = PyLong_FromSsize_t(length);
    if (len == NULL)
        return NULL;
    key = PyTuple_Pack(2, itemtype, len);
    Py_DECREF(len);
    if (!key)
        return NULL;
    result = PyDict_GetItemProxy(cache, key);
    if (result) {
        Py_INCREF(result);
        Py_DECREF(key);
        return result;
    }

    if (!PyType_Check(itemtype)) {
        PyErr_SetString(PyExc_TypeError,
                        "Expected a type object");
        Py_DECREF(key);
        return NULL;
    }
#ifdef MS_WIN64
    sprintf(name, "%.200s_Array_%Id",
        ((PyTypeObject *)itemtype)->tp_name, length);
#else
    sprintf(name, "%.200s_Array_%ld",
        ((PyTypeObject *)itemtype)->tp_name, (long)length);
#endif

    result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type,
                                   "s(O){s:n,s:O}",
                                   name,
                                   &PyCArray_Type,
                                   "_length_",
                                   length,
                                   "_type_",
                                   itemtype
        );
    if (result == NULL) {
        Py_DECREF(key);
        return NULL;
    }
    if (-1 == PyDict_SetItemProxy(cache, key, result)) {
        Py_DECREF(key);
        Py_DECREF(result);
        return NULL;
    }
    Py_DECREF(key);
    return result;
}


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

static int
Simple_set_value(CDataObject *self, PyObject *value)
{
    PyObject *result;
    StgDictObject *dict = PyObject_stgdict((PyObject *)self);

    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "can't delete attribute");
        return -1;
    }
    assert(dict); /* Cannot be NULL for CDataObject instances */
    assert(dict->setfunc);
    result = dict->setfunc(self->b_ptr, value, dict->size);
    if (!result)
        return -1;

    /* consumes the refcount the setfunc returns */
    return KeepRef(self, 0, result);
}

static int
Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
{
    PyObject *value = NULL;
    if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
        return -1;
    if (value)
        return Simple_set_value(self, value);
    return 0;
}

static PyObject *
Simple_get_value(CDataObject *self)
{
    StgDictObject *dict;
    dict = PyObject_stgdict((PyObject *)self);
    assert(dict); /* Cannot be NULL for CDataObject instances */
    assert(dict->getfunc);
    return dict->getfunc(self->b_ptr, self->b_size);
}

static PyGetSetDef Simple_getsets[] = {
    { "value", (getter)Simple_get_value, (setter)Simple_set_value,
      "current value", NULL },
    { NULL, NULL }
};

static PyObject *
Simple_from_outparm(PyObject *self, PyObject *args)
{
    if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) {
        Py_INCREF(self);
        return self;
    }
    /* call stgdict->getfunc */
    return Simple_get_value((CDataObject *)self);
}

static PyMethodDef Simple_methods[] = {
    { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
    { NULL, NULL },
};

static int Simple_bool(CDataObject *self)
{
    return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
}

static PyNumberMethods Simple_as_number = {
    0, /* nb_add */
    0, /* nb_subtract */
    0, /* nb_multiply */
    0, /* nb_remainder */
    0, /* nb_divmod */
    0, /* nb_power */
    0, /* nb_negative */
    0, /* nb_positive */
    0, /* nb_absolute */
    (inquiry)Simple_bool, /* nb_bool */
};

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

    if (Py_TYPE(self)->tp_base != &Simple_Type) {
        return PyUnicode_FromFormat("<%s object at %p>",
                                   Py_TYPE(self)->tp_name, self);
    }

    val = Simple_get_value(self);
    if (val == NULL)
        return NULL;

    result = PyUnicode_FromFormat("%s(%R)",
                                  Py_TYPE(self)->tp_name, val);
    Py_DECREF(val);
    return result;
}

static PyTypeObject Simple_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes._SimpleCData",
    sizeof(CDataObject),                        /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc)&Simple_repr,                     /* tp_repr */
    &Simple_as_number,                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    &PyCData_as_buffer,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "XXX to be provided",                       /* tp_doc */
    (traverseproc)PyCData_traverse,             /* tp_traverse */
    (inquiry)PyCData_clear,                     /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    Simple_methods,                             /* tp_methods */
    0,                                          /* tp_members */
    Simple_getsets,                             /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    (initproc)Simple_init,                      /* tp_init */
    0,                                          /* tp_alloc */
    GenericPyCData_new,                         /* tp_new */
    0,                                          /* tp_free */
};

/******************************************************************/
/*
  PyCPointer_Type
*/
static PyObject *
Pointer_item(PyObject *myself, Py_ssize_t index)
{
    CDataObject *self = (CDataObject *)myself;
    Py_ssize_t size;
    Py_ssize_t offset;
    StgDictObject *stgdict, *itemdict;
    PyObject *proto;

    if (*(void **)self->b_ptr == NULL) {
        PyErr_SetString(PyExc_ValueError,
                        "NULL pointer access");
        return NULL;
    }

    stgdict = PyObject_stgdict((PyObject *)self);
    assert(stgdict); /* Cannot be NULL for pointer object instances */

    proto = stgdict->proto;
    assert(proto);
    itemdict = PyType_stgdict(proto);
    assert(itemdict); /* proto is the item type of the pointer, a ctypes
                         type, so this cannot be NULL */

    size = itemdict->size;
    offset = index * itemdict->size;

    return PyCData_get(proto, stgdict->getfunc, (PyObject *)self,
                     index, size, (*(char **)self->b_ptr) + offset);
}

static int
Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
{
    CDataObject *self = (CDataObject *)myself;
    Py_ssize_t size;
    Py_ssize_t offset;
    StgDictObject *stgdict, *itemdict;
    PyObject *proto;

    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "Pointer does not support item deletion");
        return -1;
    }

    if (*(void **)self->b_ptr == NULL) {
        PyErr_SetString(PyExc_ValueError,
                        "NULL pointer access");
        return -1;
    }

    stgdict = PyObject_stgdict((PyObject *)self);
    assert(stgdict); /* Cannot be NULL fr pointer instances */

    proto = stgdict->proto;
    assert(proto);

    itemdict = PyType_stgdict(proto);
    assert(itemdict); /* Cannot be NULL because the itemtype of a pointer
                         is always a ctypes type */

    size = itemdict->size;
    offset = index * itemdict->size;

    return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value,
                     index, size, (*(char **)self->b_ptr) + offset);
}

static PyObject *
Pointer_get_contents(CDataObject *self, void *closure)
{
    StgDictObject *stgdict;

    if (*(void **)self->b_ptr == NULL) {
        PyErr_SetString(PyExc_ValueError,
                        "NULL pointer access");
        return NULL;
    }

    stgdict = PyObject_stgdict((PyObject *)self);
    assert(stgdict); /* Cannot be NULL fr pointer instances */
    return PyCData_FromBaseObj(stgdict->proto,
                             (PyObject *)self, 0,
                             *(void **)self->b_ptr);
}

static int
Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
{
    StgDictObject *stgdict;
    CDataObject *dst;
    PyObject *keep;

    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "Pointer does not support item deletion");
        return -1;
    }
    stgdict = PyObject_stgdict((PyObject *)self);
    assert(stgdict); /* Cannot be NULL fr pointer instances */
    assert(stgdict->proto);
    if (!CDataObject_Check(value)) {
        int res = PyObject_IsInstance(value, stgdict->proto);
        if (res == -1)
            return -1;
        if (!res) {
            PyErr_Format(PyExc_TypeError,
                         "expected %s instead of %s",
                         ((PyTypeObject *)(stgdict->proto))->tp_name,
                         Py_TYPE(value)->tp_name);
            return -1;
        }
    }

    dst = (CDataObject *)value;
    *(void **)self->b_ptr = dst->b_ptr;

    /*
       A Pointer instance must keep a the value it points to alive.  So, a
       pointer instance has b_length set to 2 instead of 1, and we set
       'value' itself as the second item of the b_objects list, additionally.
    */
    Py_INCREF(value);
    if (-1 == KeepRef(self, 1, value))
        return -1;

    keep = GetKeepedObjects(dst);
    Py_INCREF(keep);
    return KeepRef(self, 0, keep);
}

static PyGetSetDef Pointer_getsets[] = {
    { "contents", (getter)Pointer_get_contents,
      (setter)Pointer_set_contents,
      "the object this pointer points to (read-write)", NULL },
    { NULL, NULL }
};

static int
Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
{
    PyObject *value = NULL;

    if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
        return -1;
    if (value == NULL)
        return 0;
    return Pointer_set_contents(self, value, NULL);
}

static PyObject *
Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    StgDictObject *dict = PyType_stgdict((PyObject *)type);
    if (!dict || !dict->proto) {
        PyErr_SetString(PyExc_TypeError,
                        "Cannot create instance: has no _type_");
        return NULL;
    }
    return GenericPyCData_new(type, args, kw);
}

static PyObject *
Pointer_subscript(PyObject *myself, PyObject *item)
{
    CDataObject *self = (CDataObject *)myself;
    if (PyIndex_Check(item)) {
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        if (i == -1 && PyErr_Occurred())
            return NULL;
        return Pointer_item(myself, i);
    }
    else if (PySlice_Check(item)) {
        PySliceObject *slice = (PySliceObject *)item;
        Py_ssize_t start, stop, step;
        PyObject *np;
        StgDictObject *stgdict, *itemdict;
        PyObject *proto;
        Py_ssize_t i, len, cur;

        /* Since pointers have no length, and we want to apply
           different semantics to negative indices than normal
           slicing, we have to dissect the slice object ourselves.*/
        if (slice->step == Py_None) {
            step = 1;
        }
        else {
            step = PyNumber_AsSsize_t(slice->step,
                                      PyExc_ValueError);
            if (step == -1 && PyErr_Occurred())
                return NULL;
            if (step == 0) {
                PyErr_SetString(PyExc_ValueError,
                                "slice step cannot be zero");
                return NULL;
            }
        }
        if (slice->start == Py_None) {
            if (step < 0) {
                PyErr_SetString(PyExc_ValueError,
                                "slice start is required "
                                "for step < 0");
                return NULL;
            }
            start = 0;
        }
        else {
            start = PyNumber_AsSsize_t(slice->start,
                                       PyExc_ValueError);
            if (start == -1 && PyErr_Occurred())
                return NULL;
        }
        if (slice->stop == Py_None) {
            PyErr_SetString(PyExc_ValueError,
                            "slice stop is required");
            return NULL;
        }
        stop = PyNumber_AsSsize_t(slice->stop,
                                  PyExc_ValueError);
        if (stop == -1 && PyErr_Occurred())
            return NULL;
        if ((step > 0 && start > stop) ||
            (step < 0 && start < stop))
            len = 0;
        else if (step > 0)
            len = (stop - start - 1) / step + 1;
        else
            len = (stop - start + 1) / step + 1;

        stgdict = PyObject_stgdict((PyObject *)self);
        assert(stgdict); /* Cannot be NULL for pointer instances */
        proto = stgdict->proto;
        assert(proto);
        itemdict = PyType_stgdict(proto);
        assert(itemdict);
        if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
            char *ptr = *(char **)self->b_ptr;
            char *dest;

            if (len <= 0)
                return PyBytes_FromStringAndSize("", 0);
            if (step == 1) {
                return PyBytes_FromStringAndSize(ptr + start,
                                                 len);
            }
            dest = (char *)PyMem_Malloc(len);
            if (dest == NULL)
                return PyErr_NoMemory();
            for (cur = start, i = 0; i < len; cur += step, i++) {
                dest[i] = ptr[cur];
            }
            np = PyBytes_FromStringAndSize(dest, len);
            PyMem_Free(dest);
            return np;
        }
#ifdef CTYPES_UNICODE
        if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
            wchar_t *ptr = *(wchar_t **)self->b_ptr;
            wchar_t *dest;

            if (len <= 0)
                return PyUnicode_New(0, 0);
            if (step == 1) {
                return PyUnicode_FromWideChar(ptr + start,
                                              len);
            }
            dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t));
            if (dest == NULL)
                return PyErr_NoMemory();
            for (cur = start, i = 0; i < len; cur += step, i++) {
                dest[i] = ptr[cur];
            }
            np = PyUnicode_FromWideChar(dest, len);
            PyMem_Free(dest);
            return np;
        }
#endif

        np = PyList_New(len);
        if (np == NULL)
            return NULL;

        for (cur = start, i = 0; i < len; cur += step, i++) {
            PyObject *v = Pointer_item(myself, cur);
            PyList_SET_ITEM(np, i, v);
        }
        return np;
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "Pointer indices must be integer");
        return NULL;
    }
}

static PySequenceMethods Pointer_as_sequence = {
    0,                                          /* inquiry sq_length; */
    0,                                          /* binaryfunc sq_concat; */
    0,                                          /* intargfunc sq_repeat; */
    Pointer_item,                               /* intargfunc sq_item; */
    0,                                          /* intintargfunc sq_slice; */
    Pointer_ass_item,                           /* intobjargproc sq_ass_item; */
    0,                                          /* intintobjargproc sq_ass_slice; */
    0,                                          /* objobjproc sq_contains; */
    /* Added in release 2.0 */
    0,                                          /* binaryfunc sq_inplace_concat; */
    0,                                          /* intargfunc sq_inplace_repeat; */
};

static PyMappingMethods Pointer_as_mapping = {
    0,
    Pointer_subscript,
};

static int
Pointer_bool(CDataObject *self)
{
    return (*(void **)self->b_ptr != NULL);
}

static PyNumberMethods Pointer_as_number = {
    0, /* nb_add */
    0, /* nb_subtract */
    0, /* nb_multiply */
    0, /* nb_remainder */
    0, /* nb_divmod */
    0, /* nb_power */
    0, /* nb_negative */
    0, /* nb_positive */
    0, /* nb_absolute */
    (inquiry)Pointer_bool, /* nb_bool */
};

PyTypeObject PyCPointer_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes._Pointer",
    sizeof(CDataObject),                        /* tp_basicsize */
    0,                                          /* tp_itemsize */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    0,                                          /* tp_repr */
    &Pointer_as_number,                         /* tp_as_number */
    &Pointer_as_sequence,                       /* tp_as_sequence */
    &Pointer_as_mapping,                        /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0,                                          /* tp_getattro */
    0,                                          /* tp_setattro */
    &PyCData_as_buffer,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "XXX to be provided",                       /* tp_doc */
    (traverseproc)PyCData_traverse,             /* tp_traverse */
    (inquiry)PyCData_clear,                     /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* tp_methods */
    0,                                          /* tp_members */
    Pointer_getsets,                            /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    (initproc)Pointer_init,                     /* tp_init */
    0,                                          /* tp_alloc */
    Pointer_new,                                /* tp_new */
    0,                                          /* tp_free */
};


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

static const char module_docs[] =
"Create and manipulate C compatible data types in Python.";

#ifdef MS_WIN32

static char comerror_doc[] = "Raised when a COM method call failed.";

int
comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    PyObject *hresult, *text, *details;
    PyBaseExceptionObject *bself;
    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, PySequence_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;

    bself = (PyBaseExceptionObject *)self;
    Py_DECREF(bself->args);
    bself->args = args;
    Py_INCREF(bself->args);

    return 0;
}

static PyTypeObject PyComError_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ctypes.COMError",         /* tp_name */
    sizeof(PyBaseExceptionObject), /* tp_basicsize */
    0,                          /* tp_itemsize */
    0,                          /* tp_dealloc */
    0,                          /* tp_print */
    0,                          /* tp_getattr */
    0,                          /* tp_setattr */
    0,                          /* tp_reserved */
    0,                          /* tp_repr */
    0,                          /* tp_as_number */
    0,                          /* tp_as_sequence */
    0,                          /* tp_as_mapping */
    0,                          /* tp_hash */
    0,                          /* tp_call */
    0,                          /* tp_str */
    0,                          /* tp_getattro */
    0,                          /* tp_setattro */
    0,                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */
    PyDoc_STR(comerror_doc),    /* tp_doc */
    0,                          /* tp_traverse */
    0,                          /* tp_clear */
    0,                          /* tp_richcompare */
    0,                          /* tp_weaklistoffset */
    0,                          /* tp_iter */
    0,                          /* tp_iternext */
    0,                          /* tp_methods */
    0,                          /* tp_members */
    0,                          /* tp_getset */
    0,                          /* tp_base */
    0,                          /* tp_dict */
    0,                          /* tp_descr_get */
    0,                          /* tp_descr_set */
    0,                          /* tp_dictoffset */
    (initproc)comerror_init,    /* tp_init */
    0,                          /* tp_alloc */
    0,                          /* tp_new */
};


static int
create_comerror(void)
{
    PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
    if (PyType_Ready(&PyComError_Type) < 0)
        return -1;
    Py_INCREF(&PyComError_Type);
    ComError = (PyObject*)&PyComError_Type;
    return 0;
}

#endif

static PyObject *
string_at(const char *ptr, int size)
{
    if (size == -1)
        return PyBytes_FromStringAndSize(ptr, strlen(ptr));
    return PyBytes_FromStringAndSize(ptr, size);
}

static int
cast_check_pointertype(PyObject *arg)
{
    StgDictObject *dict;

    if (PyCPointerTypeObject_Check(arg))
        return 1;
    if (PyCFuncPtrTypeObject_Check(arg))
        return 1;
    dict = PyType_stgdict(arg);
    if (dict) {
        if (PyUnicode_Check(dict->proto)
            && (strchr("sPzUZXO", _PyUnicode_AsString(dict->proto)[0]))) {
            /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
            return 1;
        }
    }
    PyErr_Format(PyExc_TypeError,
                 "cast() argument 2 must be a pointer type, not %s",
                 PyType_Check(arg)
                 ? ((PyTypeObject *)arg)->tp_name
                 : Py_TYPE(arg)->tp_name);
    return 0;
}

static PyObject *
cast(void *ptr, PyObject *src, PyObject *ctype)
{
    CDataObject *result;
    if (0 == cast_check_pointertype(ctype))
        return NULL;
    result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
    if (result == NULL)
        return NULL;

    /*
      The casted objects '_objects' member:

      It must certainly contain the source objects one.
      It must contain the source object itself.
     */
    if (CDataObject_Check(src)) {
        CDataObject *obj = (CDataObject *)src;
        /* PyCData_GetContainer will initialize src.b_objects, we need
           this so it can be shared */
        PyCData_GetContainer(obj);
        /* But we need a dictionary! */
        if (obj->b_objects == Py_None) {
            Py_DECREF(Py_None);
            obj->b_objects = PyDict_New();
            if (obj->b_objects == NULL)
                goto failed;
        }
        Py_XINCREF(obj->b_objects);
        result->b_objects = obj->b_objects;
        if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
            PyObject *index;
            int rc;
            index = PyLong_FromVoidPtr((void *)src);
            if (index == NULL)
                goto failed;
            rc = PyDict_SetItem(result->b_objects, index, src);
            Py_DECREF(index);
            if (rc == -1)
                goto failed;
        }
    }
    /* Should we assert that result is a pointer type? */
    memcpy(result->b_ptr, &ptr, sizeof(void *));
    return (PyObject *)result;

  failed:
    Py_DECREF(result);
    return NULL;
}

#ifdef CTYPES_UNICODE
static PyObject *
wstring_at(const wchar_t *ptr, int size)
{
    Py_ssize_t ssize = size;
    if (ssize == -1)
        ssize = wcslen(ptr);
    return PyUnicode_FromWideChar(ptr, ssize);
}
#endif


static struct PyModuleDef _ctypesmodule = {
    PyModuleDef_HEAD_INIT,
    "_ctypes",
    module_docs,
    -1,
    _ctypes_module_methods,
    NULL,
    NULL,
    NULL,
    NULL
};

PyMODINIT_FUNC
PyInit__ctypes(void)
{
    PyObject *m;

/* Note:
   ob_type is the metatype (the 'type'), defaults to PyType_Type,
   tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
*/
#ifdef WITH_THREAD
    PyEval_InitThreads();
#endif
    m = PyModule_Create(&_ctypesmodule);
    if (!m)
        return NULL;

    _ctypes_ptrtype_cache = PyDict_New();
    if (_ctypes_ptrtype_cache == NULL)
        return NULL;

    PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache);

    _unpickle = PyObject_GetAttrString(m, "_unpickle");
    if (_unpickle == NULL)
        return NULL;

    if (PyType_Ready(&PyCArg_Type) < 0)
        return NULL;

    if (PyType_Ready(&PyCThunk_Type) < 0)
        return NULL;

    /* StgDict is derived from PyDict_Type */
    PyCStgDict_Type.tp_base = &PyDict_Type;
    if (PyType_Ready(&PyCStgDict_Type) < 0)
        return NULL;

    /*************************************************
     *
     * Metaclasses
     */

    PyCStructType_Type.tp_base = &PyType_Type;
    if (PyType_Ready(&PyCStructType_Type) < 0)
        return NULL;

    UnionType_Type.tp_base = &PyType_Type;
    if (PyType_Ready(&UnionType_Type) < 0)
        return NULL;

    PyCPointerType_Type.tp_base = &PyType_Type;
    if (PyType_Ready(&PyCPointerType_Type) < 0)
        return NULL;

    PyCArrayType_Type.tp_base = &PyType_Type;
    if (PyType_Ready(&PyCArrayType_Type) < 0)
        return NULL;

    PyCSimpleType_Type.tp_base = &PyType_Type;
    if (PyType_Ready(&PyCSimpleType_Type) < 0)
        return NULL;

    PyCFuncPtrType_Type.tp_base = &PyType_Type;
    if (PyType_Ready(&PyCFuncPtrType_Type) < 0)
        return NULL;

    /*************************************************
     *
     * Classes using a custom metaclass
     */

    if (PyType_Ready(&PyCData_Type) < 0)
        return NULL;

    Py_TYPE(&Struct_Type) = &PyCStructType_Type;
    Struct_Type.tp_base = &PyCData_Type;
    if (PyType_Ready(&Struct_Type) < 0)
        return NULL;
    Py_INCREF(&Struct_Type);
    PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);

    Py_TYPE(&Union_Type) = &UnionType_Type;
    Union_Type.tp_base = &PyCData_Type;
    if (PyType_Ready(&Union_Type) < 0)
        return NULL;
    Py_INCREF(&Union_Type);
    PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);

    Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
    PyCPointer_Type.tp_base = &PyCData_Type;
    if (PyType_Ready(&PyCPointer_Type) < 0)
        return NULL;
    Py_INCREF(&PyCPointer_Type);
    PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);

    Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
    PyCArray_Type.tp_base = &PyCData_Type;
    if (PyType_Ready(&PyCArray_Type) < 0)
        return NULL;
    Py_INCREF(&PyCArray_Type);
    PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);

    Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
    Simple_Type.tp_base = &PyCData_Type;
    if (PyType_Ready(&Simple_Type) < 0)
        return NULL;
    Py_INCREF(&Simple_Type);
    PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);

    Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
    PyCFuncPtr_Type.tp_base = &PyCData_Type;
    if (PyType_Ready(&PyCFuncPtr_Type) < 0)
        return NULL;
    Py_INCREF(&PyCFuncPtr_Type);
    PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);

    /*************************************************
     *
     * Simple classes
     */

    /* PyCField_Type is derived from PyBaseObject_Type */
    if (PyType_Ready(&PyCField_Type) < 0)
        return NULL;

    /*************************************************
     *
     * Other stuff
     */

    DictRemover_Type.tp_new = PyType_GenericNew;
    if (PyType_Ready(&DictRemover_Type) < 0)
        return NULL;

#ifdef MS_WIN32
    if (create_comerror() < 0)
        return NULL;
    PyModule_AddObject(m, "COMError", ComError);

    PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
    PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
#endif
    PyModule_AddObject(m, "FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
    PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
    PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
    PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
    PyModule_AddStringConstant(m, "__version__", "1.1.0");

    PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
    PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
    PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
    PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
#ifdef CTYPES_UNICODE
    PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
#endif

/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
#ifndef RTLD_LOCAL
#define RTLD_LOCAL 0
#endif

/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
   RTLD_LOCAL.
*/
#ifndef RTLD_GLOBAL
#define RTLD_GLOBAL RTLD_LOCAL
#endif

    PyModule_AddObject(m, "RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
    PyModule_AddObject(m, "RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));

    PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
    if (PyExc_ArgError) {
        Py_INCREF(PyExc_ArgError);
        PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
    }
    return m;
}

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