加载海康摄像枪SDK dll

  • 方案一:
    官方的方法,直接将SDK的所有dll相关文件,放置到项目根目录下,编译之后位于target/classes目录下;
    如果使用junit,需要手动将dll相关文件,拷贝到target/test-classes目录下;否则加载异常;
    spring boot项目下测试,打成jar包之后,所有资源文件打包到jar文件内的classes目录下,仍然加载不到
// HCNetSDK即: HCNetSDK.dll;一般不写.dll,以免部署Linux环境,还需要修改代码
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("HCNetSDK", HCNetSDK.class); 
PlayCtrl INSTANCE = (PlayCtrl) Native.loadLibrary("PlayCtrl", PlayCtrl.class);
<dependency>
	<groupId>com.sun.jna</groupId>
	<artifactId>jna</artifactId>
	<version>3.0.9</version>
</dependency>
  • 方案二:
import java.io.UnsupportedEncodingException;
public class ClientDemo {
    public static String DLL_PATH;
    static {
        String root = ClientDemo.class.getResource("/").getPath();
        if (root.startsWith("file:/")) {  // jar包中获取到的路径
            DLL_PATH = "";
        } else {  // 实际开发中获取到的路径不带 file:/
            root = root.replaceAll("%20", " ").substring(1);
            try {
                DLL_PATH = java.net.URLDecoder.decode(root, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }
}
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(ClientDemo.DLL_PATH + "Win32\\HCNetSDK", HCNetSDK.class);
<dependency>
	<groupId>com.sun.jna</groupId>
	<artifactId>jna</artifactId>
	<version>3.0.9</version>
</dependency>
  • 方案三:
    项目根目录下,创建lib目录,所有dll相关文件拷贝到该目录下即可;
    打成jar包之后,lib目录跟jar文件在同一个文件夹下即可; spring boot 项目测试可行
public interface HCNetSDK extends StdCallLibrary {
	HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("lib\\HCNetSDK", HCNetSDK.class);
	// 可调用接口
	int  NET_DVR_GetSDKVersion();
	// 回调接口
	public static interface FPostMessageCallBack extends StdCallCallback {
        public int invoke(int dwType, int lIndex);
    }
	// 结构体
	public static class NET_POS_PARAM extends Structure{
        public short wLeft;
        public short wTop;
        public short wRight;
        public short wBottom;
    }
}

加载华为摄像枪SDK dll

由于有 W32APIOptions.FUNCTION_MAPPER 参数,加载的是32位的dll;对应的也只能使用32位的jdk
项目根目录下,创建lib目录,所有dll相关文件拷贝到该目录下即可;
打成jar包之后,lib目录跟jar文件在同一个文件夹下即可; spring boot 项目测试可行

public interface JNAFuc extends StdCallLibrary {
	public static JNAFuc INSTANCE = Native.load("lib\\HWPuSDK", JNAFuc.class, new HashMap<String, Object>() {
		private static final long serialVersionUID = 1L;
		{
			put("function-mapper", W32APIOptions.FUNCTION_MAPPER);
		}
	});
	// 可用接口
	public long IVS_PU_GetVersion(LongByReference plVersion);
	// 回调函数接口
	public interface FedReaplayCallbackWithMetaFrame extends StdCallCallback {
        public Pointer invoke(Pointer szBuffer, ULONG lSize, Pointer pUsrData);
    }
	// 结构体
	......
}
<dependency>
	<groupId>net.java.dev.jna</groupId>
	<artifactId>jna</artifactId>
	<version>5.0.0</version>
</dependency>
<dependency>
	<groupId>net.java.dev.jna</groupId>
	<artifactId>jna-platform</artifactId>
	<version>5.0.0</version>
</dependency>

加载opencv dll

使用的是jni方式加载

static {
	java.lang.System.loadLibrary(Core.NATIVE_LIBRARY_NAME);  // Core.NATIVE_LIBRARY_NAME="opencv_java401"
}
public class Imgcodecs {
	public static Mat imread(String filename, int flags){
        Mat retVal = new Mat(imread_0(filename, flags));
        return retVal;
    }
	private static native long imread_0(String filename, int flags);
}

JNI跟JNA的区别

百度结果

解决java调dll报Unable to load library的错误可以尝试以下方法:

  • 载入库文件有两个函数,System.load 和 System.loadLibrary。
  • 当使用System.load时,需要输入文件的全路径,例如:System.load(“/tmp/test.so”);
  • 当使用System.loadlibrary时是在系统的library 的目录中需找复合条件的库文件,可以使用-Djava.library.path=[path]参数,来指定Java程序加载库文件的路径,或者将库文件(.so,.dll)复制到include的默认路径,Linux一般是/usr/lib目录下,当然你可以编辑/etc/ld.so.conf.d/下的文件,设定自己的库查找路径ldconfig -v|grep xxx看看有没有你的动态库。
  • Linux还要注意,使用System.loadLibrary(name)方法其中参数内容与Windows有区别,Linux中的的库文件名为libname.so,Windows为name.dll。
  • 在Windows中尽量使用Windows的C/C++编译器生成dll文件,否则会出现问题。

其他方法:

1、必须确保设定的路径下有需要加载的dll文件;
2、jar是64位,则dll文件必须也是64位,如果jar是32位,则dll文件必须也是32位;
3、PlayCtrl INSTANCE = (PlayCtrl) Native.loadLibrary("soft\\hikvision\\PlayCtrl", PlayCtrl.class);
其中"soft\\hikvision\\PlayCtrl"可以是绝对路径,也可以是相对路径,但是,路径分隔符必须是\,不能是/
4、在Tomcat中调用时,可将dll文件放在src目录下,编译后会自动存放到WebRoot\WEB-INF\classes\路径下,在调用时可使用如下方法:
String path = HCNetSDK.class.getResource("/").getPath()+"HCNetSDK.dll";
// 如何tomcat路径中有空格,加上这句path=path.replaceAll("%20", " ");
// 上述方法获取的path最前边第一个字符是/,如【/d:/RTSMS_x64/Servent/HCNetSDKCom/HCNetSDK.dll】
所以我用了以下方法
String path = (HCNetSDK.class.getResource("/").getPath()+"HCNetSDK.dll").replaceAll("%20", " ").substring(1).replace("/", "\\");
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(path,HCNetSDK.class);