栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

jna实现java链接动态库所形成的jar包,jar中的动态库动态加载的方法(也就是调用时只提供jar包即可运行)。jar包中拥有动态库依赖库的情况。

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

jna实现java链接动态库所形成的jar包,jar中的动态库动态加载的方法(也就是调用时只提供jar包即可运行)。jar包中拥有动态库依赖库的情况。

首先,实现调用jar包,动态的加载动态库(也就是调用时只提供jar包即可运行)。

下面代码中是调用动态库的方法,可以写在新建的类中。这里我新建了LoadDLL类,类中写了loadDll加载动态库的函数,可见传参为libName:动态库名(不带后缀),className:传入动态库时的类名。

这里面最关键的是getResourceAsStream函数(可以去搜索一下这个函数,理解意思)。

以下代码不需要改动,通过传参来控制函数。

import com.sun.jna.Native;

import java.io.*;

public class LoadDll
{
public synchronized static Object loadDll(String libName, Class className) {
        String systemType = System.getProperty("os.name");
//        String libExtension = (systemType.toLowerCase().indexOf("win") != -1) ? ".dll" : ".so";
        String libExtension = (systemType.toLowerCase().contains("win")) ? ".dll" : ".so";
        String libFullName = libName + libExtension;
        String nativeTempDir = System.getProperty("java.io.tmpdir");
        InputStream in = null;
        BufferedInputStream reader = null;
        FileOutputStream writer = null;
        File extractedLibFile = new File(nativeTempDir + File.separator
                + libFullName);
        if (!extractedLibFile.exists()) {
            try {
                in = className.getResourceAsStream("/" + libFullName);
                if (in == null)
                    in = className.getResourceAsStream(libFullName);
                reader = new BufferedInputStream(in);
                writer = new FileOutputStream(extractedLibFile);
                byte[] buffer = new byte[1024*1024];
                while (reader.read(buffer) > 0) {
                    writer.write(buffer);
                    buffer = new byte[1024*1024];
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (in != null)
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                if (writer != null)
                    try {
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
        }
        String dllName;
//        if (systemType.toLowerCase().indexOf("win") != -1) {
        if (systemType.toLowerCase().contains("win")) {
            dllName = extractedLibFile.toString().replace(".dll", "");
        } else {
            dllName = extractedLibFile.toString().replace(".so", "");
        }
        return Native.loadLibrary(dllName,className);
    }
}

 此处借鉴:解决JNA动态加载jar中dll问题_weixin_34289454的博客-CSDN博客

然后就是这个函数的使用,这个函数相当于代替了以前jna上来直接使用的 Native.load(xxx,xxx.class)

!这里动态库是放在工作目录下,此处动态库直接放在src目录下

import com.sun.jna.Native;

public  class ALSODTxInAPI {
    
    public interface libalso extends Library {
        //此处使用了上面代码段中定义的函数,传入了参数:动态库和此处类名
        libalso alsoDtxAlgorithm = (libalso) LoadDll.loadDll("libalso_dtx_in", libalso.class);
        
        //下面是jna调用动态库的函数,不变。
        String GetIEPScore(String readFileJson_root, String readFileTimeJson_root, String readFileITJson_root, String readFileLevelJson_root);

        String GetAllStusInitScore(String json_w_iep_socre11, String readAccIepJson_root, String readAccStuJson_root, String readAccInfoJson_root);

        String GetoneStuLevelScore(String json_w_iep_socre11, String json_map_all_stu_unit_score11, String readFileITJson_root, String readFileJson_root, String readFileTimeJson_root);

    }
}

那么按道理说此处,就结束了。形成jar包,那么只需丢一个jar包,即可调用jar包中的函数,而不需要把动态库移来移去。只需要jar包的世界成立了!

但是我却报了错, %1 不是有效的 Win32 应用程序啥的,然后还有win32-x86-64/一堆路径/动态库名啥的,然后一堆一堆。

        不是win32有效程序,有可能需要看jdk,动态库什么什么的位数,要统一

但这里不是,位数的问题。而是我的动态库缺乏依赖库! 我一个有两个动态库,一个依赖另一个。而我们刚刚通过jna只是加载了一个动态库。

        也就是说现在的问题变成了如何让jna加载两个动态库,两个动态库还需要有依赖关系。

让jna加载两个动态库的代码!其中libalso_dtx_in.dll依赖与jsoncpp.dll动态库

import com.sun.jna.Library;
import com.sun.jna.Native;


public class ALSODTxInAPI {
    public interface Jsoncpp extends Library {

        Jsoncpp INSTANCE = (Jsoncpp) LoadDll.loadDll("jsoncpp", Jsoncpp.class);

    }

    public interface libalso extends Library {
        Jsoncpp JSonCPP = Jsoncpp.INSTANCE;

        libalso alsoDtxAlgorithm = (libalso) LoadDll.loadDll("libalso_dtx_in", libalso.class);

        //以下是我自己动态库中的函数
        String GetIEPScore(String readFileJson_root, String readFileTimeJson_root, String readFileITJson_root, String readFileLevelJson_root);

        String GetAllStusInitScore(String json_w_iep_socre11, String readAccIepJson_root, String readAccStuJson_root, String readAccInfoJson_root);

        String GetoneStuLevelScore(String json_w_iep_socre11, String json_map_all_stu_unit_score11, String readFileITJson_root, String readFileJson_root, String readFileTimeJson_root);

    }
}

如此这般就没有任何错误,只用提供一个jar包即可。

由以上代码段,调用函数的代码(参考第二个代码段,调用函数)

ALSODTxInAPI.libalso.alsoDtxAlgorithm.GetAllStusInitScore(json_w_iep_socre11,readAccIepJson_root,readAccStuJson_root,readAccInfoJson_root);

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703692.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号