在 Clojure 中扩展(而不是实现)Java 接口

发布于 2024-10-28 07:16:24 字数 994 浏览 0 评论 0原文

我最近对 ​​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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奢华的一滴泪 2024-11-04 07:16:24

您只能用另一个接口扩展一个接口。我不明白为什么在访问现有 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文