.jar怎么使用 jnative

2014-05-25 22:51:05 testcs_dn 阅读数 46270

JAVA调用动态链接库DLL的方法有:JNI(Java Native Interface),JInvoke,JNative(Java to native interface),JNI是JAVA自身提供的方法;JInvoke从何而来不得而知,好像还需要注册付费的,64位的JDK、JIR环境下运行不了,在VMware下安装的WindowsXP下同样有问题;JNative是开源的,但相关资料文档也特别的少,好像已经停止更新了。JNative源码地址:http://jnative.cvs.sourceforge.net/viewvc/jnative/,jar包下载地址:http://sourceforge.net/projects/jnative/files/jnative/。

开发环境:myeclipse-10.7-offline-installer-windows

文件》新建》JAVA项目:


输入项目名称,单击“Finish”:


单击鼠标右键》新建》类:


输入包名,类名,勾选“public static void main(String[] args)”,单击“Finish”:


打开项目文件目录:


将要调用的DLL文件“EhfscliaxDll.dll”复制到此目录下,该DLL的代码请参考:VS2010编写动态链接库DLL及单元测试用例,调用DLL测试正确性

新建“lib”文件夹,将JNative.jar复制到此目录下:


配置编译目录:


单击“Add External JARs”添加jar包,下图为已经添加过的:


Helper类代码:

package com.ehfscliax;

import org.xvolks.jnative.JNative;  
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;  
import org.xvolks.jnative.pointers.Pointer;

public class Helper {
	/**
	 * @param args
	 * @throws NativeException 
	 */
	public static void main(String[] args) throws NativeException {
		
		JNative.setLoggingEnabled(true);
		try {
			JNative getUrl = new JNative("EhfscliaxDll.dll", "getUrl"); //创建 getUrl 方法的JNative对象
			getUrl.setRetVal(Type.STRING); //设置返回值类型为:String
			getUrl.setParameter(0, "127.0.0.1"); //按顺序设置方法需要的参数值
			getUrl.setParameter(1, 10087);
			getUrl.setParameter(2, 123);
			getUrl.invoke(); //调用方法
			System.out.println(getUrl.getRetVal()); //输出返回值
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		
		try {
			JNative getPlayUrl = new JNative("EhfscliaxDll.dll", "getPlayUrl");
			getPlayUrl.setRetVal(Type.INT); //此方法在DLL中定义的返回值类型为:const wchar_t*,如果设置返回值类型为:String,则只能获取到返回值的第一个字符
			
			String mgrIp = "127.0.0.1";
			Pointer ptr = Pointer.createPointerFromString(mgrIp);
			
			getPlayUrl.setParameter(0, ptr);
			getPlayUrl.setParameter(1, 10087);
			getPlayUrl.setParameter(2, 123);
			getPlayUrl.invoke();
			//个人理解getRetValAsInt是获取返回值的指针地址,getUnicodeMemoryAsString方法从指针地址的内存中读取字符串
			String url = JNative.getUnicodeMemoryAsString(getPlayUrl.getRetValAsInt());
			System.out.println(url);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}
执行结果:

2014-5-25 22:48:46, [DEBUG] [org.xvolks.jnative.JNative] [loadLibrary]: Successfully loaded library 'EhfscliaxDll.dll', functionName = getUrl: hModule = 268435456
http://中文127.0.0.1:10087
2014-5-25 22:48:46, [DEBUG] [org.xvolks.jnative.pointers.memory.MemoryBlockFactory] [setPreferredMemoryType]: Using org.xvolks.jnative.pointers.memory.HeapMemoryBlock memory reservation strategy
http://-�17001:10087
2014-5-25 22:48:46, [DEBUG] [org.xvolks.jnative.JNative] [unLoad]: Unloading native library 'EhfscliaxDll.dll'
getUrl方法的返回值类型为:const char*,结果是正常的,getPlayUrl的返回值类型为:const wchar_t*,虽然通过getUnicodeMemoryAsString读取到了返回值,不是第一个字符,但中文乱码的问题一直没能解决。

本学习项目源码下载:http://download.csdn.net/detail/testcs_dn/7400203

你可能会遇到以下问题:

 

如何捕获 System.loadLibrary 产生的异常?


2013-11-20 21:51:38 qqqwwwqw 阅读数 10495


通过jnative调用dll 。
下截JNative组件


jnative.sourceforge.net/ 到这里下载JNative开源项目,我下载的是1.3.2
解压JNative.zip


获得三个文件,分别是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar 。 
JNativeCpp.dll Windows下用的,拷贝到windows / system32目录下;
libJNativeCpp.so Linux下的,拷贝到系统目录下;
JNative.jar 这是一个扩展包,导入工程LIB中或将其拷贝到jdk\jre\lib\ext 下,系统会自动加载。


在源代码运行的过程中,Exception in thread "main" java.lang.IllegalStateException: JNative library not loaded, sorry !
如果报这个异常把TestJndi.dll和JNativeCpp.dll放到拷贝到java.library.path下,比如jdk的bin目录下。
在TestJndi.dll的名字叫sayHello,如果在test1方法中用这个名字,会报找不到sayHello方法,用dll查看器,下载地址:
http://www.onlinedown.net/softdown/17471_2.htm,查看正确的函数名字,为_Java_navtiveinterface_JndiTest_sayHello@8。
TestJndi.dll参考http://blog.csdn.net/qqqwwwqw/article/details/16810715


    源代码:
package navtiveinterface;


import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;


public class JNativeTest {
   private static void test1() throws Exception{
  JNative n = null;
 try{
 n = new JNative("TestJndi.dll", "_Java_navtiveinterface_JndiTest_sayHello@8");
 n.setRetVal(Type.VOID);
 n.setParameter(0,Type.STRING," xuhong ");
 n.invoke();
 }finally{
 if(n != null)
try {
n.dispose();
} catch (NativeException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
 }
   }
   private static void test2() throws Exception{
  JNative n = null;
 try{
 n = new JNative("user32.dll", "MessageBoxA");
 n.setParameter(0,Type.INT,"0");
 n.setParameter(1,Type.STRING,"jnative create window");
 n.setParameter(2,Type.STRING,"think jnative");
 n.setParameter(3,Type.INT,"0");
 n.invoke();
 }finally{
 if(n != null)
try {
n.dispose();
} catch (NativeException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
 }
   }
   public static void main(String[] args) throws Exception{
 test1();
 test2();
   }
}
2015-03-26 18:11:54 a137268431 阅读数 5142

下载地址:

JNative_1.4RC2_src.zip : http://jaist.dl.sourceforge.net/sourceforge/jnative/JNative_1.4RC2_src.zip

JNative.jar : http://nchc.dl.sourceforge.net/sourceforge/jnative/JNative.jar

如果以上版本不能完成下载,说明版本有可能更新,请从以下地址中下载:

Resource URL: http://jnative.sourceforge.net/ 

Source Code: http://sourceforge.net/projects/jnative 

Detailed Review: http://jnative.free.fr 

JavaDOC: http://jnative.free.fr/docs/

JNative相对于其它同类开源组件的优点:

1.容易使用

2.对数据类型的处理做的出色

3.支持CallBack

下面以一个小Demo来学习一下JNative:

1.理解文件用途

JNative_1.4RC2_src.zip是JNative源代码的压缩包把它解压后从中找到libJNativeCpp.so和JNativeCpp.dll两个文件.JNativeCpp.dll应用在Windows平台下.把它放在c:\windows\system32目录下.libJNativeCpp.so应用在Linux平台下.放在哪个目录,这个我不知道.

把JNative.jar加入到所需的工程中.

把要调用的dll文件也放在c:\windows\system32目录下, 这个目录存在一个文件,

2.测试类

 

Java代码  收藏代码
  1. package sms;  
  2.   
  3. import org.xvolks.jnative.JNative;  
  4. import org.xvolks.jnative.exceptions.NativeException;  
  5. import org.xvolks.jnative.pointers.Pointer;  
  6. import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;  
  7.   
  8. public class SystemTime extends org.xvolks.jnative.util.Kernel32.SystemTime {  
  9.         public short wYear;  
  10.         public short wMonth;  
  11.         public short wDayOfWeek;  
  12.         public short wDay;  
  13.         public short wHour;  
  14.         public short wMinute;  
  15.         public short wSecond;  
  16.         public short wMilliseconds;  
  17.        /** 
  18.         * 分配内存,并返回指针 
  19.         */  
  20.        public Pointer createPointer() throws NativeException {  
  21.            pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(getSizeOf()));  
  22.            return pointer;  
  23.        }  
  24.   
  25.        /** 
  26.         * 内存大小 
  27.         */  
  28.        public int getSizeOf(){  
  29.            return 8 * 2;  
  30.        }  
  31.   
  32.        /** 
  33.         * 获取通过内存指针解析出结果 
  34.         */  
  35.        public SystemTime getValueFromPointer() throws NativeException {  
  36.            wYear = getNextShort();  
  37.            wMonth = getNextShort();  
  38.            wDayOfWeek = getNextShort();  
  39.            wDay = getNextShort();  
  40.            wHour = getNextShort();  
  41.            wMinute = getNextShort();  
  42.            wSecond = getNextShort();  
  43.            wMilliseconds = getNextShort();  
  44.            return this;  
  45.        }  
  46.   
  47.        public SystemTime() throws NativeException{  
  48.            super();  
  49.            createPointer();  
  50.        }  
  51.   
  52.        public String toString(){  
  53.            return wYear + "/" + wMonth + "/" + wDay + " at + " + wHour + ":" + wMinute + ":" + wSecond + ":" + wMilliseconds;  
  54.        }  
  55.   
  56.        public static SystemTime GetSystemTime() throws NativeException, IllegalAccessException {  
  57.            // 创建对象  
  58.            JNative nGetSystemTime = new JNative("Kernel32.dll""GetSystemTime");  
  59.              
  60.            //GetSystemTime  是dll中的方法  
  61.            SystemTime systemTime = new SystemTime();  
  62.            // 设置参数  
  63.            nGetSystemTime.setParameter(0, systemTime.getPointer());  
  64.            //执行方法  
  65.            nGetSystemTime.invoke();  
  66.            // 解析结构指针内容  
  67.            return systemTime.getValueFromPointer();  
  68.        }  
  69.   
  70.        public static void main(String[] args) throws NativeException, IllegalAccessException{  
  71.            System.err.println(GetSystemTime());  
  72.                
  73.        }  
  74.         
  75. }  

 

2017-06-21 12:05:50 qq_27099139 阅读数 1196

这两天正在研究Java与底层C/C++的交互问题,接触到了这个挺老但是很好用的技术——JNI

看这段代码

        //创建对象
        JNative nGetSystemTime = new JNative("kernel32", "GetSystemTime");//GetSystemTime是dll中的方法
        SystemTime systemTime = new SystemTime();
        //设置指针的参数如上面类所述
        nGetSystemTime.setParameter(0, systemTime.getPointer());
        //执行方法
        nGetSystemTime.invoke();
        //解析结构指针的内容
        return systemTime.getValueFromPointer();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

里面有一个JNative引入了一个JNAtive.jar包,这个jar包的下载地址:

JNative_1.4RC2_src.zip : http://jaist.dl.sourceforge.net/sourceforge/jnative/JNative_1.4RC2_src.zip 
JNative.jar : http://nchc.dl.sourceforge.net/sourceforge/jnative/JNative.jar

但是下载下来用的时候,我是怎么也用不了,换了无数遍dll文件,在网上找了很多文章,查找解决办法,发现别人可以,偏偏我就不可以!!

最初我的JDK是 32位的1.8,我怀疑是我的JDK问题,于是换成了64位1.8,结果不行

然后我把个人的动态链接库dll文件从64位又换成32位,从system3又换到SysWOW64中,测试后发现。。。。。。一切皆无果,想哭的我都要重装32位系统了!!呜呜

抱着最后的心态,我又下载了一下其他版本JDK 1.7的32位,安装后修改环境变量,然后启动MyEclipse,经过测试后竟然成功和我的底层库连接了!!!哈哈,问题解决!

这里写图片描述

2017-05-16 17:03:54 vae260772 阅读数 1368

最近学习了一下win7系统下java调用C语言写的代码,做个总结。
java调用C语言的DLL文件有多种方法
1)JNA—java native方法
2)JNI—java native interface
3)jnative.jar 包
详细参考:
http://blog.csdn.net/ranmudaofa/article/details/9798779

1、我的电脑是win7 64位系统,安装的jdk也是64位,后来始终提示
运行的时候总是报错
JNative library not loaded, sorry !
JNative library not loaded, sorry !
JNative library not loaded, sorry !
JNative library not loaded, sorry !

试了各种方法,把
JNativeCpp.dll 放到 C:\Windows\System32
、jdk/bin 目录都特么不行,一直报错,
简直要崩溃了,后来找到一篇文章:
http://blog.csdn.net/longtingjing/article/details/44541649
把64位jdk换成32位jdk 成功了!!!!我擦,真坑啊

2、网上说java调用的C语言文件需要下载
Visual Studio 2010 ,谁特么有功夫下载这么大的编辑器。。。
于是搜索了一些文章,推荐使用MINGW c/c++ 编译工具。
https://sourceforge.net/projects/mingw/
这里写图片描述

这个是免安装版,下载完之后把路径配置到环境变量里面,我的如下:
Path
C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\RSA SecurID Token Common;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Users\LocalUser\Desktop\adt-bundle-windows-x86-20140702\adt-bundle-windows-x86-20140702\sdk\platform-tools;%JAVA_HOME%\bin;%java_home%\jre\bin;%adb%;C:\Users\lihui20\Downloads\mingw\bin;

注意C:\Users\lihui20\Downloads\mingw\bin;
添加之后可以
使用cmd,在任何路径选使用
强大的 gcc命令。

3、下载JNative 压缩包。
http://sourceforge.NET/projects/jnative/
最好下载所以文件(3个)
这里写图片描述

Jnative.jar 这个是必须要的,java代码里面会用到。
jnativecpp.dll 后来发现我这个没有其实也可以。网友说最新的Jnative.jar 里面已经包含后jnativecpp.dll 这个文件。经过验证发现确实如此:
这里写图片描述
lib-bin存在这个文件。不需要再添加了

libjnativecpp.so 这个是linux下使用,也就是android 手机开发app使用的。

3、写c文件。我的例子,一个菜鸟,写的比较简单,java输入一个数组,C语言打印。
array.h :头文件

    #ifndef MINGW_DLL_H__  
    #define MINGW_DLL_H__  
    void add(int a[5]);  
    #endif  

保存。

再写array.c

#include <stdio.h>  
#include "array.h"  
 void add(int a[5]){  
  //1.for循环遍历  
  int i=0;
    for (i = 0; i <5; i++)  
    {  
        printf("a[%d] = %d\n",i ,a[i]);  
    } 

} 

保存
4、使用gcc命令生成 .dll 动态库文件,给java调用
C:>gcc -Wall -shared array.c -o array.dll
注意:上面的array.c array.h文件在一个目录下,我的是在
C:\ 下面。
自动生成array.dll文件。

5、把array.dll放到当前项目的最外层目录下(不放在这也可以,使用绝对路径)。
我的是:E:\ecplicespace\FileExplorer-master\testjni\
如果array.dll文件放的路径不对,会提示:
test
Exception in thread “main” org.xvolks.jnative.exceptions.NativeException: DLL d:\array.dll not found
at org.xvolks.jnative.JNative.nLoadLibrary(Native Method)
at org.xvolks.jnative.JNative.loadLibrary(JNative.java:545)
at org.xvolks.jnative.JNative.(JNative.java:521)
at org.xvolks.jnative.JNative.(JNative.java:440)
at com.study.jnilearn.Test.testJNative(Test.java:14)
at com.study.jnilearn.Test.main(Test.java:50)

java代码:

package com.study.jnilearn;

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;

public class Test {
    public static int testJNative(int a[]) throws NativeException,
            IllegalAccessException {

        JNative n = null;
        try {
        //这里可以使用绝对路径 
            n = new JNative("c:\\array.dll", "add");
            // n.setRetVal(Type.VOID);
            // // n.setParameter(0, a);
            // // n.setParameter(1, b);
            // n.set
            // n.invoke();
            // System.out.println("返回:" + n.getRetVal());
            // 为数组创建空间
            Pointer aArrIntInput = new Pointer(
                    MemoryBlockFactory.createMemoryBlock(4 * a.length));

            // 初始化数组
            for (int i = 0; i < a.length; i++) {
                aArrIntInput.setIntAt(4 * i, a[i]);
            }

            // 设定传入参数
            n.setParameter(0, aArrIntInput); // 数组指针
            // n.setParameter(1, a.length); // 数组大小

            // 设定返回类型
            // n.setRetVal(Type.VOID);

            // 调用DLL
            n.invoke();
            // return Integer.parseInt(n.getRetVal());
        } finally {
            if (n != null)
                n.dispose();
        }
        return 0;
    }

    public static void main(String[] args) throws NativeException,
            IllegalAccessException {
        System.out.println("test");
        testJNative(new int[] { 1, 2, 3, 4, 9 });

        // System.loadLibrary("array");
        // Value v=new Value();
        // int a[]={1,2,3,4};
        // int b[]={6,7,8,9};
        // v.add(a);
    }
}

结果:
test
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 9

这里,win7下 java 使用jnative 包调用 c 的简单demo完成了,
当然更复杂的功能编写实现,还需要我们继续学习。

学习JNative

阅读数 1468