Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

78 lines (62 sloc) 2.167 kB

Dynamically load and use native C libs from Clojure using JNA

clojure-jna is available from clojars. Just add this to your Leiningen project.clj in the :dependencies section:

[net.n01se/clojure-jna "1.0.0"]

Usage

(require '[net.n01se.clojure-jna :as jna])
(jna/invoke Integer c/printf "My number: %d\n" 5)
; My number: 5
;=> 13

The first argument to jna-invoke is the native function's return value. The second is a symbol, in this case c/printf. The c part is the name of the library, in this case libc. The printf part is of course the name of the function to call. The rest are arguments to the native function.

That 13 is printfs return value -- I guess it's the number of bytes printed or something? Anyway, feel free to ignore it just like all C programs do.

If you're going to be calling the same function a few times, you might find it convenient to be able to call it like a regular Clojure function. Use jna-fn for that:

(doc jna/to-fn)
; -------------------------
; net.n01se.clojure-jna/to-fn
; ([return-type function-symbol])
; Macro
;   Return a Clojure function that wraps a native library function:
;    (def c-printf (jna/to-fn Integer c/printf))
;    (c-printf "My number: %d\n" 5)

(def c-printf (jna/to-fn Integer c/printf))

(c-printf "My number: %d\n" 5)
; My number: 5
;=> 13

(c-printf "My number: %d\n" 10)
; My number: 10
;=> 14

If you're going to be calling a bunch of functions from the same native lib, you might like to use jna-ns to create a Clojure namespace full of Clojure functions that wrap the native functions:

(doc jna/to-ns)
; -------------------------
; net.n01se.clojure-jna/to-ns
; ([new-ns libname fnspecs])
; Macro
;   Create a namespace full of Clojure functions that wrap functions from
;   a native library:
;   (jna/to-ns native-c c [Integer printf, Integer open, Integer close])
;   (native-c/printf "one %s two\n" "hello")

(jna/to-ns native-c c [Integer printf, Integer open, Integer close])
;=> #<Namespace native-c>

(native-c/printf "one %s two\n" "hello")
; one hello two
;=> 14

(native-c/open "README")
;=> -1
Jump to Line
Something went wrong with that request. Please try again.