java jna linux导入so动态库及参数对应问题

载入库文件有两个函数,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中 文件名是libname.so    调用只能是System.loadLibray(name)  函数会自动加上lib的前缀,不能带后缀so 不能带路径,默认在 java.library.path路径中查找,可以用System.getProperty(“java.library.path”) 查看, 然后将 so文件拷贝到库目录  例如 /usr/lib  /usr/lib64 等

而windows中可以带路径例如   文件名是name.dll  调用可以是 System.loadLibray(D:\\name)


备注走过的坑:

测试环境 centos7.x 64位

把so文件打入jar包中,尝试jar包内相对路径调用,失败(貌似不可行)

网上查询思路:将jar包中的动态库文件,以流的方式读到jar包以外的临时目录tmp,然后利用Sytem.load 以绝对路径加载

应该是可行的,但是本人加载库文件成功,调用函数失败,提示java.lang.UnsatisfiedLinkError  原因未知,不深究(本人在linux下带绝对路径都没成功过)

static {
		try {
			Class c = LinuxTest2.class;
			URL location = c.getProtectionDomain().getCodeSource().getLocation();
			ZipFile zf = new ZipFile(location.getPath());
			InputStream in = zf.getInputStream(zf.getEntry("lib/libWSR.so"));
			File f = File.createTempFile("JNI-", "Temp");
			FileOutputStream out = new FileOutputStream(f);
			byte [] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0)
				out.write(buf, 0, len);
			in.close();
			out.close();
			String fpath = f.getAbsolutePath();
			System.out.println("fpath:" + fpath);
			System.load(f.getAbsolutePath());
			f.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}

java 和动态库 函数参数对应表:

java jna linux导入so动态库及参数对应问题_第1张图片

另外:  动态库函数 参数传递返回值问题   例如  DWORD*   在java中对应什么类型?

动态库中头文件函数声明:  int (*ws_getCardNo)(char*,DWORD *); 

char* 类型在java中可以用 String类型来替换

DWORD* 是指针类型   java 对应的  int类型的指针   但是int是基础类型 如果需要参数返回值的话  可以用 int数组来实现,数组长度为1:

int[] b = new int[1]

java中对应的  函数声明 :public native static int ws_getCardNo(String p, int[] b);

相关:

http://www.cnblogs.com/LiuYanYGZ/p/6109516.html

https://github.com/java-native-access/jna/blob/master/www/Mappings.md

你可能感兴趣的:(java)