[ctypes-commit] ctypes/source callproc.c,1.120,1.121
Brought to you by:
theller
From: Thomas H. <th...@us...> - 2004-12-02 19:53:40
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15667 Modified Files: callproc.c Log Message: Structures as function return types work now, except for small ones returned in registers by MSVC. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.120 retrieving revision 1.121 diff -C2 -d -r1.120 -r1.121 *** callproc.c 2 Dec 2004 19:12:28 -0000 1.120 --- callproc.c 2 Dec 2004 19:53:21 -0000 1.121 *************** *** 703,707 **** * Convert the C value in result into an instance described by restype */ ! static PyObject *GetResult(PyObject *restype, ffi_type *ffi_type, void *result) { StgDictObject *dict; --- 703,707 ---- * Convert the C value in result into an instance described by restype */ ! static PyObject *GetResult(PyObject *restype, void *result) { StgDictObject *dict; *************** *** 735,738 **** --- 735,755 ---- } + if (StructTypeObject_Check(restype)) { + CDataObject *pd; + + pd = (CDataObject *)PyObject_CallFunctionObjArgs(restype, NULL); + if (!pd) + return NULL; + if (!CDataObject_Check(pd)) { + Py_DECREF(pd); + PyErr_SetString(PyExc_TypeError, + "BUG: restype call did not return a CDataObject"); + return NULL; + } + /* Even better would be to use the buffer interface */ + memcpy(pd->b_ptr, result, pd->b_size); + return (PyObject *)pd; + } + dict = PyType_stgdict(restype); if (dict && dict->getfunc) { *************** *** 848,854 **** { int i, n, argcount, argtype_count; ! struct argument result; struct argument *args, *pa; ffi_type **atypes; void **avalues; PyObject *retval = NULL; --- 865,872 ---- { int i, n, argcount, argtype_count; ! void *resbuf; struct argument *args, *pa; ffi_type **atypes; + ffi_type *rtype; void **avalues; PyObject *retval = NULL; *************** *** 907,917 **** } ! /* XXX If we have a structure as return value, the storage area that ! 'result.value' provides may not be large enough. We should ! probably create the result value (an instance of the structure ! type) before the call, and use the instance's memory buffer as the ! storage area. ! */ ! result.ffi_type = GetType(restype); avalues = (void **)alloca(sizeof(void *) * argcount); --- 925,930 ---- } ! rtype = GetType(restype); ! resbuf = alloca(max(rtype->size, sizeof(ffi_arg))); avalues = (void **)alloca(sizeof(void *) * argcount); *************** *** 926,941 **** if (-1 == _call_function_pointer(flags, pProc, avalues, atypes, ! result.ffi_type, &result.value, argcount)) goto cleanup; #ifdef MS_WIN32 if (flags & FUNCFLAG_HRESULT) { ! if (result.value.i & 0x80000000) ! retval = PyErr_SetFromWindowsErr(result.value.i); else ! retval = PyInt_FromLong(result.value.i); } else #endif ! retval = GetResult(restype, result.ffi_type, &result.value); cleanup: for (i = 0; i < argcount; ++i) --- 939,954 ---- if (-1 == _call_function_pointer(flags, pProc, avalues, atypes, ! rtype, resbuf, argcount)) goto cleanup; #ifdef MS_WIN32 if (flags & FUNCFLAG_HRESULT) { ! if (*(int *)resbuf & 0x80000000) ! retval = PyErr_SetFromWindowsErr(*(int *)resbuf); else ! retval = PyInt_FromLong(*(int *)resbuf); } else #endif ! retval = GetResult(restype, resbuf); cleanup: for (i = 0; i < argcount; ++i) |