linux下海康SDK开发(JAVA),及库文件的导入打包

放在开头的说明:

  1. 系统环境 Ubuntu 18.04
  2. 编译工具 IDEA
  3. maven仓库管理依赖
  4. 海康摄像头 普通的枪击网络摄像头

这里只写关于开发海康视频SDK中可能会遇到的问题,要想知道怎么调用这套SDK可以直接看开发文档。

(一)、 导入jna和examples两个jar包

两个jar包
在哪找?
开发包里面LinuxJavaDemo(也就是开发实例)目录下
怎么导入,以及项目打包时怎么附加?
命令行
mvn install:install-file -DgroupId=com.sun -DartifactId=jna -Dversion=1.0 -Dpackaging=jar -Dfile= jar包的完整路径加包名,像这样 /jarlibs/jna.jar
同理install examples.jar,
mvn install:install-file -DgroupId=com.sun.jna -DartifactId=examples -Dversion=1.0.0 -Dpackaging=jar -Dfile=
之后再添加下面依赖就行了。

		<dependency>
            <groupId>com.sun</groupId>
            <artifactId>jna</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jna</groupId>
            <artifactId>examples</artifactId>
            <version>1.0</version>
        </dependency>

如果你是用maven自带的package打包,添加下面这一段可以在打包可执行jar包时把这两个jar包以及其他所有依赖涵盖。当然也可以用其他打包方式

	<build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>   
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass></mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

(二)、库文件导入,及相对路径导入

如果你只是在当前电脑用这个项目,那配置 /etc/ld.so.conf 即系统默认so文件加载路径,是一种很便捷的方式。(这个只需要在文件末尾添加库文件及库文件里面的HCNetSDKCom的绝对路径)
但是如果想要将项目打包,则需要按照以下方法(网上别的文章绝对没有的方法):
先将整个库文件放在resources目录下的lib里面,像这样
在这里插入图片描述说一下为什么放这儿。没有为什么,放其他地方也可以,只不过放在这里待会打包过后这个文件夹就会出现在jar包里面的最外层目录,很容易找到。

添加一个获取加载路径的方法:

import java.io.UnsupportedEncodingException;

/**
 * @Author ws
 * @Date 2019/03/05
 */
public class Hkpath {
    // 库文件目录
    public static String DLL_PATH;
    static {
        String path = (Hkpath.class.getResource("/").getPath()).replaceAll("%20", " ").substring(1);
        String[] p = path.split("/");
        StringBuilder pa = new StringBuilder();
        for (int i=0;i<p.length-2;i++){
            pa.append("/");
            pa.append(p[i]);
        }
        pa.append("/src/main/resources/lib");
        path = pa.toString();
        try {
            DLL_PATH = java.net.URLDecoder.decode(path, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

再修改HCNetSDK.java里面加载库文件这段代码:

//修改之前
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary( "hcnetsdk", HCNetSDK.class);
//修改之后
String path = System.getProperty("user.name").equals("你自己的用户名") ?
            Hkpath.DLL_PATH + "/libhcnetsdk.so" : System.getProperty("user.dir") + "/libhcnetsdk.so";
    HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(path, HCNetSDK.class);

目的是判断这是不是在你自己电脑上运行的,因为在其他地方运行jar包时路径是不一样的。(额刚刚想到,如果你在自己电脑上运行这个jar包这里应该会报错…
这样就可以加载到了。
什么?失败了?错误码是107加载预览组件失败?那继续下面的步骤
新建一个方法

import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.JarURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


/**
 * @Author ws
 * @Date 2019/03/11
 */
@Slf4j
public class CopyDirectory {
    String url1 = System.getProperty("user.dir");
    // 拷贝普通文件
    public void copy() throws IOException {
        //String url1 = Hkpath.SO_PATH;
        String url1 = Objects.requireNonNull(this.getClass().getClassLoader().getResource("lib")).getPath();
        String url2 = System.getProperty("user.dir");
        copy(url1, url2);
    }
    // 拷贝jar文件里面的东西
    public void copy2Natives() throws IOException {
        File hcfile = new File(url1 + File.separator + "HCNetSDKCom");
        if (!hcfile.exists()) {
            hcfile.mkdirs();
        }
         URL url = this.getClass().getClassLoader().getResource("lib");
        assert url != null;
        Path nativePath = Paths.get(url1);
        if (!Files.exists(nativePath)) {
            Files.createDirectories(nativePath);
        }
        if (url.toString().contains("!/")) {
            String jarPath = url.toString().substring(0, url.toString().indexOf("!/") + 2);
            URL jarUrl = new URL(jarPath);
            JarURLConnection jarCon = (JarURLConnection) jarUrl.openConnection();
            JarFile jarFile = jarCon.getJarFile();
            Enumeration<JarEntry> jarEntrys = jarFile.entries();
            final String filePref = "lib";
            while (jarEntrys.hasMoreElements()) {
                JarEntry entry = jarEntrys.nextElement();
                String name = entry.getName();
                if (name.startsWith(filePref) && !entry.isDirectory()) {
                    String fileName = name.substring(filePref.length());
                    Path destFile = Paths.get(nativePath.toAbsolutePath().toString() + File.separator + fileName);
                    if (!Files.exists(destFile)) {
                        //不存在就复制
                      Files.copy(Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream(name)), destFile);
                    }
                }
            }
        }
    }

    // url1源文件夹
    // url2目标文件夹
    // 文件夹最后不加斜杠
    public void copy(String url1, String url2) throws IOException {
        // 创建目标文件夹
        File file2 = new File(url2);
        if (!file2.exists()) {
            file2.mkdirs();
        }
        // 获取源文件夹当前下的文件或目录
        File[] file = (new File(url1)).listFiles();
        for (int i = 0; i < file.length; i++) {
            if (file[i].isFile()) {
                // 复制文件
                copyFile(file[i], new File(url2 + File.separator + file[i].getName()));
            }
            if (file[i].isDirectory()) {
                // 复制目录
                String targetDir = url2 + File.separator + file[i].getName();
                String sourceDir = url1 + File.separator + file[i].getName();
                copy(sourceDir, targetDir);
            }
        }
    }

    // 复制文件
    public static void copyFile(File sourceFile, File targetFile)
            throws IOException {
        // 新建文件输入流并对它进行缓冲
        FileInputStream input = new FileInputStream(sourceFile);
        BufferedInputStream inBuff = new BufferedInputStream(input);

        // 新建文件输出流并对它进行缓冲
        FileOutputStream output = new FileOutputStream(targetFile);
        BufferedOutputStream outBuff = new BufferedOutputStream(output);

        // 缓冲数组
        byte[] b = new byte[1024 * 5];
        int len;
        while ((len = inBuff.read(b)) != -1) {
            outBuff.write(b, 0, len);
        }
        // 刷新此缓冲的输出流
        outBuff.flush();

        //关闭流
        inBuff.close();
        outBuff.close();
        output.close();
        input.close();
    }
}

再在你海康初始化之前加入这样的代码

// 复制库文件
        try {
            if (System.getProperty("user.name").equals("自己的用户名")){
                (new CopyDirectory()).copy();
            }else{
                (new CopyDirectory()).copy2Natives();
            }
        } catch (IOException e) {
            log.info("Copy .so files failed.", e);
        }

如果运行jar包时提示加载类错误。也就是
java.lang.NoClassDefFoundError: Could not initialize class xxx.HCNetSDK
这个的意思就是打包之前还可以加载到 HCNetSDK.java这个类的,但是打包过后在类路径(class path 里面就加载不到HCNetSDK.class了。具体原因我也不太明白,不过既然找不到路径,那我们帮它找到不就好了。所以再添加下面一段

 System.setProperty("java.class.path",
                System.getProperty("java.class.path") +
                        System.getProperty("path.separator") +
Objects.requireNonNull(this.getClass().getClassLoader().getResource("com")).getPath());

那为什么要复制库文件出去呢?
因为如果不复制一下库文件,报错信息会提示你【.//HKNetSDKCom/libCPreview.so】加载失败了,错误码107,预览组件加载失败。而其中的 ./就是项目根目录的意思,意思就是它还是从根目录获取这个文件夹里面的so文件了。我们之前配置的对这个文件目录下的so文件没起作用,而这个复制文件就是将库文件全部复制到了它能找到的地方。这样也能避免jar包在不同地方引用的时候库文件加载路径不尽相同的问题。

如果是错误码47,用户不存在,则参考我另一篇文章
https://blog.csdn.net/qq_41789316/article/details/88391031

先这样,还有什么坑的话之后再加。毕竟我倒腾两周了已经…

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
准备工作: 1.编译JnativeCpp 2.将编译出来的libJNativeCpp.so,拷贝到/usr/lib/,同时执行chmod 555 libJNativeCpp.so 测试过程简介 1.c测试库libtest.so 环境:ubuntu10.4下 语言:c 编译库名称为:libtest.so 涉及文件:so_test.h test_a.c test_b.c test_c.c 终端执行命令:$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so 将编译得到到libtest.so拷贝到/usr/lib/,同时执行chmod 555 libtest.so 2.qt测试库libmylib.so 环境:ubuntu10.4下 语言:c 编译工具:qt Creator 编译库名称为:libmylib.so 将编译得到到libmylib.so拷贝到/usr/lib/,同时执行chmod 555 libmylib.so 3.编译环境安装 a.安装jdk 1.6 b.安装netBeans 6.8 c.创建javaApp工程 d.将JNative.jar添加到工程中 e.参考如下代码,编写后编译执行,并运行 import org.xvolks.jnative.JNative; import org.xvolks.jnative.Type; import org.xvolks.jnative.exceptions.NativeException; public class Main { public static void main(String[] args) throws NativeException, IllegalAccessException{ //纯c写到动态库 JNative clib = new JNative("libtest.so", "test_a"); //调用libtest.so下到test_a函数 clib.setRetVal(Type.STRING); //设置此函数的返回值 clib.invoke(); //函数执行 System.out.println(clib.getRetVal());//输出函数返回结果 //qt写到动态库 //以下部分使用qt编译到so,注意在函数声明前加 extern "C" //如extern "C" const char* getLocalHost(); JNative getstring = new JNative("libmylib.so", "getstring"); getstring.setRetVal(Type.STRING); getstring.invoke(); System.out.println(getstring.getRetVal()); } } 4.输出结果 this is in test_a... getstring hello .....
要在Linux环境上部署海康SDK项目(Java),需要按照以下步骤进行操作: 首先,确保Linux系统已经安装好,并且已经配置好Java开发环境。如果没有安装Java,需要首先在Linux系统上安装Java运行时环境(JRE)或者Java开发工具包(JDK)。 接下来,下载并解压海康SDKJava开发包。打开海康官方网站,并找到针对Linux系统Java SDK下载链接。下载后,使用解压软件将其解压到指定的目录下。 在解压后的目录中,会包含一些示例代码和相关的文档。仔细阅读SDK提供的文档,了解项目的需求和接口的使用方法。 根据项目需求,修改示例代码或者新建自己的代码文件。使用任意文本编辑器打开代码文件,在其中添加所需的功能和逻辑。 在Linux系统上使用终端或者命令行工具进入项目所在的目录,并编译Java代码。运行以下命令:javac YourCode.java 编译成功后,可以运行Java程序。在终端或者命令行中输入以下命令:java YourCode 如果项目中需要依赖其他的库或者jar文件,可以将其放置在指定的目录下,并在编译和运行时加上相应的参数。 在部署过程中,需要注意一些常见的问题和错误。例如,缺少依赖库、权限问题、代码错误等。可以通过查看错误信息、日志文件等方式进行排查和解决。 最后,测试项目的功能和性能。确保项目在Linux环境下能够正常运行,并满足预期的需求。 总结起来,部署海康SDK项目(Java)到Linux环境中需要下载、解压、编译、运行代码,并解决可能遇到的问题和错误。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值