mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
Merged revisions 62338 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r62338 | thomas.heller | 2008-04-14 18:10:07 +0200 (Mo, 14 Apr 2008) | 3 lines Issue #2616: Implement ctypes.pointer() and ctypes.POINTER() in C for better performance. ........
This commit is contained in:
parent
c2ea8c6c3a
commit
3071f8191b
4 changed files with 81 additions and 25 deletions
|
@ -123,6 +123,10 @@ bytes(cdata)
|
|||
#include "ctypes.h"
|
||||
|
||||
PyObject *PyExc_ArgError;
|
||||
|
||||
/* This dict maps ctypes types to POINTER types */
|
||||
PyObject *_pointer_type_cache;
|
||||
|
||||
static PyTypeObject Simple_Type;
|
||||
|
||||
/* a callable object used for unpickling */
|
||||
|
@ -4994,6 +4998,12 @@ init_ctypes(void)
|
|||
if (!m)
|
||||
return;
|
||||
|
||||
_pointer_type_cache = PyDict_New();
|
||||
if (_pointer_type_cache == NULL)
|
||||
return;
|
||||
|
||||
PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_pointer_type_cache);
|
||||
|
||||
_unpickle = PyObject_GetAttrString(m, "_unpickle");
|
||||
if (_unpickle == NULL)
|
||||
return;
|
||||
|
|
|
@ -1565,7 +1565,76 @@ unpickle(PyObject *self, PyObject *args)
|
|||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
POINTER(PyObject *self, PyObject *cls)
|
||||
{
|
||||
PyObject *result;
|
||||
PyTypeObject *typ;
|
||||
PyObject *key;
|
||||
char *buf;
|
||||
|
||||
result = PyDict_GetItem(_pointer_type_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(&Pointer_Type),
|
||||
"s(O){}",
|
||||
buf,
|
||||
&Pointer_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(&Pointer_Type),
|
||||
"s(O){sO}",
|
||||
buf,
|
||||
&Pointer_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(_pointer_type_cache, key, result)) {
|
||||
Py_DECREF(result);
|
||||
Py_DECREF(key);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pointer(PyObject *self, PyObject *arg)
|
||||
{
|
||||
PyObject *result;
|
||||
PyObject *typ;
|
||||
|
||||
typ = PyDict_GetItem(_pointer_type_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;
|
||||
}
|
||||
|
||||
PyMethodDef module_methods[] = {
|
||||
{"POINTER", POINTER, METH_O },
|
||||
{"pointer", pointer, METH_O },
|
||||
{"_unpickle", unpickle, METH_VARARGS },
|
||||
{"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"},
|
||||
#ifdef CTYPES_UNICODE
|
||||
|
|
|
@ -342,6 +342,7 @@ extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t in
|
|||
/* XXX better name needed! */
|
||||
extern int IsSimpleSubType(PyObject *obj);
|
||||
|
||||
extern PyObject *_pointer_type_cache;
|
||||
|
||||
#ifdef MS_WIN32
|
||||
extern PyObject *ComError;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue