Back to index

python3.2  3.2.2
Classes | Defines | Functions | Variables
callproc.c File Reference
#include "Python.h"
#include "structmember.h"
#include "ctypes_dlfcn.h"
#include <ffi.h>
#include "ctypes.h"

Go to the source code of this file.

Classes

union  result
struct  argument

Defines

#define CTYPES_CAPSULE_NAME_PYMEM   "_ctypes pymem"

Functions

static void pymem_destructor (PyObject *ptr)
PyObject_ctypes_get_errobj (int **pspace)
static PyObjectget_error_internal (PyObject *self, PyObject *args, int index)
static PyObjectset_error_internal (PyObject *self, PyObject *args, int index)
static PyObjectget_errno (PyObject *self, PyObject *args)
static PyObjectset_errno (PyObject *self, PyObject *args)
PyCArgObject * PyCArgObject_new (void)
static void PyCArg_dealloc (PyCArgObject *self)
static PyObjectPyCArg_repr (PyCArgObject *self)
static int ConvParam (PyObject *obj, Py_ssize_t index, struct argument *pa)
ffi_type_ctypes_get_ffi_type (PyObject *obj)
static int _call_function_pointer (int flags, PPROC pProc, void **avalues, ffi_type **atypes, ffi_type *restype, void *resmem, int argcount)
static PyObjectGetResult (PyObject *restype, void *result, PyObject *checker)
void _ctypes_extend_error (PyObject *exc_class, char *fmt,...)
PyObject_ctypes_callproc (PPROC pProc, PyObject *argtuple, int flags, PyObject *argtypes, PyObject *restype, PyObject *checker)
static int _parse_voidp (PyObject *obj, void **address)
static PyObjectpy_dl_open (PyObject *self, PyObject *args)
static PyObjectpy_dl_close (PyObject *self, PyObject *args)
static PyObjectpy_dl_sym (PyObject *self, PyObject *args)
static PyObjectcall_function (PyObject *self, PyObject *args)
static PyObjectcall_cdeclfunction (PyObject *self, PyObject *args)
static PyObjectsizeof_func (PyObject *self, PyObject *obj)
static PyObjectalign_func (PyObject *self, PyObject *obj)
static PyObjectbyref (PyObject *self, PyObject *args)
static PyObjectaddressof (PyObject *self, PyObject *obj)
static int converter (PyObject *obj, void **address)
static PyObjectMy_PyObj_FromPtr (PyObject *self, PyObject *args)
static PyObjectMy_Py_INCREF (PyObject *self, PyObject *arg)
static PyObjectMy_Py_DECREF (PyObject *self, PyObject *arg)
static PyObjectresize (PyObject *self, PyObject *args)
static PyObjectunpickle (PyObject *self, PyObject *args)
static PyObjectPOINTER (PyObject *self, PyObject *cls)
static PyObjectpointer (PyObject *self, PyObject *arg)
static PyObjectbuffer_info (PyObject *self, PyObject *arg)

Variables

static PyMemberDef PyCArgType_members []
PyTypeObject PyCArg_Type
static char sizeof_doc [] = "Return the size in bytes of a C instance"
static char alignment_doc [] = "Return the alignment requirements of a C instance"
static char byref_doc [] = "as function argument"
static char addressof_doc [] = "Return the address of the C instance internal buffer"
PyMethodDef _ctypes_module_methods []

Class Documentation

union result

Definition at line 579 of file callproc.c.

Class Members
char b
char c
long double D
double d
float f
short h
int i
long l
void * p

Define Documentation

#define CTYPES_CAPSULE_NAME_PYMEM   "_ctypes pymem"

Definition at line 81 of file callproc.c.


Function Documentation

static int _call_function_pointer ( int  flags,
PPROC  pProc,
void **  avalues,
ffi_type **  atypes,
ffi_type restype,
void resmem,
int  argcount 
) [static]

Definition at line 739 of file callproc.c.

{
#ifdef WITH_THREAD
    PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
#endif
    PyObject *error_object = NULL;
    int *space;
    ffi_cif cif;
    int cc;
#ifdef MS_WIN32
    int delta;
#ifndef DONT_USE_SEH
    DWORD dwExceptionCode = 0;
    EXCEPTION_RECORD record;
#endif
#endif
    /* XXX check before here */
    if (restype == NULL) {
        PyErr_SetString(PyExc_RuntimeError,
                        "No ffi_type for result");
        return -1;
    }

    cc = FFI_DEFAULT_ABI;
#if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE)
    if ((flags & FUNCFLAG_CDECL) == 0)
        cc = FFI_STDCALL;
#endif
    if (FFI_OK != ffi_prep_cif(&cif,
                               cc,
                               argcount,
                               restype,
                               atypes)) {
        PyErr_SetString(PyExc_RuntimeError,
                        "ffi_prep_cif failed");
        return -1;
    }

    if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
        error_object = _ctypes_get_errobj(&space);
        if (error_object == NULL)
            return -1;
    }
#ifdef WITH_THREAD
    if ((flags & FUNCFLAG_PYTHONAPI) == 0)
        Py_UNBLOCK_THREADS
#endif
    if (flags & FUNCFLAG_USE_ERRNO) {
        int temp = space[0];
        space[0] = errno;
        errno = temp;
    }
#ifdef MS_WIN32
    if (flags & FUNCFLAG_USE_LASTERROR) {
        int temp = space[1];
        space[1] = GetLastError();
        SetLastError(temp);
    }
#ifndef DONT_USE_SEH
    __try {
#endif
        delta =
#endif
                ffi_call(&cif, (void *)pProc, resmem, avalues);
#ifdef MS_WIN32
#ifndef DONT_USE_SEH
    }
    __except (HandleException(GetExceptionInformation(),
                              &dwExceptionCode, &record)) {
        ;
    }
#endif
    if (flags & FUNCFLAG_USE_LASTERROR) {
        int temp = space[1];
        space[1] = GetLastError();
        SetLastError(temp);
    }
#endif
    if (flags & FUNCFLAG_USE_ERRNO) {
        int temp = space[0];
        space[0] = errno;
        errno = temp;
    }
    Py_XDECREF(error_object);
#ifdef WITH_THREAD
    if ((flags & FUNCFLAG_PYTHONAPI) == 0)
        Py_BLOCK_THREADS
#endif
#ifdef MS_WIN32
#ifndef DONT_USE_SEH
    if (dwExceptionCode) {
        SetException(dwExceptionCode, &record);
        return -1;
    }
#endif
#ifdef MS_WIN64
    if (delta != 0) {
        PyErr_Format(PyExc_RuntimeError,
                 "ffi_call failed with code %d",
                 delta);
        return -1;
    }
#else
    if (delta < 0) {
        if (flags & FUNCFLAG_CDECL)
            PyErr_Format(PyExc_ValueError,
                     "Procedure called with not enough "
                     "arguments (%d bytes missing) "
                     "or wrong calling convention",
                     -delta);
        else
            PyErr_Format(PyExc_ValueError,
                     "Procedure probably called with not enough "
                     "arguments (%d bytes missing)",
                     -delta);
        return -1;
    } else if (delta > 0) {
        PyErr_Format(PyExc_ValueError,
                 "Procedure probably called with too many "
                 "arguments (%d bytes in excess)",
                 delta);
        return -1;
    }
#endif
#endif
    if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
        return -1;
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PyObject* _ctypes_callproc ( PPROC  pProc,
PyObject argtuple,
int  flags,
PyObject argtypes,
PyObject restype,
PyObject checker 
)

Definition at line 1049 of file callproc.c.

{
    Py_ssize_t i, n, argcount, argtype_count;
    void *resbuf;
    struct argument *args, *pa;
    ffi_type **atypes;
    ffi_type *rtype;
    void **avalues;
    PyObject *retval = NULL;

    n = argcount = PyTuple_GET_SIZE(argtuple);
#ifdef MS_WIN32
    /* an optional COM object this pointer */
    if (pIunk)
        ++argcount;
#endif

    args = (struct argument *)alloca(sizeof(struct argument) * argcount);
    if (!args) {
        PyErr_NoMemory();
        return NULL;
    }
    memset(args, 0, sizeof(struct argument) * argcount);
    argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0;
#ifdef MS_WIN32
    if (pIunk) {
        args[0].ffi_type = &ffi_type_pointer;
        args[0].value.p = pIunk;
        pa = &args[1];
    } else
#endif
        pa = &args[0];

    /* Convert the arguments */
    for (i = 0; i < n; ++i, ++pa) {
        PyObject *converter;
        PyObject *arg;
        int err;

        arg = PyTuple_GET_ITEM(argtuple, i);            /* borrowed ref */
        /* For cdecl functions, we allow more actual arguments
           than the length of the argtypes tuple.
           This is checked in _ctypes::PyCFuncPtr_Call
        */
        if (argtypes && argtype_count > i) {
            PyObject *v;
            converter = PyTuple_GET_ITEM(argtypes, i);
            v = PyObject_CallFunctionObjArgs(converter,
                                               arg,
                                               NULL);
            if (v == NULL) {
                _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1);
                goto cleanup;
            }

            err = ConvParam(v, i+1, pa);
            Py_DECREF(v);
            if (-1 == err) {
                _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1);
                goto cleanup;
            }
        } else {
            err = ConvParam(arg, i+1, pa);
            if (-1 == err) {
                _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1);
                goto cleanup; /* leaking ? */
            }
        }
    }

    rtype = _ctypes_get_ffi_type(restype);
    resbuf = alloca(max(rtype->size, sizeof(ffi_arg)));

    avalues = (void **)alloca(sizeof(void *) * argcount);
    atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount);
    if (!resbuf || !avalues || !atypes) {
        PyErr_NoMemory();
        goto cleanup;
    }
    for (i = 0; i < argcount; ++i) {
        atypes[i] = args[i].ffi_type;
        if (atypes[i]->type == FFI_TYPE_STRUCT
#ifdef _WIN64
            && atypes[i]->size <= sizeof(void *)
#endif
            )
            avalues[i] = (void *)args[i].value.p;
        else
            avalues[i] = (void *)&args[i].value;
    }

    if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
                                     rtype, resbuf,
                                     Py_SAFE_DOWNCAST(argcount,
                                                      Py_ssize_t,
                                                      int)))
        goto cleanup;

#ifdef WORDS_BIGENDIAN
    /* libffi returns the result in a buffer with sizeof(ffi_arg). This
       causes problems on big endian machines, since the result buffer
       address cannot simply be used as result pointer, instead we must
       adjust the pointer value:
     */
    /*
      XXX I should find out and clarify why this is needed at all,
      especially why adjusting for ffi_type_float must be avoided on
      64-bit platforms.
     */
    if (rtype->type != FFI_TYPE_FLOAT
        && rtype->type != FFI_TYPE_STRUCT
        && rtype->size < sizeof(ffi_arg))
        resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size;
#endif

#ifdef MS_WIN32
    if (iid && pIunk) {
        if (*(int *)resbuf & 0x80000000)
            retval = GetComError(*(HRESULT *)resbuf, iid, pIunk);
        else
            retval = PyLong_FromLong(*(int *)resbuf);
    } else if (flags & FUNCFLAG_HRESULT) {
        if (*(int *)resbuf & 0x80000000)
            retval = PyErr_SetFromWindowsErr(*(int *)resbuf);
        else
            retval = PyLong_FromLong(*(int *)resbuf);
    } else
#endif
        retval = GetResult(restype, resbuf, checker);
  cleanup:
    for (i = 0; i < argcount; ++i)
        Py_XDECREF(args[i].keep);
    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _ctypes_extend_error ( PyObject exc_class,
char *  fmt,
  ... 
)

Definition at line 928 of file callproc.c.

{
    va_list vargs;
    PyObject *tp, *v, *tb, *s, *cls_str, *msg_str;

    va_start(vargs, fmt);
    s = PyUnicode_FromFormatV(fmt, vargs);
    va_end(vargs);
    if (!s)
        return;

    PyErr_Fetch(&tp, &v, &tb);
    PyErr_NormalizeException(&tp, &v, &tb);
    cls_str = PyObject_Str(tp);
    if (cls_str) {
        PyUnicode_AppendAndDel(&s, cls_str);
        PyUnicode_AppendAndDel(&s, PyUnicode_FromString(": "));
        if (s == NULL)
            goto error;
    } else
        PyErr_Clear();
    msg_str = PyObject_Str(v);
    if (msg_str)
        PyUnicode_AppendAndDel(&s, msg_str);
    else {
        PyErr_Clear();
        PyUnicode_AppendAndDel(&s, PyUnicode_FromString("???"));
        if (s == NULL)
            goto error;
    }
    PyErr_SetObject(exc_class, s);
error:
    Py_XDECREF(tp);
    Py_XDECREF(v);
    Py_XDECREF(tb);
    Py_XDECREF(s);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PyObject* _ctypes_get_errobj ( int **  pspace)

Definition at line 126 of file callproc.c.

{
    PyObject *dict = PyThreadState_GetDict();
    PyObject *errobj;
    static PyObject *error_object_name;
    if (dict == 0) {
        PyErr_SetString(PyExc_RuntimeError,
                        "cannot get thread state");
        return NULL;
    }
    if (error_object_name == NULL) {
        error_object_name = PyUnicode_InternFromString("ctypes.error_object");
        if (error_object_name == NULL)
            return NULL;
    }
    errobj = PyDict_GetItem(dict, error_object_name);
    if (errobj) {
        if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) {
            PyErr_SetString(PyExc_RuntimeError,
                "ctypes.error_object is an invalid capsule");
            return NULL;
        }
        Py_INCREF(errobj);
    }
    else {
        void *space = PyMem_Malloc(sizeof(int) * 2);
        if (space == NULL)
            return NULL;
        memset(space, 0, sizeof(int) * 2);
        errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
        if (errobj == NULL)
            return NULL;
        if (-1 == PyDict_SetItem(dict, error_object_name,
                                 errobj)) {
            Py_DECREF(errobj);
            return NULL;
        }
    }
    *pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM);
    return errobj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 704 of file callproc.c.

{
    StgDictObject *dict;
    if (obj == NULL)
        return &ffi_type_sint;
    dict = PyType_stgdict(obj);
    if (dict == NULL)
        return &ffi_type_sint;
#if defined(MS_WIN32) && !defined(_WIN32_WCE)
    /* This little trick works correctly with MSVC.
       It returns small structures in registers
    */
    if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) {
        if (dict->ffi_type_pointer.size <= 4)
            return &ffi_type_sint32;
        else if (dict->ffi_type_pointer.size <= 8)
            return &ffi_type_sint64;
    }
#endif
    return &dict->ffi_type_pointer;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int _parse_voidp ( PyObject obj,
void **  address 
) [static]

Definition at line 1196 of file callproc.c.

{
    *address = PyLong_AsVoidPtr(obj);
    if (*address == NULL)
        return 0;
    return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* addressof ( PyObject self,
PyObject obj 
) [static]

Definition at line 1593 of file callproc.c.

{
    if (CDataObject_Check(obj))
        return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr);
    PyErr_SetString(PyExc_TypeError,
                    "invalid type");
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* align_func ( PyObject self,
PyObject obj 
) [static]

Definition at line 1527 of file callproc.c.

{
    StgDictObject *dict;

    dict = PyType_stgdict(obj);
    if (dict)
        return PyLong_FromSsize_t(dict->align);

    dict = PyObject_stgdict(obj);
    if (dict)
        return PyLong_FromSsize_t(dict->align);

    PyErr_SetString(PyExc_TypeError,
                    "no alignment info");
    return NULL;
}

Here is the call graph for this function:

static PyObject* buffer_info ( PyObject self,
PyObject arg 
) [static]

Definition at line 1781 of file callproc.c.

{
    StgDictObject *dict = PyType_stgdict(arg);
    PyObject *shape;
    Py_ssize_t i;

    if (dict == NULL)
        dict = PyObject_stgdict(arg);
    if (dict == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "not a ctypes type or object");
        return NULL;
    }
    shape = PyTuple_New(dict->ndim);
    if (shape == NULL)
        return NULL;
    for (i = 0; i < (int)dict->ndim; ++i)
        PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i]));

    if (PyErr_Occurred()) {
        Py_DECREF(shape);
        return NULL;
    }
    return Py_BuildValue("siN", dict->format, dict->ndim, shape);
}

Here is the call graph for this function:

static PyObject* byref ( PyObject self,
PyObject args 
) [static]

Definition at line 1554 of file callproc.c.

{
    PyCArgObject *parg;
    PyObject *obj;
    PyObject *pyoffset = NULL;
    Py_ssize_t offset = 0;

    if (!PyArg_UnpackTuple(args, "byref", 1, 2,
                           &obj, &pyoffset))
        return NULL;
    if (pyoffset) {
        offset = PyNumber_AsSsize_t(pyoffset, NULL);
        if (offset == -1 && PyErr_Occurred())
            return NULL;
    }
    if (!CDataObject_Check(obj)) {
        PyErr_Format(PyExc_TypeError,
                     "byref() argument must be a ctypes instance, not '%s'",
                     Py_TYPE(obj)->tp_name);
        return NULL;
    }

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

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

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* call_cdeclfunction ( PyObject self,
PyObject args 
) [static]

Definition at line 1472 of file callproc.c.

{
    void *func;
    PyObject *arguments;
    PyObject *result;

    if (!PyArg_ParseTuple(args,
                          "O&O!",
                          &_parse_voidp, &func,
                          &PyTuple_Type, &arguments))
        return NULL;

    result =  _ctypes_callproc((PPROC)func,
                        arguments,
#ifdef MS_WIN32
                        NULL,
                        NULL,
#endif
                        FUNCFLAG_CDECL, /* flags */
                NULL, /* self->argtypes */
                NULL, /* self->restype */
                NULL); /* checker */
    return result;
}

Here is the call graph for this function:

static PyObject* call_function ( PyObject self,
PyObject args 
) [static]

Definition at line 1441 of file callproc.c.

{
    void *func;
    PyObject *arguments;
    PyObject *result;

    if (!PyArg_ParseTuple(args,
                          "O&O!",
                          &_parse_voidp, &func,
                          &PyTuple_Type, &arguments))
        return NULL;

    result =  _ctypes_callproc((PPROC)func,
                        arguments,
#ifdef MS_WIN32
                        NULL,
                        NULL,
#endif
                        0, /* flags */
                NULL, /* self->argtypes */
                NULL, /* self->restype */
                NULL); /* checker */
    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int converter ( PyObject obj,
void **  address 
) [static]

Definition at line 1603 of file callproc.c.

{
    *address = PyLong_AsVoidPtr(obj);
    return *address != NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ConvParam ( PyObject obj,
Py_ssize_t  index,
struct argument pa 
) [static]

Definition at line 603 of file callproc.c.

{
    StgDictObject *dict;
    pa->keep = NULL; /* so we cannot forget it later */

    dict = PyObject_stgdict(obj);
    if (dict) {
        PyCArgObject *carg;
        assert(dict->paramfunc);
        /* If it has an stgdict, it is a CDataObject */
        carg = dict->paramfunc((CDataObject *)obj);
        pa->ffi_type = carg->pffi_type;
        memcpy(&pa->value, &carg->value, sizeof(pa->value));
        pa->keep = (PyObject *)carg;
        return 0;
    }

    if (PyCArg_CheckExact(obj)) {
        PyCArgObject *carg = (PyCArgObject *)obj;
        pa->ffi_type = carg->pffi_type;
        Py_INCREF(obj);
        pa->keep = obj;
        memcpy(&pa->value, &carg->value, sizeof(pa->value));
        return 0;
    }

    /* check for None, integer, string or unicode and use directly if successful */
    if (obj == Py_None) {
        pa->ffi_type = &ffi_type_pointer;
        pa->value.p = NULL;
        return 0;
    }

    if (PyLong_Check(obj)) {
        pa->ffi_type = &ffi_type_sint;
        pa->value.i = (long)PyLong_AsUnsignedLong(obj);
        if (pa->value.i == -1 && PyErr_Occurred()) {
            PyErr_Clear();
            pa->value.i = PyLong_AsLong(obj);
            if (pa->value.i == -1 && PyErr_Occurred()) {
                PyErr_SetString(PyExc_OverflowError,
                                "long int too long to convert");
                return -1;
            }
        }
        return 0;
    }

    if (PyBytes_Check(obj)) {
        pa->ffi_type = &ffi_type_pointer;
        pa->value.p = PyBytes_AsString(obj);
        Py_INCREF(obj);
        pa->keep = obj;
        return 0;
    }

#ifdef CTYPES_UNICODE
    if (PyUnicode_Check(obj)) {
#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T
        pa->ffi_type = &ffi_type_pointer;
        pa->value.p = PyUnicode_AS_UNICODE(obj);
        Py_INCREF(obj);
        pa->keep = obj;
        return 0;
#else
        pa->ffi_type = &ffi_type_pointer;
        pa->value.p = PyUnicode_AsWideCharString(obj, NULL);
        if (pa->value.p == NULL)
            return -1;
        pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
        if (!pa->keep) {
            PyMem_Free(pa->value.p);
            return -1;
        }
        return 0;
#endif
    }
#endif

    {
        PyObject *arg;
        arg = PyObject_GetAttrString(obj, "_as_parameter_");
        /* Which types should we exactly allow here?
           integers are required for using Python classes
           as parameters (they have to expose the '_as_parameter_'
           attribute)
        */
        if (arg) {
            int result;
            result = ConvParam(arg, index, pa);
            Py_DECREF(arg);
            return result;
        }
        PyErr_Format(PyExc_TypeError,
                     "Don't know how to convert parameter %d",
                     Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
        return -1;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* get_errno ( PyObject self,
PyObject args 
) [static]

Definition at line 201 of file callproc.c.

{
    return get_error_internal(self, args, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* get_error_internal ( PyObject self,
PyObject args,
int  index 
) [static]

Definition at line 169 of file callproc.c.

{
    int *space;
    PyObject *errobj = _ctypes_get_errobj(&space);
    PyObject *result;

    if (errobj == NULL)
        return NULL;
    result = PyLong_FromLong(space[index]);
    Py_DECREF(errobj);
    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* GetResult ( PyObject restype,
void result,
PyObject checker 
) [static]

Definition at line 885 of file callproc.c.

{
    StgDictObject *dict;
    PyObject *retval, *v;

    if (restype == NULL)
        return PyLong_FromLong(*(int *)result);

    if (restype == Py_None) {
        Py_INCREF(Py_None);
        return Py_None;
    }

    dict = PyType_stgdict(restype);
    if (dict == NULL)
        return PyObject_CallFunction(restype, "i", *(int *)result);

    if (dict->getfunc && !_ctypes_simple_instance(restype)) {
        retval = dict->getfunc(result, dict->size);
        /* If restype is py_object (detected by comparing getfunc with
           O_get), we have to call Py_DECREF because O_get has already
           called Py_INCREF.
        */
        if (dict->getfunc == _ctypes_get_fielddesc("O")->getfunc) {
            Py_DECREF(retval);
        }
    } else
        retval = PyCData_FromBaseObj(restype, NULL, 0, result);

    if (!checker || !retval)
        return retval;

    v = PyObject_CallFunctionObjArgs(checker, retval, NULL);
    if (v == NULL)
        _ctypes_add_traceback("GetResult", "_ctypes/callproc.c", __LINE__-2);
    Py_DECREF(retval);
    return v;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* My_Py_DECREF ( PyObject self,
PyObject arg 
) [static]

Definition at line 1628 of file callproc.c.

{
    Py_DECREF(arg); /* that's what this function is for */
    Py_INCREF(arg); /* that's for returning it */
    return arg;
}
static PyObject* My_Py_INCREF ( PyObject self,
PyObject arg 
) [static]

Definition at line 1620 of file callproc.c.

{
    Py_INCREF(arg); /* that's what this function is for */
    Py_INCREF(arg); /* that for returning it */
    return arg;
}
static PyObject* My_PyObj_FromPtr ( PyObject self,
PyObject args 
) [static]

Definition at line 1610 of file callproc.c.

{
    PyObject *ob;
    if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob))
        return NULL;
    Py_INCREF(ob);
    return ob;
}

Here is the call graph for this function:

static PyObject* POINTER ( PyObject self,
PyObject cls 
) [static]

Definition at line 1714 of file callproc.c.

{
    PyObject *result;
    PyTypeObject *typ;
    PyObject *key;
    char *buf;

    result = PyDict_GetItem(_ctypes_ptrtype_cache, cls);
    if (result) {
        Py_INCREF(result);
        return result;
    }
    if (PyUnicode_CheckExact(cls)) {
        char *name = _PyUnicode_AsString(cls);
        buf = alloca(strlen(name) + 3 + 1);
        sprintf(buf, "LP_%s", name);
        result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
                                       "s(O){}",
                                       buf,
                                       &PyCPointer_Type);
        if (result == NULL)
            return result;
        key = PyLong_FromVoidPtr(result);
    } else if (PyType_Check(cls)) {
        typ = (PyTypeObject *)cls;
        buf = alloca(strlen(typ->tp_name) + 3 + 1);
        sprintf(buf, "LP_%s", typ->tp_name);
        result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
                                       "s(O){sO}",
                                       buf,
                                       &PyCPointer_Type,
                                       "_type_", cls);
        if (result == NULL)
            return result;
        Py_INCREF(cls);
        key = cls;
    } else {
        PyErr_SetString(PyExc_TypeError, "must be a ctypes type");
        return NULL;
    }
    if (-1 == PyDict_SetItem(_ctypes_ptrtype_cache, key, result)) {
        Py_DECREF(result);
        Py_DECREF(key);
        return NULL;
    }
    Py_DECREF(key);
    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* pointer ( PyObject self,
PyObject arg 
) [static]

Definition at line 1764 of file callproc.c.

{
    PyObject *result;
    PyObject *typ;

    typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg));
    if (typ)
        return PyObject_CallFunctionObjArgs(typ, arg, NULL);
    typ = POINTER(NULL, (PyObject *)Py_TYPE(arg));
    if (typ == NULL)
                    return NULL;
    result = PyObject_CallFunctionObjArgs(typ, arg, NULL);
    Py_DECREF(typ);
    return result;
}

Here is the call graph for this function:

static PyObject* py_dl_close ( PyObject self,
PyObject args 
) [static]

Definition at line 1401 of file callproc.c.

{
    void *handle;

    if (!PyArg_ParseTuple(args, "O&:dlclose", &_parse_voidp, &handle))
        return NULL;
    if (dlclose(handle)) {
        PyErr_SetString(PyExc_OSError,
                               ctypes_dlerror());
        return NULL;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

Here is the call graph for this function:

static PyObject* py_dl_open ( PyObject self,
PyObject args 
) [static]

Definition at line 1363 of file callproc.c.

{
    PyObject *name, *name2;
    char *name_str;
    void * handle;
#ifdef RTLD_LOCAL
    int mode = RTLD_NOW | RTLD_LOCAL;
#else
    /* cygwin doesn't define RTLD_LOCAL */
    int mode = RTLD_NOW;
#endif
    if (!PyArg_ParseTuple(args, "O|i:dlopen", &name, &mode))
        return NULL;
    mode |= RTLD_NOW;
    if (name != Py_None) {
        if (PyUnicode_FSConverter(name, &name2) == 0)
            return NULL;
        if (PyBytes_Check(name2))
            name_str = PyBytes_AS_STRING(name2);
        else
            name_str = PyByteArray_AS_STRING(name2);
    } else {
        name_str = NULL;
        name2 = NULL;
    }
    handle = ctypes_dlopen(name_str, mode);
    Py_XDECREF(name2);
    if (!handle) {
        char *errmsg = ctypes_dlerror();
        if (!errmsg)
            errmsg = "dlopen() error";
        PyErr_SetString(PyExc_OSError,
                               errmsg);
        return NULL;
    }
    return PyLong_FromVoidPtr(handle);
}

Here is the call graph for this function:

static PyObject* py_dl_sym ( PyObject self,
PyObject args 
) [static]

Definition at line 1416 of file callproc.c.

{
    char *name;
    void *handle;
    void *ptr;

    if (!PyArg_ParseTuple(args, "O&s:dlsym",
                          &_parse_voidp, &handle, &name))
        return NULL;
    ptr = ctypes_dlsym((void*)handle, name);
    if (!ptr) {
        PyErr_SetString(PyExc_OSError,
                               ctypes_dlerror());
        return NULL;
    }
    return PyLong_FromVoidPtr(ptr);
}

Here is the call graph for this function:

static void PyCArg_dealloc ( PyCArgObject *  self) [static]

Definition at line 434 of file callproc.c.

{
    Py_XDECREF(self->obj);
    PyObject_Del(self);
}
static PyObject* PyCArg_repr ( PyCArgObject *  self) [static]

Definition at line 441 of file callproc.c.

{
    char buffer[256];
    switch(self->tag) {
    case 'b':
    case 'B':
        sprintf(buffer, "<cparam '%c' (%d)>",
            self->tag, self->value.b);
        break;
    case 'h':
    case 'H':
        sprintf(buffer, "<cparam '%c' (%d)>",
            self->tag, self->value.h);
        break;
    case 'i':
    case 'I':
        sprintf(buffer, "<cparam '%c' (%d)>",
            self->tag, self->value.i);
        break;
    case 'l':
    case 'L':
        sprintf(buffer, "<cparam '%c' (%ld)>",
            self->tag, self->value.l);
        break;

#ifdef HAVE_LONG_LONG
    case 'q':
    case 'Q':
        sprintf(buffer,
#ifdef MS_WIN32
            "<cparam '%c' (%I64d)>",
#else
            "<cparam '%c' (%qd)>",
#endif
            self->tag, self->value.q);
        break;
#endif
    case 'd':
        sprintf(buffer, "<cparam '%c' (%f)>",
            self->tag, self->value.d);
        break;
    case 'f':
        sprintf(buffer, "<cparam '%c' (%f)>",
            self->tag, self->value.f);
        break;

    case 'c':
        sprintf(buffer, "<cparam '%c' (%c)>",
            self->tag, self->value.c);
        break;

/* Hm, are these 'z' and 'Z' codes useful at all?
   Shouldn't they be replaced by the functionality of c_string
   and c_wstring ?
*/
    case 'z':
    case 'Z':
    case 'P':
        sprintf(buffer, "<cparam '%c' (%p)>",
            self->tag, self->value.p);
        break;

    default:
        sprintf(buffer, "<cparam '%c' at %p>",
            self->tag, self);
        break;
    }
    return PyUnicode_FromString(buffer);
}

Here is the call graph for this function:

PyCArgObject* PyCArgObject_new ( void  )

Definition at line 420 of file callproc.c.

{
    PyCArgObject *p;
    p = PyObject_New(PyCArgObject, &PyCArg_Type);
    if (p == NULL)
        return NULL;
    p->pffi_type = NULL;
    p->tag = '\0';
    p->obj = NULL;
    memset(&p->value, 0, sizeof(p->value));
    return p;
}

Here is the caller graph for this function:

static void pymem_destructor ( PyObject ptr) [static]

Definition at line 83 of file callproc.c.

{
    void *p = PyCapsule_GetPointer(ptr, CTYPES_CAPSULE_NAME_PYMEM);
    if (p) {
        PyMem_Free(p);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* resize ( PyObject self,
PyObject args 
) [static]

Definition at line 1636 of file callproc.c.

{
    CDataObject *obj;
    StgDictObject *dict;
    Py_ssize_t size;

    if (!PyArg_ParseTuple(args,
                          "On:resize",
                          &obj, &size))
        return NULL;

    dict = PyObject_stgdict((PyObject *)obj);
    if (dict == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "excepted ctypes instance");
        return NULL;
    }
    if (size < dict->size) {
        PyErr_Format(PyExc_ValueError,
                     "minimum size is %zd",
                     dict->size);
        return NULL;
    }
    if (obj->b_needsfree == 0) {
        PyErr_Format(PyExc_ValueError,
                     "Memory cannot be resized because this object doesn't own it");
        return NULL;
    }
    if (size <= sizeof(obj->b_value)) {
        /* internal default buffer is large enough */
        obj->b_size = size;
        goto done;
    }
    if (obj->b_size <= sizeof(obj->b_value)) {
        /* We are currently using the objects default buffer, but it
           isn't large enough any more. */
        void *ptr = PyMem_Malloc(size);
        if (ptr == NULL)
            return PyErr_NoMemory();
        memset(ptr, 0, size);
        memmove(ptr, obj->b_ptr, obj->b_size);
        obj->b_ptr = ptr;
        obj->b_size = size;
    } else {
        void * ptr = PyMem_Realloc(obj->b_ptr, size);
        if (ptr == NULL)
            return PyErr_NoMemory();
        obj->b_ptr = ptr;
        obj->b_size = size;
    }
  done:
    Py_INCREF(Py_None);
    return Py_None;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* set_errno ( PyObject self,
PyObject args 
) [static]

Definition at line 207 of file callproc.c.

{
    return set_error_internal(self, args, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* set_error_internal ( PyObject self,
PyObject args,
int  index 
) [static]

Definition at line 183 of file callproc.c.

{
    int new_errno, old_errno;
    PyObject *errobj;
    int *space;

    if (!PyArg_ParseTuple(args, "i", &new_errno))
        return NULL;
    errobj = _ctypes_get_errobj(&space);
    if (errobj == NULL)
        return NULL;
    old_errno = space[index];
    space[index] = new_errno;
    Py_DECREF(errobj);
    return PyLong_FromLong(old_errno);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* sizeof_func ( PyObject self,
PyObject obj 
) [static]

Definition at line 1506 of file callproc.c.

{
    StgDictObject *dict;

    dict = PyType_stgdict(obj);
    if (dict)
        return PyLong_FromSsize_t(dict->size);

    if (CDataObject_Check(obj))
        return PyLong_FromSsize_t(((CDataObject *)obj)->b_size);
    PyErr_SetString(PyExc_TypeError,
                    "this type has no size");
    return NULL;
}

Here is the call graph for this function:

static PyObject* unpickle ( PyObject self,
PyObject args 
) [static]

Definition at line 1692 of file callproc.c.

{
    PyObject *typ;
    PyObject *state;
    PyObject *result;
    PyObject *tmp;

    if (!PyArg_ParseTuple(args, "OO", &typ, &state))
        return NULL;
    result = PyObject_CallMethod(typ, "__new__", "O", typ);
    if (result == NULL)
        return NULL;
    tmp = PyObject_CallMethod(result, "__setstate__", "O", state);
    if (tmp == NULL) {
        Py_DECREF(result);
        return NULL;
    }
    Py_DECREF(tmp);
    return result;
}

Here is the call graph for this function:


Variable Documentation

Definition at line 1807 of file callproc.c.

char addressof_doc[] = "Return the address of the C instance internal buffer" [static]

Definition at line 1588 of file callproc.c.

char alignment_doc[] = "Return the alignment requirements of a C instance" [static]

Definition at line 1521 of file callproc.c.

char byref_doc[] = "as function argument" [static]

Definition at line 1544 of file callproc.c.

Definition at line 518 of file callproc.c.

Initial value:
 {
    { "_obj", T_OBJECT,
      offsetof(PyCArgObject, obj), READONLY,
      "the wrapped object" },
    { NULL },
}

Definition at line 511 of file callproc.c.

char sizeof_doc[] = "Return the size in bytes of a C instance" [static]

Definition at line 1500 of file callproc.c.