首先,实现调用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);



