Java调用C++ DLL库文件

       对于C++编程人员, 他们一般会在C++工程中进行相关功能的封装, 形成一个独立的库文件, 这时可以将这个库文件提供给其他人员使用; 对于Java编程人员来说, Java 也是可以调用C++的DLL库的, 其操作方式也是类似, 以下描述Java中如何使用C++库(注: 这里假设库的编写人员也是自己, 库的名字为libhh.dll): 

1. 操作步骤

a. 创建Java调用C++库的程序文件, 这里假设为: com.gg.utils.DmoHello.java, 其内容为:
    package com.gg.utils;
    
    public class DmoHello {
      public native int say_hello(String user);
    }
b. 编译Java工程, 生成class文件: com.gg.utils.DmoHello.class

c. 进入目录target/classes下, 打开cmd窗口或者powershell, 输入以下命令:
    javah com.gg.utils.DmoHello
d. 生成了一个名为: com_gg_utils_DmoHello.h头文件在当前目录, 打开可以看到其部分内容为:
    JNIEXPORT jint JNICALL Java_com_gg_utils_DmoHello
    (JNIEnv *, jobject, jstring);
e. 将这个头文件拷贝到C++工程中, 并且新建一个名为com_gg_utils_DmoHello.cpp的文件, 其内容为实现d中接口的代码
    略
f. 重新编译整个库文件, 生成库libhh.dll
g. 新增com.gg.utils.DmoHello.java以下内容:
    public class DmoHello {
      // load dll library
      static {
        System.loadLibrary("kernel32");
        System.loadLibrary("libeay32");
          System.loadLibrary("libhh");
      }
      
      public native int say_hello(String user);
      
      // debug function
      public static void main(String args[]) {
          DmoHello hello = new DmoHello();
          int iRet = hello.say_hello("Tom");
          System.out.println("iRet: " + iRet);
      }
h. 编译Java工程, 我们可以在这里直接进行debug操作;

2. 可能出现的问题

  a. javah时可能出现异常错误
  Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: .\com\gg\utils\DmoHello
     at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:129)
     at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:107)
     at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:64)
     at com.sun.tools.javah.JavahTask.run(JavahTask.java:503)
     at com.sun.tools.javah.JavahTask.run(JavahTask.java:329)
     at com.sun.tools.javah.Main.main(Main.java:46)
     
     cmd或者powershell不在合适的位置上打开, 这里是在target/classes下打开并运行该命令的;
  b. 运行时出现以下错误
  Exception in thread "main" java.lang.UnsatisfiedLinkError: no libeay32 in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860)
    at java.lang.Runtime.loadLibrary0(Runtime.java:871)
    at java.lang.System.loadLibrary(System.java:1122)
    at com.gg.utils.crypto.DmoCrypto.<clinit>(DmoCrypto.java:9)
    此时是因为Java加载DLL库时找不到对应的库文件, 因此这里统一新建一个DLL库目录: d:\Lib, 将C++生成的动态链接库及相关的依赖库放入此目录中; 然后在运行时配置java参数如下:
      -Djava.library.path=D:\Lib
  c. 运行时出现
  Exception in thread "main" java.lang.UnsatisfiedLinkError: .... Can't find dependent libraries
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1934)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1850)
    at java.lang.Runtime.loadLibrary0(Runtime.java:871)
    at java.lang.System.loadLibrary(System.java:1122)
    这是没有将动态链接库及依赖的动态链接库加载进来的原因. 注意: 依赖的动态链接库也有加载进来, 并且注意依赖顺序!例如, 上面我依赖了kernel32.dll及libeay32.dll.
  d. 切记不要随意在一个目录下创建Java文件, 然后生成对应的“.h”头文件, 然后再将它引入到自己的实际工程中, 它将会出现运行出错信息, 不好排查.

3. C++动态链接库是其他人(第三方人员)编写的, 怎么办?

这时可以自己对第三方人员编写的库进行封装, 形成一个代理库, 再结合上面的步骤, 将该库引入到Java代码中来.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值