I've been looking a lot at Clojure recently and I've been wondering if it suits the scope of my next project. Unfortunately, it involves writing non-portable code and I need access to the Win32 API.
I stumbled upon the Java Native Access library for easily mapping native libraries with a C interface into Java. It even provides an (empty) wrapper for Kernel32.dll
as an example in the tutorial!
However, I'm a bit stumped as to translating the examples from Java to Clojure. I know I can implement interfaces and implement classes, but how can I simply extend an interface?
Thanks to the link posted by Joost, here is a minimal working example:
(import (com.sun.jna Library Native Platform Pointer))
(import (com.sun.jna.win32 StdCallLibrary))
(def K32
(gen-interface
:name Kernel32
:extends [com.sun.jna.win32.StdCallLibrary]
:methods [[GetCurrentProcess [] com.sun.jna.Pointer]]))
(defn load-native-library [name interface]
(cast interface (com.sun.jna.Native/loadLibrary name interface)))
(def k32 (load-native-library "kernel32" K32))
(println (.GetCurrentProcess k32))
Outputs #<Pointer native@0xffffffff>
, as expected!
You can only extend an interface with another interface. I'm at a loss why you'd need that functionality when accessing an existing API - even in Java. Just implement it and be done with it.
EDIT: and usually, in my experience, it's much clearer to write your interfaces in pure Java; the usual reason for defining a new Interface in clojure is when you want to add a Java-friendly interface to some clojure code anyway.
EDIT AGAIN: You can use definterface if you find that more attractive for this case. This blog post has a few examples using it for accessing JNA.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With