请在2024 Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以了解更多关于这个问题的信息。

0
Java互操作

大家好,

我想从Clojure调用C库中的原生函数,而不必编写Java代码。

(defproject mypkg
	:dependencies [[org.clojure/clojure "1.10.1"]
				   [com.github.jnr/jnr-ffi "2.2.0"]])

基于这里的示例这里的示例,Java包装器可能是这样的

package blahblah;

public class BlahNative {
	private static int[] intDummy;
	private static double[] doubleDummy;

	public BlahNative() {
	}

	public static native void native_a(char var0, char var1, int var2, int var3, int var4, double[] var7, int var8, int var9);

	public static native void native_b(char var0, char var1, int var2, int var3, int var4, double[] var7, int var8, int var9);

	static {
		lib = LibraryLoader
            .create(LibSodium.class)
            .search("/usr/local/lib")
            .search("/opt/local/lib")
            .search("/usr/lib")
            .search("/lib")
            .load(LIBRARY_NAME);
        initializeLibrary(lib);
    }
}

我假设我的Clojure命名空间应该使用gen-class功能来实现Java类。

(ns mypkg.native
	(:import [jnr.ffi LibraryLoader])
	(:import [jnr.ffi.annotations IgnoreError])
	(:import [jnr.ffi.provider FFIProvider])
    (:gen-class))

那么:

  1. 如何在Clojure中编写原生方法?换句话说,在使用Clojure的Java互操作功能时,我是否需要指定方法类型(如native)?

  2. 在加载了原生库之后,我不知道如何访问库中的C函数。我该如何做?

  3. 为了避免为每个C函数的每个Clojure包装器函数重新加载库,我能否编写一个像这样的方法

    (defn lib (. LibraryLoader load LIBRARY_NAME))

然后在此库中访问原生函数?

我不是C或Java专家,所以任何指导都将非常感激。

感谢。

2 答案

+1

选定
 
最佳答案

1. Clojure 不支持所有的 Java 类关键字。创建一个 Java 类,构建一个 .class 文件,并从 Clojure 中使用它。

2. 从 Clojure 可以调用任何 Java 方法。只需查看你库的 javadocs,或使用 clojure.reflect/reflect 来了解你对象的所有方法。

3. 当然(?!)

  • 我不是C或Java专家,所以任何指导都将非常感激。

我建议你先退一步,先学习“如何在 Java 中调用 C 函数”,一旦你弄懂了,再尝试将你的代码从 Java 移植到 Clojure 中。

by
感谢 Enzzo

您的回答进一步证实了我的看法,那就是在不编写 Java 包装器的情况下,无法将本机 C 语言库与 Clojure 进行接口。

我在思考这个问题至少两周后发布了这个问题,所以我相当自信,我可以从 Java 调用足够的 C 函数来为我的 Clojure 项目编写包装器 :)
+1
by

您明确要求一个基于 JNR-FFI 的解决方案,但也有一些不基于 JNR-FFI 的 Clojure 库可以实现您想要的功能。请查看

https://github.com/Chouser/clojure-jna

或者

https://github.com/techascent/tech.jna

两者都可以通过使用底层 JNA 来实现您想要的(不是使用 JNR-FFR)。

by
感谢 Didier。有选择总是好的 :)
...