2011-03-29 76 views
5

Java接口最近我一直在尋找很多的Clojure的,如果它適合我​​的下一個項目的範圍,我一直在想。不幸的是,它涉及編寫不可移植的代碼,我需要訪問Win32 API。擴展(不執行)Clojure中

我偶然發現了Java Native Access庫很容易用C接口到Java映射本地庫。它甚至提供了一個(空)包裝Kernel32.dll作爲教程中的一個例子!

不過,我有點難倒作爲翻譯從Java到Clojure的例子。我知道我可以implement interfaces and implement classes,但我怎樣才能簡單地擴展接口


感謝張貼Joost的鏈接,這裏是一個最小的工作例如:

(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)) 

輸出#<Pointer [email protected]>,如預期!

回答

5

只能擴展另一個接口的接口。我不知道爲什麼當訪問現有的API時需要該功能 - 即使是在Java中。只需實施它並完成它。

編輯:通常,在我的經驗,這是更清晰的寫在純Java的接口;在clojure中定義一個新接口的常見原因是無論如何你都想爲一些clojure代碼添加一個Java友好的接口。

再次編輯:你可以,如果你發現,對於這種情況下更具吸引力使用definterface。 This blog post有幾個使用它訪問JNA的例子。

+0

因爲JNA代碼似乎爲我生成備份類。查看發佈的鏈接中的「如何開始使用JNA」。 – 2011-03-29 22:57:42

+0

請注意'clojure.core'確實提供了在Clojure中定義Java接口的機制。請參閱http://clojuredocs.org/clojure_core/1.2.0/clojure.core/definterface。但是,它似乎並不支持擴展*現有的*接口。這似乎是一個巨大的限制。 – 2011-03-29 23:01:21

+0

@Andre:好的,我的java已經生鏽了,我不能真正看到你是否真的需要在那裏定義一個新的界面,或者你是否可以用其他方法逃脫。我正在更新我的答案。 – 2011-03-29 23:04:36