JNI使用本机方法

时间:2014-04-04 09:11:24

标签: java dll methods java-native-interface

我正在开发一个项目,需要从dll文件中调用一些方法。 这两个dll是

  • EasySign.dll
  • EasySignJNI

EasySignJNI取决于EasySign。

我写了这个类来加载EasySignJNI,如下所示:

package easysign;


class EasySign {

    EasySign(){}

    public native String EasyHashFile(String filename);
    public native int EasySign(String pkcs11_driver,String pin, int type, String file_data, int out_format, String signed_file, String cert_out, int cert_format);
    public native int EasyVerify(String cert_user, String file_data, String signed_file, String crl_file, String ca_file, String out_document);


    static {
        System.loadLibrary("EasySignJNI");
    }
 }

现在我将从我的主要方法中调用这些方法:

public class Test {
   public static void main(String[] args) throws IOException{
          EasySign es = new EasySign();
          System.out.println("EasyHashFile : " + es.EasyHashFile("test.txt"));
        }
    }

我必须在-Djava.library.path中指定什么?只有我的EasySignJNI.dll所在的路径?可以用这种方式调用本机方法吗? 我正在使用NetBeans来完成。

编辑: 我注意到提供给我的第三方dll(特别是JNI dll)定义了没有任何包的方法名称,所以我不得不把加载dll的类放在默认包中。有没有办法只更改dll方法名称,包括我自己的包名?

编辑2: 我的意思是EasySign.dll和EasySignJNI.dll都按原样提供给我,我无法修改它们(我没有源代码)。 EasySignJNI是JNI部分,但检查它我注意到方法符号的格式为:_java_EasySign_MethodName。当我从我的Easysign类加载Java中的dll(这个类必须位于“mypackage”包中)时,我收到了jni不满意的链接错误,因为如果我理解正确的话,我正在调用“_java_mypackage_EasySign_MethodName”方法,即符号是与dll不同。因此,使其工作的唯一方法是重写JNI部分并构建它以获得JNI方法的正确标记吗?

1 个答案:

答案 0 :(得分:0)

  

我必须在-Djava.library.path中指定什么?只有我的EasySignJNI.dll所在的路径?

正确,操作系统将为您找到依赖的EasySign.dll,只要它可用于操作系统预期的位置。

  

可以这种方式调用本机方法吗?我正在使用NetBeans来完成。

我通读了你的编辑,你成功地失去了我。你指的是什么默认包? (请记住,我们都不知道EasySign.dll是什么)所以,我将提供一些关于我如何做你最初描述的信息,希望它会有所帮助。

如果您有src,首先编译EasySign。不要构建DLL或共享对象,而是构建静态库。如果您没有EasySign的src代码或预构建的静态库,您将无法使用该DLL并继续下一步。

现在您已准备好编译jni部分。您的所有JNI C代码基本上应该将Java输入/输出转换为其JVM / Native类型,并调用DLL库中的相应函数。您希望保留此层,并尽可能简洁和简单,因为它非常难以调试。您的C ++包名称在这里并不重要,您可以使用您想要的Java类包名称。您应该能够编译JNI代码,最好是到EasySign.dll文件的静态链接,这样您就不必担心分发它了。如果必须动态链接,请确保将EasySign.dll安装到DLL PATH / LDPATH上的位置,因为操作系统需要在JVM加载JNI DLL后立即定位并加载该文件

此时你应该能够在你的JNI DLL的路径上指向-Djava.library.path,并且一切都应该有用。