Skip to content

Instantly share code, notes, and snippets.

@zcaudate
Last active June 23, 2020 17:22
Show Gist options
  • Save zcaudate/f05001f6cc38a8a02f9b0892bab02a82 to your computer and use it in GitHub Desktop.
Save zcaudate/f05001f6cc38a8a02f9b0892bab02a82 to your computer and use it in GitHub Desktop.
jnr-ffi example
(ns libc
(:require [jise.core :refer [defclass]])
(:import (jnr.ffi LibraryLoader
Pointer
Struct
Struct$SignedLong
Struct$time_t)
(jnr.ffi.annotations Out Transient)))
;;
;;
;; Minimum Working Example for JNR/Clojure
;;
;;
(definterface LibCPrint
(^int puts [^String x])
(^int fflush [^jnr.ffi.Pointer stream]))
(def +cprint+ (-> (LibraryLoader/create LibCPrint)
(.load "c")))
;; This prints "Hello World" on a newline when run
(comment
(do (.puts +cprint+ "Hello World")
(.fflush +cprint+ nil))
(jnr.ffi.Runtime/getRuntime +cprint+)
)
;;
;; Clojure Port of Gettimeofday
;;
;; JNR Reference: https://github.com/jnr/jnr-ffi-examples/blob/master/gettimeofday/src/main/java/gettimeofday/Gettimeofday.java
;; Clojure Reference: https://github.com/lvh/caesium/blob/master/src/caesium/binding.clj
;;
;; DOES NOT COMPILE
^{:public true}
(defclass Timeval [jnr.ffi.Struct]
^:public
(def ^Struct$time_t tv_sec)
^:public
(def ^Struct$SignedLong tv_usec)
^:public
(defm Timeval [^jnr.ffi.Runtime rt]
(super rt)
(set! (.tv_sec this) (Struct$time_t.))
(set! (.tv_usec this) (Struct$SignedLong.))))
(definterface LibCTimeOfDay
(^int gettimeofday [^libc.Timeval ^{jnr.ffi.annotations.Out {}
jnr.ffi.annotations.Transient {}} tv
^jnr.ffi.Pointer stream]))
(def +ctimeofday+
(-> (LibraryLoader/create LibCTimeOfDay)
(.load "c")))
(comment
(def +rt+ (jnr.ffi.Runtime/getRuntime +ctimeofday+))
(def +tv+ (TimeVal. +rt+))
;; Prints out Time of day
(do (.gettimeofday +tv+)
(println (format "sec: %d, usec: %d"
(.. +tv+ -tv_sec get)
(.. +tv+ -tv_usec get)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment