美文网首页
动态库文件加载(Sys)

动态库文件加载(Sys)

作者: essential_note | 来源:发表于2017-12-05 17:34 被阅读0次

    为什么记录?

    Java 可以通过System.load()与System.loadLibrary()加载动态库。

    • 问题一 :loadLibrary()加载有libname参数指定的系统库。将库映射到实际系统库的方法取决于系统。load() 以指定的文件名加载代码文件。文件名必须是绝对路径。使用opencv时,需要系统能够work every where,所以需要使用load()方法。将dll或者so文件打包到jar下,并不能直接使用,需要将文件写到临时文件中。

    • 问题二 :动态文件加载一遍之后,bundle卸载重装,但karaf并没有重新启动,到日志bundle再次运行后出现文件已经加载,再次加载出错的问题。解决办法是在bundle停止运行或者卸载的时候,将动态文件释放。

    1. 将jar包中的文件写到临时文件夹
    //BIN_LIB为JAR包中存放DLL的路径
        //getResourceAsStream以JAR中根路径为开始点
        public static String getLib(String libName, String type) throws IOException {
           
            BufferedInputStream reader = null;
            FileOutputStream writer = null;
            String systemType = System.getProperty("os.name");
            String libExtension = (systemType.toLowerCase().indexOf("win") != -1) ? ".dll" : ".so";
            String libFullName = libName + libExtension;
            String nativeTempDir = System.getProperty("java.io.tmpdir");
            File extractedLibFile = new File(nativeTempDir + File.separator + libFullName);
            InputStream in = LibUtil.class.getResourceAsStream("/libs/" + libFullName);
            if (!extractedLibFile.exists()) {
                try {
                    if (in == null)
                        in = LibUtil.class.getResourceAsStream(libFullName);
                    LibUtil.class.getResource(libFullName);
                    reader = new BufferedInputStream(in);
                    writer = new FileOutputStream(extractedLibFile);
    
                    byte[] buffer = new byte[1024];
    
                    while (reader.read(buffer) > 0) {
                        writer.write(buffer);
                        buffer = new byte[1024];
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (in != null)
                        in.close();
                    if (writer != null)
                        writer.close();
                }
            }
    
            return extractedLibFile.toString();
        }
    
    2. 卸载或释放动态链文件
    // libName:动态文件全路径
    public static synchronized void unloadNativeLibs(String libName) {
            try {
                ClassLoader classLoader = LibUtil.class.getClassLoader();
                Field field = ClassLoader.class.getDeclaredField("nativeLibraries");
                field.setAccessible(true);
                Vector<Object> libs = (Vector<Object>) field.get(classLoader);
                Iterator it = libs.iterator();
                while (it.hasNext()) {
                    Object object = it.next();
                    Field[] fs = object.getClass().getDeclaredFields();
                    for (int k = 0; k < fs.length; k++) {
                        if (fs[k].getName().equals("name")) {
                            fs[k].setAccessible(true);
                            String dllPath = fs[k].get(object).toString();
                            if (dllPath.endsWith(libName)) {
                                Method finalize = object.getClass().getDeclaredMethod("finalize");
                                finalize.setAccessible(true);
                                finalize.invoke(object);
                                list.add(libName);
                            }
                        }
                    }
                }
            } catch (Throwable th) {
                th.printStackTrace();
            }
    
        }
    

    相关文章

      网友评论

          本文标题:动态库文件加载(Sys)

          本文链接:https://www.haomeiwen.com/subject/snvcixtx.html