diff options
Diffstat (limited to 'Modules/_ctypes/callbacks.c')
-rw-r--r-- | Modules/_ctypes/callbacks.c | 886 |
1 files changed, 443 insertions, 443 deletions
diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 5cf0441a7d..4c9c013c2d 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -12,65 +12,65 @@ static void CThunkObject_dealloc(PyObject *_self) { - CThunkObject *self = (CThunkObject *)_self; - Py_XDECREF(self->converters); - Py_XDECREF(self->callable); - Py_XDECREF(self->restype); - if (self->pcl) - _ctypes_free_closure(self->pcl); - PyObject_GC_Del(self); + CThunkObject *self = (CThunkObject *)_self; + Py_XDECREF(self->converters); + Py_XDECREF(self->callable); + Py_XDECREF(self->restype); + if (self->pcl) + _ctypes_free_closure(self->pcl); + PyObject_GC_Del(self); } static int CThunkObject_traverse(PyObject *_self, visitproc visit, void *arg) { - CThunkObject *self = (CThunkObject *)_self; - Py_VISIT(self->converters); - Py_VISIT(self->callable); - Py_VISIT(self->restype); - return 0; + CThunkObject *self = (CThunkObject *)_self; + Py_VISIT(self->converters); + Py_VISIT(self->callable); + Py_VISIT(self->restype); + return 0; } static int CThunkObject_clear(PyObject *_self) { - CThunkObject *self = (CThunkObject *)_self; - Py_CLEAR(self->converters); - Py_CLEAR(self->callable); - Py_CLEAR(self->restype); - return 0; + CThunkObject *self = (CThunkObject *)_self; + Py_CLEAR(self->converters); + Py_CLEAR(self->callable); + Py_CLEAR(self->restype); + return 0; } PyTypeObject PyCThunk_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CThunkObject", - sizeof(CThunkObject), /* tp_basicsize */ - sizeof(ffi_type), /* tp_itemsize */ - CThunkObject_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 */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "CThunkObject", /* tp_doc */ - CThunkObject_traverse, /* tp_traverse */ - CThunkObject_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ + PyVarObject_HEAD_INIT(NULL, 0) + "_ctypes.CThunkObject", + sizeof(CThunkObject), /* tp_basicsize */ + sizeof(ffi_type), /* tp_itemsize */ + CThunkObject_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 */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + "CThunkObject", /* tp_doc */ + CThunkObject_traverse, /* tp_traverse */ + CThunkObject_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ }; /**************************************************************/ @@ -78,43 +78,43 @@ PyTypeObject PyCThunk_Type = { static void PrintError(char *msg, ...) { - char buf[512]; - PyObject *f = PySys_GetObject("stderr"); - va_list marker; - - va_start(marker, msg); - vsnprintf(buf, sizeof(buf), msg, marker); - va_end(marker); - if (f != NULL && f != Py_None) - PyFile_WriteString(buf, f); - PyErr_Print(); + char buf[512]; + PyObject *f = PySys_GetObject("stderr"); + va_list marker; + + va_start(marker, msg); + vsnprintf(buf, sizeof(buf), msg, marker); + va_end(marker); + if (f != NULL && f != Py_None) + PyFile_WriteString(buf, f); + PyErr_Print(); } /* after code that pyrex generates */ void _ctypes_add_traceback(char *funcname, char *filename, int lineno) { - PyObject *py_globals = 0; - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - - py_globals = PyDict_New(); - if (!py_globals) goto bad; - py_code = PyCode_NewEmpty(filename, funcname, lineno); - if (!py_code) goto bad; - py_frame = PyFrame_New( - PyThreadState_Get(), /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - py_globals, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - py_frame->f_lineno = lineno; - PyTraceBack_Here(py_frame); + PyObject *py_globals = 0; + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + + py_globals = PyDict_New(); + if (!py_globals) goto bad; + py_code = PyCode_NewEmpty(filename, funcname, lineno); + if (!py_code) goto bad; + py_frame = PyFrame_New( + PyThreadState_Get(), /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + py_globals, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + py_frame->f_lineno = lineno; + PyTraceBack_Here(py_frame); bad: - Py_XDECREF(py_globals); - Py_XDECREF(py_code); - Py_XDECREF(py_frame); + Py_XDECREF(py_globals); + Py_XDECREF(py_code); + Py_XDECREF(py_frame); } #ifdef MS_WIN32 @@ -131,15 +131,15 @@ void _ctypes_add_traceback(char *funcname, char *filename, int lineno) static void TryAddRef(StgDictObject *dict, CDataObject *obj) { - IUnknown *punk; + IUnknown *punk; - if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_")) - return; + if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_")) + return; - punk = *(IUnknown **)obj->b_ptr; - if (punk) - punk->lpVtbl->AddRef(punk); - return; + punk = *(IUnknown **)obj->b_ptr; + if (punk) + punk->lpVtbl->AddRef(punk); + return; } #endif @@ -149,421 +149,421 @@ TryAddRef(StgDictObject *dict, CDataObject *obj) * */ static void _CallPythonObject(void *mem, - ffi_type *restype, - SETFUNC setfunc, - PyObject *callable, - PyObject *converters, - int flags, - void **pArgs) + ffi_type *restype, + SETFUNC setfunc, + PyObject *callable, + PyObject *converters, + int flags, + void **pArgs) { - Py_ssize_t i; - PyObject *result; - PyObject *arglist = NULL; - Py_ssize_t nArgs; - PyObject *error_object = NULL; - int *space; + Py_ssize_t i; + PyObject *result; + PyObject *arglist = NULL; + Py_ssize_t nArgs; + PyObject *error_object = NULL; + int *space; #ifdef WITH_THREAD - PyGILState_STATE state = PyGILState_Ensure(); + PyGILState_STATE state = PyGILState_Ensure(); #endif - nArgs = PySequence_Length(converters); - /* Hm. What to return in case of error? - For COM, 0xFFFFFFFF seems better than 0. - */ - if (nArgs < 0) { - PrintError("BUG: PySequence_Length"); - goto Done; - } - - arglist = PyTuple_New(nArgs); - if (!arglist) { - PrintError("PyTuple_New()"); - goto Done; - } - for (i = 0; i < nArgs; ++i) { - /* Note: new reference! */ - PyObject *cnv = PySequence_GetItem(converters, i); - StgDictObject *dict; - if (cnv) - dict = PyType_stgdict(cnv); - else { - PrintError("Getting argument converter %d\n", i); - goto Done; - } - - if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) { - PyObject *v = dict->getfunc(*pArgs, dict->size); - if (!v) { - PrintError("create argument %d:\n", i); - Py_DECREF(cnv); - goto Done; - } - PyTuple_SET_ITEM(arglist, i, v); - /* XXX XXX XX - We have the problem that c_byte or c_short have dict->size of - 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. - BTW, the same problem occurrs when they are pushed as parameters - */ - } else if (dict) { - /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */ - CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL); - if (!obj) { - PrintError("create argument %d:\n", i); - Py_DECREF(cnv); - goto Done; - } - if (!CDataObject_Check(obj)) { - Py_DECREF(obj); - Py_DECREF(cnv); - PrintError("unexpected result of create argument %d:\n", i); - goto Done; - } - memcpy(obj->b_ptr, *pArgs, dict->size); - PyTuple_SET_ITEM(arglist, i, (PyObject *)obj); + nArgs = PySequence_Length(converters); + /* Hm. What to return in case of error? + For COM, 0xFFFFFFFF seems better than 0. + */ + if (nArgs < 0) { + PrintError("BUG: PySequence_Length"); + goto Done; + } + + arglist = PyTuple_New(nArgs); + if (!arglist) { + PrintError("PyTuple_New()"); + goto Done; + } + for (i = 0; i < nArgs; ++i) { + /* Note: new reference! */ + PyObject *cnv = PySequence_GetItem(converters, i); + StgDictObject *dict; + if (cnv) + dict = PyType_stgdict(cnv); + else { + PrintError("Getting argument converter %d\n", i); + goto Done; + } + + if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) { + PyObject *v = dict->getfunc(*pArgs, dict->size); + if (!v) { + PrintError("create argument %d:\n", i); + Py_DECREF(cnv); + goto Done; + } + PyTuple_SET_ITEM(arglist, i, v); + /* XXX XXX XX + We have the problem that c_byte or c_short have dict->size of + 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. + BTW, the same problem occurrs when they are pushed as parameters + */ + } else if (dict) { + /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */ + CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL); + if (!obj) { + PrintError("create argument %d:\n", i); + Py_DECREF(cnv); + goto Done; + } + if (!CDataObject_Check(obj)) { + Py_DECREF(obj); + Py_DECREF(cnv); + PrintError("unexpected result of create argument %d:\n", i); + goto Done; + } + memcpy(obj->b_ptr, *pArgs, dict->size); + PyTuple_SET_ITEM(arglist, i, (PyObject *)obj); #ifdef MS_WIN32 - TryAddRef(dict, obj); + TryAddRef(dict, obj); #endif - } else { - PyErr_SetString(PyExc_TypeError, - "cannot build parameter"); - PrintError("Parsing argument %d\n", i); - Py_DECREF(cnv); - goto Done; - } - Py_DECREF(cnv); - /* XXX error handling! */ - pArgs++; - } + } else { + PyErr_SetString(PyExc_TypeError, + "cannot build parameter"); + PrintError("Parsing argument %d\n", i); + Py_DECREF(cnv); + goto Done; + } + Py_DECREF(cnv); + /* XXX error handling! */ + pArgs++; + } #define CHECK(what, x) \ if (x == NULL) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() - if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { - error_object = _ctypes_get_errobj(&space); - if (error_object == NULL) - goto Done; - if (flags & FUNCFLAG_USE_ERRNO) { - int temp = space[0]; - space[0] = errno; - errno = temp; - } + if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { + error_object = _ctypes_get_errobj(&space); + if (error_object == NULL) + goto Done; + 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); - } + if (flags & FUNCFLAG_USE_LASTERROR) { + int temp = space[1]; + space[1] = GetLastError(); + SetLastError(temp); + } #endif - } + } - result = PyObject_CallObject(callable, arglist); - CHECK("'calling callback function'", result); + result = PyObject_CallObject(callable, arglist); + CHECK("'calling callback function'", result); #ifdef MS_WIN32 - if (flags & FUNCFLAG_USE_LASTERROR) { - int temp = space[1]; - space[1] = GetLastError(); - SetLastError(temp); - } + 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); - - if ((restype != &ffi_type_void) && result) { - PyObject *keep; - assert(setfunc); + if (flags & FUNCFLAG_USE_ERRNO) { + int temp = space[0]; + space[0] = errno; + errno = temp; + } + Py_XDECREF(error_object); + + if ((restype != &ffi_type_void) && result) { + PyObject *keep; + assert(setfunc); #ifdef WORDS_BIGENDIAN - /* See the corresponding code in callproc.c, around line 961 */ - if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg)) - mem = (char *)mem + sizeof(ffi_arg) - restype->size; + /* See the corresponding code in callproc.c, around line 961 */ + if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg)) + mem = (char *)mem + sizeof(ffi_arg) - restype->size; #endif - keep = setfunc(mem, result, 0); - CHECK("'converting callback result'", keep); - /* keep is an object we have to keep alive so that the result - stays valid. If there is no such object, the setfunc will - have returned Py_None. - - If there is such an object, we have no choice than to keep - it alive forever - but a refcount and/or memory leak will - be the result. EXCEPT when restype is py_object - Python - itself knows how to manage the refcount of these objects. - */ - if (keep == NULL) /* Could not convert callback result. */ - PyErr_WriteUnraisable(callable); - else if (keep == Py_None) /* Nothing to keep */ - Py_DECREF(keep); - else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { - if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning, - "memory leak in callback function.", - 1)) - PyErr_WriteUnraisable(callable); - } - } - Py_XDECREF(result); + keep = setfunc(mem, result, 0); + CHECK("'converting callback result'", keep); + /* keep is an object we have to keep alive so that the result + stays valid. If there is no such object, the setfunc will + have returned Py_None. + + If there is such an object, we have no choice than to keep + it alive forever - but a refcount and/or memory leak will + be the result. EXCEPT when restype is py_object - Python + itself knows how to manage the refcount of these objects. + */ + if (keep == NULL) /* Could not convert callback result. */ + PyErr_WriteUnraisable(callable); + else if (keep == Py_None) /* Nothing to keep */ + Py_DECREF(keep); + else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { + if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning, + "memory leak in callback function.", + 1)) + PyErr_WriteUnraisable(callable); + } + } + Py_XDECREF(result); Done: - Py_XDECREF(arglist); + Py_XDECREF(arglist); #ifdef WITH_THREAD - PyGILState_Release(state); + PyGILState_Release(state); #endif } static void closure_fcn(ffi_cif *cif, - void *resp, - void **args, - void *userdata) + void *resp, + void **args, + void *userdata) { - CThunkObject *p = (CThunkObject *)userdata; - - _CallPythonObject(resp, - p->ffi_restype, - p->setfunc, - p->callable, - p->converters, - p->flags, - args); + CThunkObject *p = (CThunkObject *)userdata; + + _CallPythonObject(resp, + p->ffi_restype, + p->setfunc, + p->callable, + p->converters, + p->flags, + args); } static CThunkObject* CThunkObject_new(Py_ssize_t nArgs) { - CThunkObject *p; - int i; - - p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs); - if (p == NULL) { - PyErr_NoMemory(); - return NULL; - } - - p->pcl = NULL; - memset(&p->cif, 0, sizeof(p->cif)); - p->converters = NULL; - p->callable = NULL; - p->setfunc = NULL; - p->ffi_restype = NULL; - - for (i = 0; i < nArgs + 1; ++i) - p->atypes[i] = NULL; - PyObject_GC_Track((PyObject *)p); - return p; + CThunkObject *p; + int i; + + p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nArgs); + if (p == NULL) { + PyErr_NoMemory(); + return NULL; + } + + p->pcl = NULL; + memset(&p->cif, 0, sizeof(p->cif)); + p->converters = NULL; + p->callable = NULL; + p->setfunc = NULL; + p->ffi_restype = NULL; + + for (i = 0; i < nArgs + 1; ++i) + p->atypes[i] = NULL; + PyObject_GC_Track((PyObject *)p); + return p; } CThunkObject *_ctypes_alloc_callback(PyObject *callable, - PyObject *converters, - PyObject *restype, - int flags) + PyObject *converters, + PyObject *restype, + int flags) { - int result; - CThunkObject *p; - Py_ssize_t nArgs, i; - ffi_abi cc; - - nArgs = PySequence_Size(converters); - p = CThunkObject_new(nArgs); - if (p == NULL) - return NULL; - - assert(CThunk_CheckExact((PyObject *)p)); - - p->pcl = _ctypes_alloc_closure(); - if (p->pcl == NULL) { - PyErr_NoMemory(); - goto error; - } - - p->flags = flags; - for (i = 0; i < nArgs; ++i) { - PyObject *cnv = PySequence_GetItem(converters, i); - if (cnv == NULL) - goto error; - p->atypes[i] = _ctypes_get_ffi_type(cnv); - Py_DECREF(cnv); - } - p->atypes[i] = NULL; - - Py_INCREF(restype); - p->restype = restype; - if (restype == Py_None) { - p->setfunc = NULL; - p->ffi_restype = &ffi_type_void; - } else { - StgDictObject *dict = PyType_stgdict(restype); - if (dict == NULL || dict->setfunc == NULL) { - PyErr_SetString(PyExc_TypeError, - "invalid result type for callback function"); - goto error; - } - p->setfunc = dict->setfunc; - p->ffi_restype = &dict->ffi_type_pointer; - } - - cc = FFI_DEFAULT_ABI; + int result; + CThunkObject *p; + Py_ssize_t nArgs, i; + ffi_abi cc; + + nArgs = PySequence_Size(converters); + p = CThunkObject_new(nArgs); + if (p == NULL) + return NULL; + + assert(CThunk_CheckExact((PyObject *)p)); + + p->pcl = _ctypes_alloc_closure(); + if (p->pcl == NULL) { + PyErr_NoMemory(); + goto error; + } + + p->flags = flags; + for (i = 0; i < nArgs; ++i) { + PyObject *cnv = PySequence_GetItem(converters, i); + if (cnv == NULL) + goto error; + p->atypes[i] = _ctypes_get_ffi_type(cnv); + Py_DECREF(cnv); + } + p->atypes[i] = NULL; + + Py_INCREF(restype); + p->restype = restype; + if (restype == Py_None) { + p->setfunc = NULL; + p->ffi_restype = &ffi_type_void; + } else { + StgDictObject *dict = PyType_stgdict(restype); + if (dict == NULL || dict->setfunc == NULL) { + PyErr_SetString(PyExc_TypeError, + "invalid result type for callback function"); + goto error; + } + p->setfunc = dict->setfunc; + p->ffi_restype = &dict->ffi_type_pointer; + } + + cc = FFI_DEFAULT_ABI; #if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64) - if ((flags & FUNCFLAG_CDECL) == 0) - cc = FFI_STDCALL; + if ((flags & FUNCFLAG_CDECL) == 0) + cc = FFI_STDCALL; #endif - result = ffi_prep_cif(&p->cif, cc, - Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int), - _ctypes_get_ffi_type(restype), - &p->atypes[0]); - if (result != FFI_OK) { - PyErr_Format(PyExc_RuntimeError, - "ffi_prep_cif failed with %d", result); - goto error; - } - result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p); - if (result != FFI_OK) { - PyErr_Format(PyExc_RuntimeError, - "ffi_prep_closure failed with %d", result); - goto error; - } - - Py_INCREF(converters); - p->converters = converters; - Py_INCREF(callable); - p->callable = callable; - return p; + result = ffi_prep_cif(&p->cif, cc, + Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int), + _ctypes_get_ffi_type(restype), + &p->atypes[0]); + if (result != FFI_OK) { + PyErr_Format(PyExc_RuntimeError, + "ffi_prep_cif failed with %d", result); + goto error; + } + result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p); + if (result != FFI_OK) { + PyErr_Format(PyExc_RuntimeError, + "ffi_prep_closure failed with %d", result); + goto error; + } + + Py_INCREF(converters); + p->converters = converters; + Py_INCREF(callable); + p->callable = callable; + return p; error: - Py_XDECREF(p); - return NULL; + Py_XDECREF(p); + return NULL; } #ifdef MS_WIN32 static void LoadPython(void) { - if (!Py_IsInitialized()) { + if (!Py_IsInitialized()) { #ifdef WITH_THREAD - PyEval_InitThreads(); + PyEval_InitThreads(); #endif - Py_Initialize(); - } + Py_Initialize(); + } } /******************************************************************/ long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - PyObject *mod, *func, *result; - long retval; - static PyObject *context; - - if (context == NULL) - context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); - - mod = PyImport_ImportModuleNoBlock("ctypes"); - if (!mod) { - PyErr_WriteUnraisable(context ? context : Py_None); - /* There has been a warning before about this already */ - return E_FAIL; - } - - func = PyObject_GetAttrString(mod, "DllGetClassObject"); - Py_DECREF(mod); - if (!func) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - { - PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid); - PyObject *py_riid = PyLong_FromVoidPtr((void *)riid); - PyObject *py_ppv = PyLong_FromVoidPtr(ppv); - if (!py_rclsid || !py_riid || !py_ppv) { - Py_XDECREF(py_rclsid); - Py_XDECREF(py_riid); - Py_XDECREF(py_ppv); - Py_DECREF(func); - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - result = PyObject_CallFunctionObjArgs(func, - py_rclsid, - py_riid, - py_ppv, - NULL); - Py_DECREF(py_rclsid); - Py_DECREF(py_riid); - Py_DECREF(py_ppv); - } - Py_DECREF(func); - if (!result) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - retval = PyLong_AsLong(result); - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(context ? context : Py_None); - retval = E_FAIL; - } - Py_DECREF(result); - return retval; + PyObject *mod, *func, *result; + long retval; + static PyObject *context; + + if (context == NULL) + context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); + + mod = PyImport_ImportModuleNoBlock("ctypes"); + if (!mod) { + PyErr_WriteUnraisable(context ? context : Py_None); + /* There has been a warning before about this already */ + return E_FAIL; + } + + func = PyObject_GetAttrString(mod, "DllGetClassObject"); + Py_DECREF(mod); + if (!func) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + { + PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid); + PyObject *py_riid = PyLong_FromVoidPtr((void *)riid); + PyObject *py_ppv = PyLong_FromVoidPtr(ppv); + if (!py_rclsid || !py_riid || !py_ppv) { + Py_XDECREF(py_rclsid); + Py_XDECREF(py_riid); + Py_XDECREF(py_ppv); + Py_DECREF(func); + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + result = PyObject_CallFunctionObjArgs(func, + py_rclsid, + py_riid, + py_ppv, + NULL); + Py_DECREF(py_rclsid); + Py_DECREF(py_riid); + Py_DECREF(py_ppv); + } + Py_DECREF(func); + if (!result) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + retval = PyLong_AsLong(result); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(context ? context : Py_None); + retval = E_FAIL; + } + Py_DECREF(result); + return retval; } STDAPI DllGetClassObject(REFCLSID rclsid, - REFIID riid, - LPVOID *ppv) + REFIID riid, + LPVOID *ppv) { - long result; + long result; #ifdef WITH_THREAD - PyGILState_STATE state; + PyGILState_STATE state; #endif - LoadPython(); + LoadPython(); #ifdef WITH_THREAD - state = PyGILState_Ensure(); + state = PyGILState_Ensure(); #endif - result = Call_GetClassObject(rclsid, riid, ppv); + result = Call_GetClassObject(rclsid, riid, ppv); #ifdef WITH_THREAD - PyGILState_Release(state); + PyGILState_Release(state); #endif - return result; + return result; } long Call_CanUnloadNow(void) { - PyObject *mod, *func, *result; - long retval; - static PyObject *context; - - if (context == NULL) - context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow"); - - mod = PyImport_ImportModuleNoBlock("ctypes"); - if (!mod) { -/* OutputDebugString("Could not import ctypes"); */ - /* We assume that this error can only occur when shutting - down, so we silently ignore it */ - PyErr_Clear(); - return E_FAIL; - } - /* Other errors cannot be raised, but are printed to stderr */ - func = PyObject_GetAttrString(mod, "DllCanUnloadNow"); - Py_DECREF(mod); - if (!func) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - result = PyObject_CallFunction(func, NULL); - Py_DECREF(func); - if (!result) { - PyErr_WriteUnraisable(context ? context : Py_None); - return E_FAIL; - } - - retval = PyLong_AsLong(result); - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(context ? context : Py_None); - retval = E_FAIL; - } - Py_DECREF(result); - return retval; + PyObject *mod, *func, *result; + long retval; + static PyObject *context; + + if (context == NULL) + context = PyUnicode_InternFromString("_ctypes.DllCanUnloadNow"); + + mod = PyImport_ImportModuleNoBlock("ctypes"); + if (!mod) { +/* OutputDebugString("Could not import ctypes"); */ + /* We assume that this error can only occur when shutting + down, so we silently ignore it */ + PyErr_Clear(); + return E_FAIL; + } + /* Other errors cannot be raised, but are printed to stderr */ + func = PyObject_GetAttrString(mod, "DllCanUnloadNow"); + Py_DECREF(mod); + if (!func) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + result = PyObject_CallFunction(func, NULL); + Py_DECREF(func); + if (!result) { + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } + + retval = PyLong_AsLong(result); + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(context ? context : Py_None); + retval = E_FAIL; + } + Py_DECREF(result); + return retval; } /* @@ -572,26 +572,26 @@ long Call_CanUnloadNow(void) STDAPI DllCanUnloadNow(void) { - long result; + long result; #ifdef WITH_THREAD - PyGILState_STATE state = PyGILState_Ensure(); + PyGILState_STATE state = PyGILState_Ensure(); #endif - result = Call_CanUnloadNow(); + result = Call_CanUnloadNow(); #ifdef WITH_THREAD - PyGILState_Release(state); + PyGILState_Release(state); #endif - return result; + return result; } #ifndef Py_NO_ENABLE_SHARED BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvRes) { - switch(fdwReason) { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - } - return TRUE; + switch(fdwReason) { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hinstDLL); + break; + } + return TRUE; } #endif |