-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathtest.py
72 lines (54 loc) · 1.84 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
from ctypes import *
import glob
import struct
import msgpack
import itertools
# For finding where the built .so file is, independent on whether it was built with stack or cabal
def find_file_ending_with(ending_with_str, path='.'):
# `glob` `**` does not match dotfiles (such as `.stack_work`), so we have to do that explicitly.
glob_result_generator = itertools.chain(
glob.glob(path + "/**/*" + ending_with_str, recursive=True),
glob.glob(path + "/.*/**/*" + ending_with_str, recursive=True),
)
for path_str in glob_result_generator:
return path_str
else:
raise Exception("Could not find " + ending_with_str + " in " + path)
so_file_path = find_file_ending_with('call-haskell-from-anything.so')
free = cdll.LoadLibrary("libc.so.6").free
lib = cdll.LoadLibrary(so_file_path)
lib.hs_init(0, 0)
# Set function return type to string
fun = lib.f1_t_export
fun.restype = POINTER(c_char)
# Call function
msg = msgpack.packb([1, 2.23])
length_64bits = struct.pack(">q", len(msg)) # big-endian
ptr = fun(length_64bits + msg)
data_length = struct.unpack(">q", ptr[:8])[0]
res = msgpack.unpackb(ptr[8:8+data_length])
free(ptr)
print("Haskell said:", res)
# Some shortcuts
def make_msgpack_fun(fun):
fun.restype = POINTER(c_char)
def f(*args):
packed = msgpack.packb(args)
length_64bits = struct.pack(">q", len(packed)) # big-endian
ptr = fun(length_64bits + packed)
data_length = struct.unpack(">q", ptr[:8])[0]
res = msgpack.unpackb(ptr[8:8+data_length])
free(ptr)
return res
return f
# Now this is the only thing required
fib = make_msgpack_fun(lib.fib_export)
print("Haskell fib:", fib(13))
# def fib(n):
# if n == 0 or n == 1: return 1
# return fib(n-1) + fib(n-2)
sum = 0
for x in range(100000):
sum += fib(15)
print(sum)
lib.hs_exit()