From: <wme...@us...> - 2009-09-04 13:50:28
|
Revision: 6750 http://jython.svn.sourceforge.net/jython/?rev=6750&view=rev Author: wmeissner Date: 2009-09-04 13:50:18 +0000 (Fri, 04 Sep 2009) Log Message: ----------- Implement from_address and in_dll for scalar, pointer, string and struct types Modified Paths: -------------- branches/ctypes-jffi/Lib/ctypes/__init__.py branches/ctypes-jffi/src/org/python/modules/jffi/CData.java branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java branches/ctypes-jffi/src/org/python/modules/jffi/StringCData.java branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java branches/ctypes-jffi/src/org/python/modules/jffi/Util.java Modified: branches/ctypes-jffi/Lib/ctypes/__init__.py =================================================================== --- branches/ctypes-jffi/Lib/ctypes/__init__.py 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/Lib/ctypes/__init__.py 2009-09-04 13:50:18 UTC (rev 6750) @@ -27,14 +27,19 @@ dict = { '_jffi_type': jffi.Type.Array(self, len) } return type("%s_%d" % (self.__name__, len), (_ArrayCData,), dict) -class _ScalarCData(jffi.ScalarCData): - __metaclass__ = _CTypeMetaClass +class _CData(object): + @classmethod + def in_dll(self, lib, name): + return self.from_address(lib[name]) + @classmethod def size(self): return self._jffi_type.size - size = classmethod(size) +class _ScalarCData(jffi.ScalarCData, _CData): + __metaclass__ = _CTypeMetaClass + class _ArrayCData(object): def __init__(self, *args): raise NotImplementedError("instantiating arrays is not implemented yet") @@ -76,6 +81,7 @@ return jffi.StructLayout(fields = self.fields, union = self.union) class _AggregateMetaClass(type): + @staticmethod def __new_aggregate__(cls, name, bases, dict, union = False): if dict.has_key('_fields_'): layout = dict['_jffi_type'] = _StructLayoutBuilder(union).add_fields(dict['_fields_']).build() @@ -85,8 +91,6 @@ return type.__new__(cls, name, bases, dict) - __new_aggregate__ = staticmethod(__new_aggregate__) - class _StructMetaClass(_AggregateMetaClass): def __new__(cls, name, bases, dict): return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = False) @@ -95,7 +99,7 @@ def __new__(cls, name, bases, dict): return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = True) -class Structure(jffi.Structure): +class Structure(jffi.Structure, _CData): __metaclass__ = _StructMetaClass class Union(jffi.Structure): @@ -133,7 +137,7 @@ name = mod.__name__ dict["__module__"] = name - ptype = type("LP_%s" % (ctype.__name__,), (jffi.PointerCData,), dict) + ptype = type("LP_%s" % (ctype.__name__,), (jffi.PointerCData, _CData), dict) _pointer_type_cache[ctype] = ptype return ptype @@ -201,7 +205,7 @@ c_size_t = c_ulong c_ssize_t = c_long -class c_char_p(jffi.StringCData): +class c_char_p(jffi.StringCData, _CData): _type_ = 'z' _jffi_type = jffi.Type.STRING Modified: branches/ctypes-jffi/src/org/python/modules/jffi/CData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/CData.java 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/src/org/python/modules/jffi/CData.java 2009-09-04 13:50:18 UTC (rev 6750) @@ -2,6 +2,8 @@ package org.python.modules.jffi; import org.python.core.Py; +import org.python.core.PyInteger; +import org.python.core.PyLong; import org.python.core.PyObject; import org.python.core.PyType; import org.python.expose.ExposedMethod; @@ -15,10 +17,14 @@ private DirectMemory referenceMemory; - CData(PyType subtype, CType type) { + CData(PyType subtype, CType ctype) { + this(subtype, ctype, null); + } + + CData(PyType subtype, CType ctype, DirectMemory memory) { super(subtype); - this.ctype = type; - this.referenceMemory = null; + this.ctype = ctype; + this.referenceMemory = memory; } /** @@ -86,4 +92,15 @@ } protected abstract void initReferenceMemory(Memory m); + + + + protected static final DirectMemory findInDll(PyObject lib, PyObject name) { + if (!(lib instanceof DynamicLibrary)) { + throw Py.TypeError("expected library, not " + lib.getType().fastGetName()); + } + DynamicLibrary.Symbol sym = (DynamicLibrary.Symbol) ((DynamicLibrary) lib).find_symbol(name); + + return sym.getMemory(); + } } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java 2009-09-04 13:50:18 UTC (rev 6750) @@ -79,13 +79,22 @@ public static final class TextSymbol extends Symbol implements ExposeAsSuperclass { public TextSymbol(DynamicLibrary lib, String name, long address) { - super(lib, name, new NativeMemory(address)); + super(lib, name, new SymbolMemory(lib, address)); } } public static final class DataSymbol extends Symbol implements ExposeAsSuperclass { public DataSymbol(DynamicLibrary lib, String name, long address) { - super(lib, name, new NativeMemory(address)); + super(lib, name, new SymbolMemory(lib, address)); } } + + private static final class SymbolMemory extends NativeMemory { + private final DynamicLibrary library; // backlink to keep library alive + + public SymbolMemory(DynamicLibrary library, long address) { + super(address); + this.library = library; + } + } } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java 2009-09-04 13:50:18 UTC (rev 6750) @@ -5,6 +5,7 @@ import org.python.core.PyNewWrapper; import org.python.core.PyObject; import org.python.core.PyType; +import org.python.expose.ExposedClassMethod; import org.python.expose.ExposedGet; import org.python.expose.ExposedNew; import org.python.expose.ExposedSet; @@ -25,14 +26,8 @@ public static PyObject PointerCData_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { - PyObject jffi_type = subtype.__getattr__("_jffi_type"); + CType.Pointer pointerType = getPointerType(subtype); - if (!(jffi_type instanceof CType.Pointer)) { - throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); - } - - CType.Pointer pointerType = (CType.Pointer) jffi_type; - // No args == create NULL pointer if (args.length == 0) { return new PointerCData(subtype, pointerType, NullMemory.INSTANCE, pointerType.componentMemoryOp); @@ -48,6 +43,27 @@ } } + static final CType.Pointer getPointerType(PyType subtype) { + PyObject jffi_type = subtype.__getattr__("_jffi_type"); + + if (!(jffi_type instanceof CType.Pointer)) { + throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); + } + + return (CType.Pointer) jffi_type; + } + + @ExposedClassMethod(names= { "from_address" }) + public static final PyObject from_address(PyType subtype, PyObject address) { + + CType.Pointer pointerType = getPointerType(subtype); + DirectMemory m = Util.getMemoryForAddress(address); + PointerCData cdata = new PointerCData(subtype, pointerType, m.getMemory(0), pointerType.componentMemoryOp); + cdata.setReferenceMemory(m); + + return cdata; + } + @ExposedGet(name="contents") public PyObject getContents() { return componentMemoryOp.get(getMemory(), 0); @@ -57,4 +73,5 @@ public void setContents(PyObject value) { componentMemoryOp.put(getMemory(), 0, value); } + } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java 2009-09-04 13:50:18 UTC (rev 6750) @@ -3,10 +3,13 @@ import org.python.core.Py; import org.python.core.PyFloat; +import org.python.core.PyInteger; +import org.python.core.PyLong; import org.python.core.PyNewWrapper; import org.python.core.PyObject; import org.python.core.PyObject.ConversionException; import org.python.core.PyType; +import org.python.expose.ExposedClassMethod; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; @@ -16,31 +19,46 @@ @ExposedType(name = "jffi.ScalarCData", base = CData.class) public class ScalarCData extends CData { public static final PyType TYPE = PyType.fromClass(ScalarCData.class); - + static { +// TYPE.fastGetDict().__setitem__("in_dll", new InDll()); + } private PyObject value = Py.None; @ExposedNew public static PyObject ScalarCData_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { - PyObject jffi_type = subtype.__getattr__("_jffi_type"); + ScalarCData cdata = new ScalarCData(subtype, getScalarType(subtype)); - if (!(jffi_type instanceof CType.Builtin)) { - throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); - } - - ScalarCData cdata = new ScalarCData(subtype, (CType.Builtin) jffi_type); - // If an initial value was supplied, use it, else default to zero cdata.setValue(args.length > 0 ? args[0] : Py.newInteger(0)); return cdata; } + + @ExposedClassMethod(names= { "from_address" }) + public static final PyObject from_address(PyType subtype, PyObject address) { + return new ScalarCData(subtype, getScalarType(subtype), Util.getMemoryForAddress(address)); + } + + static final CType.Builtin getScalarType(PyType subtype) { + PyObject jffi_type = subtype.__getattr__("_jffi_type"); + + if (!(jffi_type instanceof CType.Builtin)) { + throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); + } + return (CType.Builtin) jffi_type; + } + ScalarCData(PyType pytype, CType.Builtin ctype) { super(pytype, ctype); } + ScalarCData(PyType pytype, CType.Builtin ctype, DirectMemory m) { + super(pytype, ctype, m); + } + protected final void initReferenceMemory(Memory m) { getMemoryOp().put(m, 0, value); } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/StringCData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/StringCData.java 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/src/org/python/modules/jffi/StringCData.java 2009-09-04 13:50:18 UTC (rev 6750) @@ -5,6 +5,7 @@ import org.python.core.PyNewWrapper; import org.python.core.PyObject; import org.python.core.PyType; +import org.python.expose.ExposedClassMethod; import org.python.expose.ExposedGet; import org.python.expose.ExposedNew; import org.python.expose.ExposedSet; @@ -33,6 +34,16 @@ return new StringCData(subtype, CType.typeOf(subtype), m); } + @ExposedClassMethod(names= { "from_address" }) + public static final PyObject from_address(PyType subtype, PyObject address) { + + DirectMemory m = Util.getMemoryForAddress(address); + StringCData cdata = new StringCData(subtype, CType.typeOf(subtype), m.getMemory(0)); + cdata.setReferenceMemory(m); + + return cdata; + } + @ExposedGet(name = "value") public PyObject getValue() { Memory m = getMemory(); Modified: branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/src/org/python/modules/jffi/Structure.java 2009-09-04 13:50:18 UTC (rev 6750) @@ -1,13 +1,12 @@ package org.python.modules.jffi; -import java.lang.reflect.Field; import java.util.List; -import org.python.core.ArgParser; import org.python.core.Py; import org.python.core.PyNewWrapper; import org.python.core.PyObject; import org.python.core.PyType; +import org.python.expose.ExposedClassMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @@ -33,12 +32,7 @@ public static PyObject Structure_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { - PyObject jffi_type = subtype.__getattr__("_jffi_type"); - if (!(jffi_type instanceof StructLayout)) { - throw Py.TypeError("invalid _jffi_type for " + subtype.fastGetName() + "; should be instance of jffi.StructLayout"); - } - - StructLayout layout = (StructLayout) jffi_type; + StructLayout layout = getStructLayout(subtype); Structure s = new Structure(subtype, layout); if (args.length > 0) { int n = args.length - keywords.length; @@ -59,6 +53,20 @@ return s; } + static final StructLayout getStructLayout(PyType subtype) { + PyObject jffi_type = subtype.__getattr__("_jffi_type"); + if (!(jffi_type instanceof StructLayout)) { + throw Py.TypeError("invalid _jffi_type for " + subtype.fastGetName() + "; should be instance of jffi.StructLayout"); + } + + return (StructLayout) jffi_type; + } + + @ExposedClassMethod(names= { "from_address" }) + public static final PyObject from_address(PyType subtype, PyObject address) { + return new Structure(subtype, getStructLayout(subtype), Util.getMemoryForAddress(address)); + } + protected final void initReferenceMemory(Memory m) { throw Py.RuntimeError("reference memory already initialized"); } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/Util.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/Util.java 2009-09-04 13:44:07 UTC (rev 6749) +++ branches/ctypes-jffi/src/org/python/modules/jffi/Util.java 2009-09-04 13:50:18 UTC (rev 6750) @@ -129,4 +129,15 @@ + off + " size=" + len + " is out of bounds"); } } + + static final DirectMemory getMemoryForAddress(PyObject address) { + if (address instanceof Pointer) { + return ((Pointer) address).getMemory(); + } else if (address instanceof PyInteger) { + return new NativeMemory(address.asInt()); + } else if (address instanceof PyLong) { + return new NativeMemory(((PyLong) address).getValue().longValue()); + } + throw Py.TypeError("invalid address"); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |