Clojure 如何在lein项目中加载和使用本机c代码?

Clojure 如何在lein项目中加载和使用本机c代码?,clojure,native,leiningen,Clojure,Native,Leiningen,问题我无法将已编译的c类中的方法加载并调用到leiningen项目中。我的基本方法是加载一个Java类JavaWrapper.Java,它使用JNI调用本机代码wrapper.o中的一些本机方法,然后通过这个Java包装类调用这些方法。 我想象加载一个java类时会出现类加载器问题,该类从clojure项目加载本机代码,但鉴于我似乎无法直接让clojure代码在库路径上找到wrapper.o,我不确定如何处理这个问题 lein项目文件 带有main方法的clojure文件 我尝试过用四种方法对其

问题
我无法将已编译的c类中的方法加载并调用到leiningen项目中。我的基本方法是加载一个Java类JavaWrapper.Java,它使用JNI调用本机代码wrapper.o中的一些本机方法,然后通过这个Java包装类调用这些方法。
我想象加载一个java类时会出现类加载器问题,该类从clojure项目加载本机代码,但鉴于我似乎无法直接让clojure代码在库路径上找到wrapper.o,我不确定如何处理这个问题

lein项目文件

带有main方法的clojure文件
我尝试过用四种方法对其进行轻微修改,所有方法都包含在下面的代码中,并在注释中给出相应的错误

(ns lein-native-test.core
(:import (com.test JavaWrapper)))
(def -main []
;;four things I've tried and their errors
(clojure.lang.RT.load "/abs/path/to/wrapper.o") ;;could not find file /abs/path/wrapper.o_init.class or wrapper.o.clj
(clojure.lang.RT.loadLibrary "wrapper.o") ;;UnsatisfiedLinkError no wrapper.o in java library path
(JavaWrapper/load "/abs/path/to/wrapper.o") ;;UnsatisfiedLinkError com.test.JavaWrapper.setup()
(assembly-load "/abs/path/to/wrapper.o") ;;unable to resolvesymbol: assembly-load
)
带有使用JNI、JavaWrapper.Java的本机方法的Java代码

在尝试使用clojure和lein之前,我通过JavaWrapper和JNI成功地加载并使用了wrapper.o中的本机方法

可能相关:
我也无法通过加载JavaWrapper.java中的wrapper.o

System.loadLibrary("wrapper.o");
我必须使用

System.load("/absolute/path/to/wrapper.o");
工具的版本
clojure版本:1.5.1
lein版本:2.3.4
jdk:1.7
操作系统:debian7


更好地理解类加载器,尤其是一个简单的工作示例将非常有用,谢谢。

问题是由于我的方法在C头和每个源文件中的命名错误造成的。将jni与clojure一起使用的正确方法是像我所做的那样创建一个Java包装器类,并用该方法加载动态库
clojure.lang.RT.loadLibrary

由于我很难找到这方面的好例子,所以我在

错误
1) (clojure.lang.RT.load)/abs/path/to/wrapper.o);;找不到文件/abs/path/wrapper.o_init.class或wrapper.o.clj
此加载方法不适用于本机代码,它需要一个java类或clj文件

2) (clojure.lang.RT.loadLibrary“wrapper.o”);;java库路径中没有wrapper.o,未满足链接错误
Clojure在链接时无法找到库,因此出现不满意的链接错误---这是由于命名错误造成的
  • 首先,库应编译为动态共享库,即对于gcc编译器,使用-shared标志(我确实使用了-shared标志,但没有使用normal.so扩展名命名输出文件)
  • java和clojure希望本机库以一种非常具体的方式命名:libwrapper.so(或mac的.jnilib或windows的.dll,但总是带有“lib”前缀)
  • /ul>
    3) (JavaWrapper/load“/abs/path/to/wrapper.o”);;不满意的linkerror com.test.JavaWrapper.setup()
    这次错误发生在文件或库中JavaWrapper中的一个方法上,因此您知道至少它找到了该文件。在Java类中指定特定方法的未满足LinkError(如本例)总是由于Java文件中声明的本机方法与c源文件或头文件中实际存在的方法之间的命名错误造成的。
    注意名称空间“com.test”
    在c中声明jni方法时,方法名称必须遵循特定格式,

    “动态链接器根据条目的名称解析条目。本机方法名称由以下组件连接:”

    • 前缀Java_u2;
    • 损坏的完全限定类名
    • 下划线(41;分隔符
    • 损坏的方法名称
    • 对于重载的本机方法,两个下划线(_u)后跟损坏的参数签名

    在这种情况下,完整的c源方法签名将是

    void Java_com_test_setup(JNIEnv *env, jobject obj)
    

    4) (组装负载“/abs/path/to/wrapper.o”);;无法解析符号:程序集加载
    此方法也不用于加载本机代码

    System.load("/absolute/path/to/wrapper.o");
    
    void Java_com_test_setup(JNIEnv *env, jobject obj)