使用JNI一些值得注意的地方

最近要使用JNI来做一些程序,花了一下午的时间,终于搞定,记录一下步骤,方便以后使用。

 

安装gcc等编译工具,我用的cygwin。。。真的很麻烦,不过终于搞定了。这个网上资料很多。

 

写natvie类,这个也没什么。

 

生成头文件,javah,也很简单,注意要用全路径,也就是包路径+类名,如java.lang.String

 

导入头文件和java的include里的所有文件也没问题。

 

编写c文件。

 

正戏来了,在编译成dll文件的时候,出现了十分令人郁闷的问题,java.lang.UnsatisfiedLinkError;hellonative.Main.nativePrint()V。这个说明dll文件找到了,但是方法找不到,经过查找,原来是编译的时候参数没有设置清楚,正确的应该是

-mno-cygwin -Wl,--kill-at -shared -m32

其中-mno-cygwin是说脱离cygwin环境,-m32是编译成32位,这两个一般情况下是可选的。--kill-at是关键,这个是说生成的文件中不要有@,必须要有该参数,否这就抛上面的异常。

 

另如果想把dll文件打包进jar中,可以用到下面的代码来做:

    static {
        try {
            InputStream inputStream = Main.class.getResourceAsStream("HelloNative.dll");
//            System.out.println(inputStream);
            File temporaryDll = File.createTempFile("HelloNative", ".dll");
//            System.out.println(temporaryDll.getAbsolutePath());
            FileOutputStream outputStream = new FileOutputStream(temporaryDll);
            byte[] array = new byte[8192];
            int i = -1;
            while ((i = inputStream.read(array)) != -1) {
                outputStream.write(array, 0, i);
            }
            outputStream.close();
            temporaryDll.deleteOnExit();
            System.out.println(temporaryDll.getAbsolutePath());
            System.load(temporaryDll.getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 把文件复制进临时文件夹调用,因为system.load不能访问jar文件。

你可能感兴趣的:(C++,c,jni,gcc,C#)