2022-06-19 23:52:37 +00:00
|
|
|
#
|
|
|
|
# Simple FFI test script that tests against a simple shared object
|
|
|
|
#
|
|
|
|
|
2022-08-14 18:26:13 +00:00
|
|
|
(def is-windows (= :windows (os/which)))
|
|
|
|
(def ffi/loc (string "examples/ffi/so." (if is-windows "dll" "so")))
|
2022-06-18 15:06:39 +00:00
|
|
|
(def ffi/source-loc "examples/ffi/so.c")
|
2022-06-08 14:41:09 +00:00
|
|
|
|
2022-08-14 18:26:13 +00:00
|
|
|
(if is-windows
|
|
|
|
(os/execute ["cl.exe" "/nologo" "/LD" ffi/source-loc "/link" "/DLL" (string "/OUT:" ffi/loc)] :px)
|
|
|
|
(os/execute ["cc" ffi/source-loc "-shared" "-o" ffi/loc] :px))
|
2022-06-08 14:41:09 +00:00
|
|
|
|
2022-08-14 20:20:30 +00:00
|
|
|
(ffi/context ffi/loc)
|
2022-06-10 01:27:56 +00:00
|
|
|
|
2022-06-12 15:02:02 +00:00
|
|
|
(def intintint (ffi/struct :int :int :int))
|
|
|
|
(def big (ffi/struct :s64 :s64 :s64))
|
2022-06-10 17:24:50 +00:00
|
|
|
|
2022-08-14 20:20:30 +00:00
|
|
|
(ffi/defbind int-fn :int [a :int b :int])
|
|
|
|
(ffi/defbind double-fn :double [a :double b :double c :double])
|
|
|
|
(ffi/defbind double-many :double
|
|
|
|
[x :double y :double z :double w :double a :double b :double])
|
|
|
|
(ffi/defbind double-lots :double
|
|
|
|
[a :double b :double c :double d :double e :double f :double g :double h :double i :double j :double])
|
|
|
|
(ffi/defbind float-fn :double
|
|
|
|
[x :float y :float z :float])
|
|
|
|
(ffi/defbind intint-fn :int
|
|
|
|
[x :double ii [:int :int]])
|
|
|
|
(ffi/defbind return-struct [:int :int]
|
|
|
|
[i :int])
|
|
|
|
(ffi/defbind intintint-fn :int
|
|
|
|
[x :double iii intintint])
|
|
|
|
(ffi/defbind struct-big big
|
|
|
|
[i :int d :double])
|
|
|
|
(ffi/defbind void-fn :void [])
|
|
|
|
(ffi/defbind double-lots-2 :double
|
|
|
|
[a :double
|
|
|
|
b :double
|
|
|
|
c :double
|
|
|
|
d :double
|
|
|
|
e :double
|
|
|
|
f :double
|
|
|
|
g :double
|
|
|
|
h :double
|
|
|
|
i :double
|
|
|
|
j :double])
|
2022-09-15 18:58:54 +00:00
|
|
|
(ffi/defbind void-fn-2 :void [y :double])
|
2022-06-10 17:33:01 +00:00
|
|
|
|
2022-09-18 02:18:07 +00:00
|
|
|
(def split (ffi/struct :int :int :float :float))
|
|
|
|
(ffi/defbind split-fn :float [s split])
|
2022-06-10 14:38:52 +00:00
|
|
|
#
|
|
|
|
# Struct reading and writing
|
|
|
|
#
|
|
|
|
|
|
|
|
(defn check-round-trip
|
|
|
|
[t value]
|
2022-06-12 15:02:02 +00:00
|
|
|
(def buf (ffi/write t value))
|
|
|
|
(def same-value (ffi/read t buf))
|
2022-06-10 14:38:52 +00:00
|
|
|
(assert (deep= value same-value)
|
|
|
|
(string/format "round trip %j (got %j)" value same-value)))
|
|
|
|
|
|
|
|
(check-round-trip :bool true)
|
|
|
|
(check-round-trip :bool false)
|
|
|
|
(check-round-trip :void nil)
|
|
|
|
(check-round-trip :void nil)
|
|
|
|
(check-round-trip :s8 10)
|
|
|
|
(check-round-trip :s8 0)
|
|
|
|
(check-round-trip :s8 -10)
|
|
|
|
(check-round-trip :u8 10)
|
|
|
|
(check-round-trip :u8 0)
|
|
|
|
(check-round-trip :s16 10)
|
|
|
|
(check-round-trip :s16 0)
|
|
|
|
(check-round-trip :s16 -12312)
|
|
|
|
(check-round-trip :u16 10)
|
|
|
|
(check-round-trip :u16 0)
|
|
|
|
(check-round-trip :u32 0)
|
|
|
|
(check-round-trip :u32 10)
|
|
|
|
(check-round-trip :u32 0xFFFF7777)
|
|
|
|
(check-round-trip :s32 0x7FFF7777)
|
|
|
|
(check-round-trip :s32 0)
|
|
|
|
(check-round-trip :s32 -1234567)
|
|
|
|
|
2022-06-12 15:02:02 +00:00
|
|
|
(def s (ffi/struct :s8 :s8 :s8 :float))
|
2022-06-10 14:38:52 +00:00
|
|
|
(check-round-trip s [1 3 5 123.5])
|
|
|
|
(check-round-trip s [-1 -3 -5 -123.5])
|
|
|
|
|
2022-08-14 18:26:13 +00:00
|
|
|
#
|
|
|
|
# Call functions
|
|
|
|
#
|
|
|
|
|
2022-09-18 02:18:07 +00:00
|
|
|
(tracev (split-fn [5 6 1.2 3.4]))
|
2022-09-15 18:58:54 +00:00
|
|
|
(tracev (void-fn-2 10.3))
|
2022-08-14 20:20:30 +00:00
|
|
|
(tracev (double-many 1 2 3 4 5 6))
|
|
|
|
(tracev (string/format "%.17g" (double-many 1 2 3 4 5 6)))
|
|
|
|
(tracev (type (double-many 1 2 3 4 5 6)))
|
|
|
|
(tracev (double-lots-2 0 1 2 3 4 5 6 7 8 9))
|
|
|
|
(tracev (void-fn))
|
|
|
|
(tracev (int-fn 10 20))
|
|
|
|
(tracev (double-fn 1.5 2.5 3.5))
|
|
|
|
(tracev (double-lots 1 2 3 4 5 6 7 8 9 10))
|
|
|
|
(tracev (float-fn 8 4 17))
|
|
|
|
(tracev (intint-fn 123.456 [10 20]))
|
|
|
|
(tracev (intintint-fn 123.456 [10 20 30]))
|
|
|
|
(tracev (return-struct 42))
|
|
|
|
(tracev (double-lots 1 2 3 4 5 6 700 800 9 10))
|
|
|
|
(tracev (struct-big 11 99.5))
|
|
|
|
|
|
|
|
(assert (= 9876543210 (double-lots-2 0 1 2 3 4 5 6 7 8 9)))
|
2022-08-14 18:26:13 +00:00
|
|
|
(assert (= 60 (int-fn 10 20)))
|
|
|
|
(assert (= 42 (double-fn 1.5 2.5 3.5)))
|
2022-08-14 20:20:30 +00:00
|
|
|
(assert (= 21 (math/round (double-many 1 2 3 4 5 6.01))))
|
2022-08-14 18:26:13 +00:00
|
|
|
(assert (= 19 (double-lots 1 2 3 4 5 6 7 8 9 10)))
|
|
|
|
(assert (= 204 (float-fn 8 4 17)))
|
|
|
|
|
2022-06-08 14:41:09 +00:00
|
|
|
(print "Done.")
|