ariovistus avatar ariovistus committed 8837e74

playing with ctypes
some ddoc touchups

Comments (0)

Files changed (12)

 *.exe
 *.obj
 junk.txt
+MANIFEST
+examples/arraytest/tsetup.py
+examples/hello/tsetup.py
+examples/inherit/tsetup.py
+examples/rawexample/tsetup.py
+examples/testdll/tsetup.py
+examples/misc/ctypes/boilerplate.d
+syntax: regexp
+^build/
+^examples/arraytest/build/
+^examples/hello/build/
+^examples/inherit/build/
+^examples/rawexample/build/
+^examples/testdll/build/
+^examples/pyind/pyind
+^examples/pyind/pyind3

examples/misc/ctypes/common.d

+
+struct PyObject{ }
+
+extern(C) alias PyObject* function(PyObject*) PyFun1;
+extern(C) alias PyObject* function(PyObject*, PyObject*) PyFun2;
+extern(C) alias PyObject* function(long) PyLFun1;
+extern(C) alias PyObject* function(ulong) PyLUFun1;
+extern(C) alias PyObject* function(const(char)* buf, size_t len) PyStrFun1;
+extern(C) alias PyObject* function(const(char)* str) PyStrFun2;
+
+struct Funs{
+    static __gshared:
+    PyStrFun2 raise;
+    PyLFun1 long_to_python;
+    PyLUFun1 ulong_to_python;
+    PyStrFun1 utf8_to_python;
+
+    PyFun2 get_item;
+}
+
+extern(C) int pyd_reg_fun(char* _fnom, PyFun1 somefun) {
+    import std.conv;
+    import std.exception;
+    import std.traits;
+    import std.typetuple;
+    import std.stdio;
+    string fnom = to!string(_fnom);
+    alias TypeTuple!(__traits(allMembers, Funs)) Fields;
+    foreach(i,_; Fields) {
+        enum string nom = _;
+        if(nom == fnom) {
+            writefln("Funs[%s]: %s", i, nom);
+            mixin("Funs."~nom ~ " = cast(typeof(Funs."~nom~")) somefun;");
+            return 0;
+        }
+    }
+    enforce(0);
+    return 0;
+}

examples/misc/ctypes/common.py

+
+dll = None
+LIST = []
+def reg_fun(nom, fun):
+    LIST.append(fun)
+    dll.pyd_reg_fun(nom, fun)

examples/misc/ctypes/makefile

+LDC=ldc2
+
+LIBS= -Wl,--no-as-needed -lphobos-ldc -ldruntime-ldc -lrt -lpthread -ldl -lm 
+
+# raise a python exception in D
+test3: test3.py libtest3.so
+	python test3.py
+test2: test2.py libtest2.so
+	python test2.py
+# convert a d integer to python int
+test1: test1.py libtest1.so
+	python test1.py
+
+clean:
+	rm -f *.so
+	rm -f *.o
+
+lib%.so: %.o boilerplate.o common.o
+	echo "building $@"
+	gcc -nostartfiles -shared $(LIBS) $^ -o $@ 
+	#gcc -shared $^ -o $@
+boilerplate.d: ../../../infrastructure/d/python_so_linux_boilerplate.d
+	cp $< $@
+	echo "extern(C) void _Dmain(){}" >> $@
+%.o: %.d 
+	echo "building $@"
+	$(LDC) -relocation-model=pic -c $^ -of $@
+	#gcc -fPIC -c $^ -o $@

examples/misc/ctypes/test1.d

+import std.exception;
+import std.typetuple;
+import std.conv;
+import std.traits;
+import common;
+
+extern(C) PyObject* test_pyd(PyObject* thing) {
+    return Funs.long_to_python(3);
+}
+

examples/misc/ctypes/test1.py

+from ctypes import *
+import ctypes.util;
+import os, os.path
+dll = CDLL(os.path.abspath("libtest1.so"))
+dll.test_pyd.restype = py_object
+def _type(obj): return type(obj)
+def _id(l): 
+    print '_id l: ', type(l)
+    return l
+FUNC2 = CFUNCTYPE(py_object, py_object, py_object)
+def get_item(thing, index):
+    print 'get_item thing: ', type(thing)
+    print 'get_item index: ', type(index)
+    return thing[index]
+def utf8_to_str(_buffer, _len):
+    a = create_string_buffer(_buffer, _len)
+    return a.value
+#dll.init_pyd(LCONV(c_longlong), LUCONV(c_ulonglong), FUNC2(get_item))
+#dll.init_pyd(LCONV(_id), LUCONV(_id), FUNC2(get_item))
+LCONV = CFUNCTYPE(py_object, c_longlong)
+dll.pyd_reg_fun('long_to_python', LCONV(_id))
+print 'zip'
+
+z = dll.test_pyd(py_object(1))
+print z
+

examples/misc/ctypes/test2.d

+import std.exception;
+import std.typetuple;
+import std.conv;
+import std.traits;
+
+import common;
+
+PyObject* d_to_python(T)(T t) {
+    static if(isIntegral!T) {
+        static if(isUnsigned!T) {
+            ulong arg = t;
+            return Funs.ulong_to_python(arg);
+        }else static if(isSigned!T) {
+            long arg  = t;
+            import std.stdio;
+            writefln("Funs.long_to_python: %s", Funs.long_to_python);
+            auto result = Funs.long_to_python(arg);
+            writefln("long_to_python result: %s", result);
+            return result;
+        }
+    }
+}
+
+extern(C) PyObject* test_long_to_d(PyObject* a) {
+    return Funs.long_to_python(3);
+}
+
+extern(C) PyObject* test_pyd(PyObject* thing) {
+    import std.stdio;
+    writefln("Funs.get_item: %s", Funs.get_item);
+    auto z = d_to_python(3);
+    writefln("z: %s", z);
+    return Funs.get_item(thing, z);
+}
+

examples/misc/ctypes/test2.py

+from ctypes import *
+import ctypes.util;
+import os, os.path
+
+from common import reg_fun
+import common
+common.dll = dll = CDLL(os.path.abspath("libtest2.so"))
+dll.test_pyd.restype = py_object
+dll.test_long_to_d.restype = py_object
+def _type(obj): return type(obj)
+def _id(l): 
+    print '_id l: ', type(l)
+    return l
+FUNC2 = CFUNCTYPE(py_object, py_object, py_object)
+def get_item(thing, index):
+    print 'get_item thing: ', type(thing)
+    print 'get_item index: ', type(index)
+    return thing[index]
+def utf8_to_str(_buffer, _len):
+    a = create_string_buffer(_buffer, _len)
+    return a.value
+    
+LCONV = CFUNCTYPE(py_object, c_longlong)
+reg_fun('long_to_python', LCONV(_id))
+LUCONV = CFUNCTYPE(py_object, c_ulonglong)
+reg_fun('ulong_to_python', LUCONV(_id))
+UTF8CONV = CFUNCTYPE(py_object, c_void_p, c_size_t)
+reg_fun('utf8_to_python', UTF8CONV(utf8_to_str))
+reg_fun('get_item', FUNC2(get_item))
+print 'test2 zip'
+print dll.test_long_to_d(py_object(1))
+
+a = set()
+#z = dll.test_pyd(py_object([1,2,3,a,5,6]))
+#print a is z
+

examples/misc/ctypes/test3.d

+import std.exception;
+import std.typetuple;
+import std.conv;
+import std.traits;
+
+import common;
+
+extern(C) PyObject* test_pyd(PyObject* thing) {
+    try{
+        enforce(false);
+    }catch(Throwable t) {
+        Funs.raise(("D Exception:\n" ~ t.toString() ~ "\0").ptr);
+    }
+    return thing;
+}
+

examples/misc/ctypes/test3.py

+from ctypes import *
+import ctypes.util;
+import os, os.path
+dll = CDLL(os.path.abspath("libtest3.so"))
+dll.test_pyd.restype = py_object
+STRFUNC1 = CFUNCTYPE(py_object, c_char_p)
+def _raise(buf):
+    print '_raise.buf: ', type(buf)
+    raise Exception(buf)
+dll.pyd_reg_fun('raise', STRFUNC1(_raise))
+print 'zip'
+
+dll.test_pyd(py_object(1))
+

infrastructure/pyd/embedded.d

   Encapsulate a context within the Python interpreter.
 
   This will preserve local variables and changes to the Python interpreter
-  made by 'from __future__ import feature' across calls to this.py_eval and
+  made by 'from ___future__ import feature' across calls to this.py_eval and
   this.py_stmts.
 
   Otherwise, will not segregate global changes made to the Python interpreter.

infrastructure/pyd/func_wrap.d

 template maxArgs(alias fn, fn_t = typeof(&fn)) {
     alias variadicFunctionStyle!fn vstyle;
     alias ParameterTypeTuple!fn ps;
+    /// _
     enum bool hasMax = vstyle == Variadic.no;
+    /// _
     enum size_t max = ps.length;
 }
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.