Расширение (не реализация) интерфейсов Java в Clojure - PullRequest
5 голосов
/ 30 марта 2011

В последнее время я много смотрел на Clojure, и мне было интересно, подходит ли он для моего следующего проекта. К сожалению, это связано с написанием непереносимого кода, и мне нужен доступ к Win32 API.

Я наткнулся на библиотеку Native Access Java для простого отображения собственных библиотек с интерфейсом C в Java. Он даже предоставляет (пустую) оболочку для Kernel32.dll в качестве примера в руководстве!

Однако я немного озадачен переводом примеров с Java на Clojure. Я знаю, что могу реализовать интерфейсы и реализовать классы , но как мне просто расширить интерфейс ?


Благодаря ссылке, размещенной 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 native@0xffffffff>, как и ожидалось!

1 Ответ

5 голосов
/ 30 марта 2011

Вы можете расширить интерфейс только с другим интерфейсом. Я в недоумении, зачем вам эта функциональность нужна при доступе к существующему API - даже в Java. Просто осуществите это и покончите с этим.

РЕДАКТИРОВАТЬ: и обычно, по моему опыту, гораздо понятнее написать ваши интерфейсы на чистой Java; Обычная причина для определения нового интерфейса в clojure - это когда вы все равно хотите добавить дружественный к Java интерфейс в некоторый код clojure.

ВНОВЬ РЕДАКТИРОВАТЬ: Вы можете использовать definterface, если вы находите это более привлекательным для этого случая. В этом блоге есть несколько примеров использования его для доступа к JNA.

...