在 Clojure 中扩展(而不是实现)Java 接口
我最近对 Clojure 进行了很多研究,我一直想知道它是否适合我下一个项目的范围。不幸的是,它涉及编写不可移植的代码,并且我需要访问 Win32 API。
我偶然发现了 Java Native Access 库,可以轻松地将具有 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))
输出 #
,如预期!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您只能用另一个接口扩展一个接口。我不明白为什么在访问现有 API 时需要该功能 - 即使在 Java 中也是如此。只需实施它并完成即可。
编辑:根据我的经验,通常用纯 Java 编写接口会更清晰;在 clojure 中定义新接口的通常原因是当您想向某些 clojure 代码添加 Java 友好的接口时。
再次编辑:如果您发现 definterface 对于这种情况更有吸引力,则可以使用 definterface。 这篇博文有一些使用它来访问 JNA 的示例。
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.