开发者

Extending (not implementing) Java interfaces in Clojure

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 Ker开发者_开发问答nel32
      :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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜