[Python-checkins] r62339 - in python/branches/py3k: Lib/ctypes/__init__.py Modules/_ctypes/_ctypes.c Modules/_ctypes/callproc.c Modules/_ctypes/ctypes.h
thomas.heller
python-checkins at python.org
Mon Apr 14 18:17:33 CEST 2008
Author: thomas.heller
Date: Mon Apr 14 18:17:33 2008
New Revision: 62339
Log:
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.
........
Modified:
python/branches/py3k/ (props changed)
python/branches/py3k/Lib/ctypes/__init__.py
python/branches/py3k/Modules/_ctypes/_ctypes.c
python/branches/py3k/Modules/_ctypes/callproc.c
python/branches/py3k/Modules/_ctypes/ctypes.h
Modified: python/branches/py3k/Lib/ctypes/__init__.py
==============================================================================
--- python/branches/py3k/Lib/ctypes/__init__.py (original)
+++ python/branches/py3k/Lib/ctypes/__init__.py Mon Apr 14 18:17:33 2008
@@ -239,27 +239,7 @@
class c_bool(_SimpleCData):
_type_ = "?"
-# This cache maps types to pointers to them.
-_pointer_type_cache = {}
-
-def POINTER(cls):
- try:
- return _pointer_type_cache[cls]
- except KeyError:
- pass
- if type(cls) is str:
- klass = type(_Pointer)("LP_%s" % cls,
- (_Pointer,),
- {})
- _pointer_type_cache[id(klass)] = klass
- return klass
- else:
- name = "LP_%s" % cls.__name__
- klass = type(_Pointer)(name,
- (_Pointer,),
- {'_type_': cls})
- _pointer_type_cache[cls] = klass
- return klass
+from _ctypes import POINTER, pointer, _pointer_type_cache
try:
from _ctypes import set_conversion_mode
@@ -309,10 +289,6 @@
_pointer_type_cache[cls] = pointer
del _pointer_type_cache[id(pointer)]
-
-def pointer(inst):
- return POINTER(type(inst))(inst)
-
# XXX Deprecated
def ARRAY(typ, len):
return typ * len
Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/_ctypes.c (original)
+++ python/branches/py3k/Modules/_ctypes/_ctypes.c Mon Apr 14 18:17:33 2008
@@ -123,6 +123,10 @@
#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 @@
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;
Modified: python/branches/py3k/Modules/_ctypes/callproc.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callproc.c (original)
+++ python/branches/py3k/Modules/_ctypes/callproc.c Mon Apr 14 18:17:33 2008
@@ -1565,7 +1565,76 @@
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
Modified: python/branches/py3k/Modules/_ctypes/ctypes.h
==============================================================================
--- python/branches/py3k/Modules/_ctypes/ctypes.h (original)
+++ python/branches/py3k/Modules/_ctypes/ctypes.h Mon Apr 14 18:17:33 2008
@@ -342,6 +342,7 @@
/* XXX better name needed! */
extern int IsSimpleSubType(PyObject *obj);
+extern PyObject *_pointer_type_cache;
#ifdef MS_WIN32
extern PyObject *ComError;
More information about the Python-checkins
mailing list