ariovistus avatar ariovistus committed bb2148d

conversion of d string to python unicode through ctypes
got a 32 bit shared lib out of dmd on linux!

Comments (0)

Files changed (12)

examples/misc/ctypes/common.py

-
+from ctypes import *
 dll = None
 LIST = []
 def reg_fun(nom, fun):
     LIST.append(fun)
     dll.pyd_reg_fun(nom, fun)
+UTF8CONV = CFUNCTYPE(py_object, POINTER(c_char), c_size_t)
+def utf8_to_str(_buffer, _len):
+    bz = bytearray(_len)
+    for i in xrange(_len): bz[i] = _buffer[i];
+    return unicode(str(bz), 'utf8' )
+LCONV = CFUNCTYPE(py_object, c_longlong)
+LUCONV = CFUNCTYPE(py_object, c_ulonglong)
+def my_id(l): return l
+FUNC2 = CFUNCTYPE(py_object, py_object, py_object)
+def get_item(thing, index): return thing[index]

examples/misc/ctypes/makefile

 
 LIBS= -Wl,--no-as-needed -lphobos-ldc -ldruntime-ldc -lrt -lpthread -ldl -lm 
 
+# convert a D string to python unicode
+test4: test4.py libtest4.so
+	python test4.py
 # raise a python exception in D
 test3: test3.py libtest3.so
 	python test3.py

examples/misc/ctypes/test1.py

 from ctypes import *
 import ctypes.util;
 import os, os.path
-dll = CDLL(os.path.abspath("libtest1.so"))
+from common import *
+import common
+common.dll = 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'
+dll.pyd_reg_fun('long_to_python', LCONV(my_id))
 
 z = dll.test_pyd(py_object(1))
-print z
+assert z == 3
 

examples/misc/ctypes/test2.py

 import ctypes.util;
 import os, os.path
 
-from common import reg_fun
+from common import *
 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('long_to_python', LCONV(my_id))
+reg_fun('ulong_to_python', LUCONV(my_id))
 reg_fun('get_item', FUNC2(get_item))
-print 'test2 zip'
-print dll.test_long_to_d(py_object(1))
 
+z = dll.test_long_to_d(py_object(1))
+assert z == 3
 a = set()
-#z = dll.test_pyd(py_object([1,2,3,a,5,6]))
-#print a is z
+z = dll.test_pyd(py_object([1,2,3,a,5,6]))
+assert a is z
 

examples/misc/ctypes/test4.d

+import std.exception;
+import std.typetuple;
+import std.conv;
+import std.traits;
+
+import common;
+
+extern(C) PyObject* test_pyd(int i) {
+    string ret;
+    foreach(j; 0 .. i) {
+        if(j == 0) ret = "Doctor!\0";
+        else if(j == 2) ret ~= " ち!\0";
+        else ret ~= " Doctor!\0";
+    }
+    return Funs.utf8_to_python(ret.ptr, ret.length);
+}
+

examples/misc/ctypes/test4.py

+from ctypes import *
+import ctypes.util;
+import os, os.path
+from common import *
+import common
+common.dll = dll = CDLL(os.path.abspath("libtest4.so"))
+dll.test_pyd.restype = py_object
+
+reg_fun('utf8_to_python', UTF8CONV(utf8_to_str))
+
+a = dll.test_pyd(1)
+assert a == u'Doctor!\0'
+a = dll.test_pyd(2)
+assert a == u'Doctor!\0 Doctor!\0'
+a = dll.test_pyd(5)
+assert a == u'Doctor!\0 Doctor!\0 \u3061!\0 Doctor!\0 Doctor!\0'
+

examples/misc/dmd_sharedlibs/boilerplate.d

+extern(C) shared bool _D2rt6dmain212_d_isHaltingOb;
+alias _D2rt6dmain212_d_isHaltingOb _d_isHalting;
+extern(C) {
+
+    void rt_init();
+    void rt_term();
+
+    void my_init() {
+        rt_init();
+    }
+
+    void my_fini() {
+        if(!_d_isHalting){
+            rt_term();
+        }
+    }
+
+}
+
+// (*^*&%^(* druntime
+
+extern(C) void _Dmain(){}

examples/misc/dmd_sharedlibs/makefile

 # ###########################################################
-#DMD=dmd
-DMD=dmd -m32 
-GCC=gcc -m32
-#DMD=dmd -m32 -v
+BITSI = 
+ifeq ($(BITSI), 32)
+DMD_M=-m32
+GCC_M=-m32
+else	
+ifeq ($(BITSI), 64)
+DMD_M=-m64
+GCC_M=-m64
+else
+DMD_M=
+GCC_M=
+endif
+endif
+DMD=dmd $(DMD_M)
+GCC=gcc $(GCC_M)
+
+
+# build a shared lib with d, link to it from c.
 test1: test1.x libtest1.so
 	LD_LIBRARY_PATH=. ./test1.x
+# build two shared libs with d, link to both from c.
+test2: test2.x libtest2a.so libtest2b.so
+	LD_LIBRARY_PATH=. ./test2.x
 test3: test3.x libtest3.so
 	LD_LIBRARY_PATH=. ./test3.x
 clean:
 	rm -f *.so
 	rm -f *.x
 
-libtest1.so: test1.d test1helper.c
+lib%.so: %.d boilerplate.d test1helper.o 
+	$(DMD) -unittest -fPIC -shared $^ -of$@
+test1helper.o: test1helper.c
 	$(GCC) -c test1helper.c -o test1helper.o
-	$(DMD) -fPIC -shared $< test1helper.o -of$@
 
 test1.x: test1.c libtest1.so
 	LD_LIBRARY_PATH=. $(GCC) $< -L. -ltest1 -o $@
+test2.x: test2.c libtest2a.so libtest2b.so
+	LD_LIBRARY_PATH=. $(GCC) $< -L. -ltest2a -ltest2b -o $@
 test3.x: test3.d libtest3.so
 	LD_LIBRARY_PATH=. dmd $< -L-L. -L-ltest3 -of$@ 
 libtest3.so: test3lib.c

examples/misc/dmd_sharedlibs/test1.d

-import std.c.stdio;
-// stuff in our library
+import std.stdio;
 
 static this() {
-    printf("yawn. stretch.");
+    writeln("yawn. stretch.");
+}
+
+unittest {
+    writeln("lets test this donut.");
 }
 
 extern(C) int foo(int i) {
-    return "abc".dup.length + i+1;
+    return cast(int)("abc".dup.length) + i+1;
 }
 
-// stuff in infrastructure/d/python_so_boilerplate
-
-extern(C) shared bool _D2rt6dmain212_d_isHaltingOb;
-alias _D2rt6dmain212_d_isHaltingOb _d_isHalting;
-extern(C) {
-
-    void rt_init();
-    void rt_term();
-
-    void my_init() {
-        rt_init();
-    }
-
-    void my_fini() {
-        if(!_d_isHalting){
-            rt_term();
-        }
-    }
-
-}
-
-// (*^*&%^(* druntime
-
-extern(C) void _Dmain(){}

examples/misc/dmd_sharedlibs/test2.c

+
+#include <stdio.h>
+int foo(int);
+int foo2(int);
+
+// bad bad bad
+void *_deh_beg;
+void *_deh_end;
+__thread void *_tlsstart;
+__thread void *_tlsend;
+
+int main() {
+    printf("foo(%d)=%d\n", 2, foo(2));
+    printf("foo2(%d)=%d\n", 2, foo2(2));
+    return 0;
+}
+

examples/misc/dmd_sharedlibs/test2a.d

+import std.stdio;
+
+static this() {
+    writeln("yawn. stretch.");
+}
+
+extern(C) int foo(int i) {
+    return cast(int)("abc".dup.length) + i+1;
+}

examples/misc/dmd_sharedlibs/test2b.d

+import std.stdio;
+
+static this() {
+    writeln("yawn yawn. stretch stretch.");
+}
+
+extern(C) int foo2(int i) {
+    return cast(int)("abcd".dup.length) + i+1;
+}
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.