64位dll jnative

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

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 阅读数 10497


通过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();
   }
}
2013-01-02 23:31:23 luanxiyuan 阅读数 627

下文参考自:http://blog.163.com/wex660@126/blog/static/2415306520103142363964/

因为项目需要,用到了java调用dll文件中的方法。写成dll文件大多是用C、VB、Delphi语言弄成的,对于我这个纯粹干java的人员来说,着实让我太为难了。唉,也就是说我编程底子没有搭好,惭愧。要是这些语言我都会些,也不至少让我了解并应用这个技术花了很长时间。
我是用JNative技术做的一个例子。需要用到的是:JNative.jar,JNative.dll这些是在Windows中开发的,如果用Linus要用到libJNative.so
1.将JNative.dl,所要读的dll文件l放在C:\windows\system32下面。
2.将JNative.jar放在你的项目下的lib下面
3.将要读的dll文件放在跟使用的类相同的目录下。
4.我的类的源码 .MemoryBlockFactory;

public class SystemTime extends AbstractBasicData<SystemTime>{

    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;

    /**
     * 分配内存,并返回指针
     */
    public Pointer createPointer() throws NativeException {
        pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(getSizeOf()));
        return pointer;
    }

    /**
     * 内存大小
     */
    public int getSizeOf(){
        return 8 * 2;
    }

    /**
     * 获取通过内存指针解析出结果
     */
    public SystemTime getValueFromPointer() throws NativeException {
        wYear = getNextShort();
        wMonth = getNextShort();
        wDayOfWeek = getNextShort();
        wDay = getNextShort();
        wHour = getNextShort();
        wMinute = getNextShort();
        wSecond = getNextShort();
        wMilliseconds = getNextShort();
        return this;
    }

    public SystemTime() throws NativeException{
        super(null);
        createPointer();
    }

    public String toString(){
        return wYear + "/" + wMonth + "/" + wDay + " at + " + wHour + ":" + wMinute + ":" + wSecond + ":" + wMilliseconds;
    }

    public static SystemTime GetSystemTime() throws NativeException, IllegalAccessException {
        // 创建对象
        JNative nGetSystemTime = new JNative("Kernel32.dll", "GetSystemTime");
        SystemTime systemTime = new SystemTime();
        // 设置参数
        nGetSystemTime.setParameter(0, systemTime.getPointer());
        nGetSystemTime.invoke();
        // 解析结构指针内容
        return systemTime.getValueFromPointer();
    }

    public static void main(String[] args) throws NativeException, IllegalAccessException{
        System.err.println(GetSystemTime());
    }

}

注:Kernel32.dll是我要读的dll文件,GetSystemTime是dll文件中的方法(就是所谓的函数名)

That's ok,相信我这么不懂dll的都能做出来,你也能

===============================另一个参考====================================

下文参考自:http://blog.csdn.net/volant_hoo/article/details/2102726

因为项目需求,需要在java中调用dll文件。测试过几种方法,发现还是JNative最为便利。

1.   安装

jnative.sourceforge.net下载最新的JNative二进制包,解压后得到3个文件:JNativeCpp.dll,libJNativeCpp.so,JNative.jar,其中:

JNativeCpp.dll     放在windows/system32目录下

libJNativeCpp.so    linux下使用

JNative.jar          导入工程中

2.   使用

2.1.     加载dll文件

JNative可使用两种方式加载dll文件:

使用System.loadLibrary加载

使用此方法可加载系统目录中的dll文件。可以先把dll文件复制到system32目录下,使用文件前缀名作为参数来加载dll文件。

使用System.load加载

此方法参数为dll文件全路径名。

2.2.     调用函数

1、首先创建JNative对象:

JNative jnative = new JNative(dll文件名, 函数名);

2、设置返回值类型:

jnative.setRetVal(Type.INT);

3、设置参数

jnative.setParameter(0, Type.STRING, …); //设置第一个参数为字符串

jnative.setParameter(1, Type.INT, String.valueof(…));       //设置第二个参数为整数

4、执行

n.invoke();

5、获取返回值

Integer.parseInt(jnative.getRetVal());

2.3.     一个实例

来自国外网上的一个实例,用于摸索struct处理方法:

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


/**
 * SystemTime
 * 
 * typedef struct _SYSTEMTIME {
 *     WORD wYear;
 *     WORD wMonth;
 *     WORD wDayOfWeek;
 *     WORD wDay;
 *     WORD wHour;
 *     WORD wMinute;
 *     WORD wSecond;
 *     WORD wMilliseconds;
 * } SYSTEMTIME, 
 */
public class SystemTime extends AbstractBasicData<SystemTime> {

    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;

    /**
     * 分配内存,并返回指针
     */
    public Pointer createPointer() throws NativeException {
        pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(getSizeOf()));
        return pointer;
    }

    /**
     * 内存大小
     */
    public int getSizeOf() {
        return 8 * 2;
    }

    /**
     * 获取通过内存指针解析出结果
     */
    public SystemTime getValueFromPointer() throws NativeException {
        wYear = getNextShort();
        wMonth = getNextShort();
        wDayOfWeek = getNextShort();
        wDay = getNextShort();
        wHour = getNextShort();
        wMinute = getNextShort();
        wSecond = getNextShort();
        wMilliseconds = getNextShort();
        return this;
    }

    public SystemTime() throws NativeException {
        super(null);
        createPointer();
    }

    public String toString() {
        return wYear + "/" + wMonth + "/" + wDay + " at + " + wHour + ":" + wMinute + ":" + wSecond
                + ":" + wMilliseconds;
    }

    public static SystemTime GetSystemTime() throws NativeException, IllegalAccessException {
        // 创建对象
        JNative nGetSystemTime = new JNative("Kernel32.dll", "GetSystemTime");
        SystemTime systemTime = new SystemTime();
        // 设置参数
        nGetSystemTime.setParameter(0, systemTime.getPointer());
        nGetSystemTime.invoke();
        // 解析结构指针内容
        return systemTime.getValueFromPointer();
    }

    public static void main(String[] args) throws NativeException, IllegalAccessException {
        System.err.println(GetSystemTime());
    }

}

 

2011-09-14 18:40:28 baifuta 阅读数 4334

 jnative在官网中 说明:只支持32位的windows 2000/xp/2003,linux操作系统。

要在64位的操作系统中使用jnative 需要安装32位的jdk ,不能用64位的jdk。而且jnative所要调用的dll,也应该是32位系统中编译的。

目前jnative最高位1.4版,而且好像不再更新了。

 

2015-11-30 12:44:09 wwx1619 阅读数 2208

支持32位jdk,如64位jdk,则在调用时会报错:JNativelibrary not loaded, sorry !

操作系统32位、64位均可。

32位系统调用dll:将要调用的dll文件放入C:\Windows\System32

64位系统调用dll:将要调用的dll文件放入C:\Windows\SysWOW64

JNative:JAVA调用DLL

阅读数 1358