使用JNI调用dll(C++)

使用JNI调用dll(C++)

  简单说下业务背景,有一个用C++写的加密算法(据说速度快),需要用JAVA来调用,并将值展示在页面。这块内容网上一搜一大堆,给个别人写的教程,非常详细,照着做,可以实现一个DEMO,传送门
  但是,这仅仅只是一个DEMO,在实际应用中,应该怎么做。

dll文件的位置

  网上说法是将调用的dll放在tomcat的bin目录下,但是在实际生产中,我们希望能将调用的dll文件放在工程里,这样,就不会对环境产生依赖。
  废话不多说,直接上代码。

public class CallThirdDll {

    public native String callThirdDll(String str, int mode);
    //这是大多数的作法,但是dll必须放在java.library.path目录
    /*static {
        //这里只需要写上你生成的那个中介dll名称即可
        System.loadLibrary("CallThirdDll");
    }*/


    public CallThirdDll()
    {
        //我这里将dll放在包下面
        String packagePath = "/com/test/common/jni/";
        //这里注意,先写第三方的dll名称,再写自己JNI产生的dll,否则,系统会提示找不到CallThirdDll.dll
        String[] filenames = new String[]{"ThirdDll.dll", "CallThirdDll.dll"};
        // 取得src下的物理路径,
        String path = CallThirdDll.class.getResource("/").getPath();
        // 将路径里的%20替换成空格
        path = path.replaceAll("%20", " ");
        System.out.println(path);

        for (String filename : filenames)
        {
            //这里的Load里在的地址是绝对地址
            System.load(path + packagePath + filename);
        }
    }
}

  这样的好处,显而易见。

  但是我却没有使用这种方式,应为生产环境是WAS,使用这种方式,找不到dll所在目录。

  于是采用下面的方式来取得dll的绝对路径,虽然可以正常打印出dll的目录,但是却报java.lang.UnsatisfiedLinkError。我郁闷了,打印出来的目录明明可以找到dll的,为什么会报这个错,如果有知情的,求告知。最终,我还是把所用的dll放在JDK的Bin目录下面,代码采用System.loadLibrary("MediumDll");的方式来调用dll的。

CallThirdDll.class.getClassLoader().getResource("/com/test/common/jni/JACVinToPin.dll").toURI().getPath();

关于32位 OR 64位的dll

  如果你的JDK是32位的,那么请使用对应的32位的dl,不要问为什么,因为不那样做,会报错。具体的异常代码,我就不贴了。
另外,在用javah来编译你的头文件时,请采用实际环境中的JDK下的javah.exe来编译。
  既然说到javah编译头文件,再多说一句,请切到你的编译出来的class的包所在的上级目录来执行javah com.test.jni.CallThirdDll。
即classes这个目录下执行javah命令。

内存泄漏

  如果说使用JNI最令人头疼的事情是什么,就是出了问题,不知道怎么排查。我调用dll可以正常返回值,但是却会导致JVM异常退出,我一开始觉得是内存溢出,我在这件事情上搞了一整天,最终发现完全不是的。

  是因为我在C++中(我不了解C++)里面进行char声明的时候,内存大小申请小了,就是下面这句话。

char* m_char = (char*)malloc(sizeof(char)*10);

好吧,至于其他要Release的地方,请自行释放。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值