2009-09-10 14:13:00 zjutsoft 阅读数 1498

 

要把操作的dll文件放到 c:windows system32目录下。

 

代码:

 

import org.xvolks.jnative.JNative;
 import org.xvolks.jnative.Type;
 import org.xvolks.jnative.exceptions.NativeException;
 import org.xvolks.jnative.pointers.Pointer;
 import org.xvolks.jnative.pointers.memory.HeapMemoryBlock;
 import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;
import org.xvolks.jnative.misc.basicStructures.INT64;
 import org.xvolks.jnative.misc.basicStructures.LONG;
 import org.xvolks.jnative.misc.basicStructures.HWND;
 import org.xvolks.jnative.misc.basicStructures.LPARAM;
 import org.xvolks.jnative.misc.basicStructures.HANDLE;
import org.xvolks.jnative.util.Callback;
 
public class catchDLL2 {
 private static JNative v = null;
 
 /**
 * 加载的DLL
 */
 private static final String DLL_LIB = "BxADLL.dll";


 
// 强制关机
 static void SetScreenState(int a){
  int i=0;
  try{
   v = new JNative(DLL_LIB, "SetScreenState");
   Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   v.setParameter(i++,1);
   v.setParameter(i++,a);
   p.setStringAt(0,"ScreenStateData1");
   v.setParameter(i++,p);
   v.invoke();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 //设置亮度
 static void SetScreenLight(int a){
  int i=0;
  try{
   v = new JNative(DLL_LIB, "SetScreenLight");
   Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   v.setParameter(i++,1);
   v.setParameter(i++,a);
   p.setStringAt(0,"ScreenLight1");
   v.setParameter(i++,p);
   v.invoke();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
  //设置显示屏参数
 static void SetScreenParameter() throws NativeException, IllegalAccessException{
  int i = 0;
  v = new JNative(DLL_LIB, "SetScreenParameter");
  Pointer p3 = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
  
  p3.setStringAt(0,"ParametetData1");
  //设置参数
  v.setParameter(i++,1);
  
  v.setParameter(i++,64);
  v.setParameter(i++,32);
  v.setParameter(i++,2);
  v.setParameter(i++,2);
  v.setParameter(i++,0);
  v.setParameter(i++,0);
  v.setParameter(i++,p3);
  
  //设置返回值类型
  //v.setRetVal(Type.INT);
  v.invoke();
 
  
 }
 //发送命令   参数是包含命令的文件
 static int SendDataToComm(String pchar,int i){
  int ret=1;
  try{
  v = new JNative(DLL_LIB, "SendDataToComm");
  System.out.println(v.getDLLName());
  Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
  Pointer p2 = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
  
  //设置参数
  v.setParameter(0,1);
  
  v.setParameter(1,i);
  v.setParameter(2,64);
  v.setParameter(3,32);
  v.setParameter(4,2);
  p.setStringAt(0,"Com1");
  v.setParameter(5,p);
  v.setParameter(6,57600);
  p2.setStringAt(0,pchar);
  v.setParameter(7,p2);
  
  //设置返回值类型
  v.setRetVal(Type.LONG);
  v.invoke();
  //System.out.println("LED设备="+p2.getAsString());
   ret = Integer.parseInt(v.getRetVal());
  }catch(Exception e){
   e.printStackTrace();
  }
  return ret;
 }
 //取得发送全部显示屏数据的数据头信息,在添加显示区域信息前添加。
 static void GetAllDataHead(){

  try{

   int i = 0;
   v = new JNative(DLL_LIB, "GetAllDataHead");
   /*Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   
   p.setStringAt(0,"SendAllDataHead1");*/
   //设置参数===================
   
   //显示屏屏号
   v.setParameter(i++,1);
   //显示屏中区域的个数
   v.setParameter(i++,2);
   //字幕区域的宽度
   v.setParameter(i++,64);
   //字幕区域的高度
   v.setParameter(i++,32);
   //显示屏类型
   v.setParameter(i++,2);
   
   //字幕区域信息保存的文件名;
   v.setParameter(i++,"SendAllDataHead1");
   
   
   //设置返回值类型
   //v.setRetVal(Type.INT);
   v.invoke();
  
   
  
  }catch(Exception e){
   e.printStackTrace();
  }
 
 }
 //合并显示区域信息文件 
 static void UnionAreaDataToFile(int a,int b,String file,int c){


  try{

   int i = 0;
   v = new JNative(DLL_LIB, "UnionAreaDataToFile");
   /*Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   Pointer p1 = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   p.setStringAt(0,file);
   p1.setStringAt(0,"SendAllData1");*/
   //设置参数===================
   
   //pSourceFile是否是区域文件;1:区域文件;0:非区域文件;
   v.setParameter(i++,a);
   //区域序号;从1开始;
   v.setParameter(i++,b);
   //预合并信息文件名称
   v.setParameter(i++,file);
   //合并目标文件名称。
   v.setParameter(i++,"SendAllData1");
   //0:在原文件下添加合并信息文件;1:删除原文件信息,重新创建合并信息文件
   v.setParameter(i++,c);
   
   
   
   //设置返回值类型
   //v.setRetVal(Type.INT);
   v.invoke();
  
   
  
  }catch(Exception e){
   e.printStackTrace();
  }
 
 
 }
 //转换 字幕区域显示信息 SendDataTitle1 D1
 static void SetScreenTitle(int nAreaOrdID,int x,int y,int hight,int big,String pTitle,int nStunt,int nRunSpeed,int nShowTime){
  try{
   
   int i = 0;
   v = new JNative(DLL_LIB, "SetScreenTitle");
   Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   //Pointer p1 = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   Pointer p2 = new Pointer(MemoryBlockFactory.createMemoryBlock(100));
   p.setStringAt(0,"宋体");
   //p1.setStringAt(0,pTitle);
   p2.setStringAt(0,"SendDataTitle1");
   //设置参数===================
   
   //区域序号
   v.setParameter(i++,nAreaOrdID);
   //字幕区域的横坐标
   v.setParameter(i++,x);
   //字幕区域的纵坐标
   v.setParameter(i++,y);
   //字幕区域的长度
   v.setParameter(i++,64);
   //字幕区域的高度
   v.setParameter(i++,hight);
   //显示屏类型
   v.setParameter(i++,2);
   //点阵类型
   v.setParameter(i++,1);
   //字幕区域显示字体
   v.setParameter(i++,p);
   //字幕区域显示字号
   v.setParameter(i++,big);
   //字幕区域显示颜色; 1:红色;2:绿色;3:黄色
   v.setParameter(i++,1);
   //粗体;1:粗体;0正常
   v.setParameter(i++,0);
   //斜体;1:斜体;0正常
   v.setParameter(i++,0);
   //下划线;1:下划线;0正常
   v.setParameter(i++,0);
   //字幕区域显示的字幕滚动信息
   v.setParameter(i++,pTitle);
   //字幕区域显示特技;具体特技特征字见注1;
   v.setParameter(i++,nStunt);
   //字幕区域信息运行速度
   v.setParameter(i++,nRunSpeed);
   //字幕区域信息停留时间
   v.setParameter(i++,nShowTime);
   //字幕区域信息保存的文件名;
   v.setParameter(i++,p2);
   
   
   //设置返回值类型
   //v.setRetVal(Type.INT);
   v.invoke();
  
   
  
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 
 //设置亮度
 static void setLight(int a){
        //设置亮度 SetScreenLight(1--15) ScreenLight1
  SetScreenLight(a);
  int ret=SendDataToComm("ScreenLight1",0xc8); 
  if(ret==1) System.out.println("亮度设置发送成功");
  else System.out.println("亮度设置发送失败");
 }
 
 //强制开关机
 static void setState(int a){
  //强制开关机 SetScreenState(1表示开机  0表示关闭); ScreenStateData1
  SetScreenState(a);
  int opendown=SendDataToComm("ScreenStateData1",0xC4); 
  if(opendown==1) System.out.println("开关机发送成功");
  else System.out.println("开关机发送失败");
  
 }
 
 //设置屏参
 static void setParameter() throws NativeException, IllegalAccessException{
  //设置显示屏参数 SetScreenParameter(); ParametetData1
  SetScreenParameter();
  int par=SendDataToComm("ParametetData1",0xC1); 
  if(par==1) System.out.println("显示屏参数发送成功");
  else System.out.println("显示屏参数发送失败");
  
 }
// UnionAreaDataToFile 1:区域文件;0:非区域文件; 区域序号;从1开始;
 //0:在原文件下添加合并信息文件;1:删除原文件信息,重新创建合并信息文件
 //发送字幕 message1显示上面  message2显示下面
 public static void SendMessage(String message1,String message2){
  GetAllDataHead();
  UnionAreaDataToFile(0,0,"SendAllDataHead1",1);
  //16是字幕显示高度 12是字体大小
  SetScreenTitle(1,0,0,16,12,message1,1,1,2);
  UnionAreaDataToFile(1,1,"SendDataTitle1",0);
  
  SetScreenTitle(2,0,16,16,12,message2,1,1,2);
  UnionAreaDataToFile(1,2,"SendDataTitle1",0);
  //设置字幕 SetScreenTitle(); SendDataTitle1
  //SetScreenTitle();
  int title=SendDataToComm("SendAllData1",0xD1); 
  if(title==1) System.out.println("向显示屏发送数据成功");
  else System.out.println("向显示屏发送数据失败");
 }
 
// 发送字幕 message1显示上面 全屏显示
 public static void SendOne(String message1){
  GetAllDataHead();
  UnionAreaDataToFile(0,0,"SendAllDataHead1",1);
  
  SetScreenTitle(1,0,0,32,24,message1,1,1,2);
  UnionAreaDataToFile(1,1,"SendDataTitle1",0);
  
  
  //设置字幕 SetScreenTitle(); SendDataTitle1
  //SetScreenTitle();
  int title=SendDataToComm("SendAllData1",0xD1); 
  if(title==1) System.out.println("向显示屏发送数据成功");
  else System.out.println("向显示屏发送数据失败");
 }
 
 public static void main(String[] args) {
  
  try{
   //1~15  亮度增加
   //setLight(1);
   //0关机 1 开机
   //setState(1);
   //设置屏参
   //setParameter();
   
   SendMessage("浙A-T56865","杭州威玛计算机系统有限公司");
   //SendOne("中国你好");
  }catch(Exception ne){
   System.err.println("listAllDevice NativeException!");
   //releaseCard();
   ne.printStackTrace();
  }
  
 }

}

2011-08-15 11:32:36 iteye_9620 阅读数 63
由于项目要求,需要用Java调用windows的dll文件,查了一下,如果用JNI的话是比较麻烦的,在sourceforge.net上搜索了一下 “Java dll”,首先出现的是Jnative,于是决定用它,后来也试了些别的,但还是JNative好使,简单总结如下:

Java调用动态库所需要关心的问题:
l 如何装载dll文件,以及如何定位所要使用的方法;

l 数据类型是如何对应的;

l 如何给使用的方法传递参数;

l 如何获取返回的值。

JNative INFO:
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/

Version:1.3

一个开源的组件,通过它调用已有动态库中的方法就非常的方便,支持CallBack 。

为什么选择JNative
同类的开源组件相对活跃的还有,JNA ( Java Native Access ), Jawin,Nativecall,etc.但是Jnative 相对更容易使用,它对数据类型的处理做的更好。

l JNA 需要用户对所使用的DLL文件事先进行封装,才能装载。另外需要在一个java接口中描述目标DLL中的函数与结构,从而使JNA自动实现Java接口到native function的映射,较麻烦。

l Nativecall 暂时还不知道如何装载dll文件。

l Jawin 数据类型匹配相当敏感,它采用一种叫做”instruction string”的格式来传递参数,还没有完全理解。

How to:
解压JNative-1.3.2.zip 获得三个文件,分别是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar 。


JNativeCpp.dll Windows下用的,拷到windows / system32目录下;

libJNativeCpp.so Linux下的咚咚;

JNative.jar 这是一个扩展包,将其copy到C:\jdk\jre\lib\ext 下(我的目录结构),系统会自动加载。

结构映射(Structure Mapping)


Type
Length
JNative class

DWORD
4
org.xvolks.jnative.misc.basicStructures.LONG

HWND
4
org.xvolks.jnative.misc.basicStructures.HWND

COLORREF
4
org.xvolks.jnative.misc.basicStructures.LONG

COLORREF*
4
org.xvolks.jnative.pointers.Pointer

LPARAM
4
org.xvolks.jnative.misc.basicStructures.LPARAM

LPCCHOOKPROC
4
org.xvolks.jnative.util.Callback

LPCTSTR
4
org.xvolks.jnative.pointers.Pointer


一些关键的类及方法

Class
作用
一般用到的方法(参数略,参考Doc)

org.xvolks.jnative.Jnative
装载dll文件,定位函数
JNative(),setParameter(),setRetVal(),getRetVal() etc.

org.xvolks.jnative.pointers.Pointer
替代本地函数中的的指针,需要先申请一块内存空间,才能创建
Pointer(),dispose()

org.xvolks.jnative.pointers.memory.MemoryBlockFactory
申请一块内存空间
createMemoryBlock()

org.xvolks.jnative.exceptions.NativeException
抛出装载,定位等方面的异常


org.xvolks.jnative.Type
列举和管理Jnative需要的不同的数据类型


(二)

简单测试,Javadoc 下和官方网上有些例子,下面的是我随便从IC读卡程序中找了个DLL进行的测试:
SCReader.dll 下的SCHelp_HexStringToBytes()函数原型
SCREADER_API WINAPI long SCHelp_HexStringToBytes(

LPCTSTR pSrc,

BYTE* pTar,

int MaxCount

);

注意:dll文件需要放到System32下,否则可能找不到


通过Jnative 用java 来调用代码如下:

package onlyfun.dllcall;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;
import org.xvolks.jnative.Type;
public class UserCall {
/**
* return 转换成功的字节数
*/
static JNative Something = null;
static Pointer pointer;
public String getSomething(String pSrc, Pointer pTar, int MaxCount) throws NativeException, IllegalAccessException{

try{
if(Something == null){
pTar = new Pointer(MemoryBlockFactory.createMemoryBlock(36));
Something = new JNative("SCReader.DLL", "SCHelp_HexStringToBytes");
// 利用org.xvolks.jnative.JNative 来装载 SCReader.dll,并利用其SCHelp_HexStringToBytes方法
Something.setRetVal(Type.INT);
// 指定返回参数的类型
}
int i=0;
Something.setParameter(i++,pSrc);
Something.setParameter(i++,pTar);
Something.setParameter(i++,MaxCount);
System.out.println("调用的DLL文件名为:"+Something.getDLLName());
System.out.println("调用的方法名为:"+Something.getFunctionName());
//传值
Something.invoke();//调用方法
return Something.getRetVal();
}finally{
if(Something!=null){
Something.dispose();//释放
}
}
}
public Pointer creatPointer() throws NativeException{
pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(36));
pointer.setIntAt(0, 36);
return pointer;
}

public static void main(String[] args) throws NativeException, IllegalAccessException {
UserCall uc = new UserCall();
String result = uc.getSomething("0FFFFF", uc.creatPointer(), 100);
System.err.println("转换成功的字节数为:"+result);
TestCallback.runIt();
}
}


摘自:http://www.oschina.net/question/12_10956
2016-09-24 12:22:09 a462464126 阅读数 4135

1.第一个问题:Java调用dll文件

JNative方式调用dll
JNative是一种能够使Java语言使调用DLL的一种技术,对JNI进行了封装,可能有些读者会有这样一个问题,JNative对JNI进行了封装,并且是一种跨语言的使用DLL,会不会在效率方面很不如人意,我可以用我使用Jnative的经验告诉你,不会!因为我用Jnative就是用来处理大量的数据调用,是基于实时数据库接口的调用。而实时数据库的数据量是非常大的。
首先下载JNative,
注意:将JNative解压,并将其中的JNativeCpp.dll拷贝到system32文件夹中,libJNativeCpp.so是linux平台使用的。
(网址:http://blog.csdn.net/a491857321/article/details/51504094
使用过程出现问题:
1.找不到NISEC_SKSC.dll,出现这个问题是因为我仅仅将NISEC_SKSC.dll文件放到system32下,而NISEC_SKSC.dll有其他dll的引用,所以需要将安装过的税控所有文件拷到system32下
这里写图片描述
2.找不到JNativeCpp.dll,需要将其放到system32下,同时JNative.jar需要放到jdk和jre目录下面
这里写图片描述
这里写图片描述
配置classpath添加JNative.jar的路径

2.第二个问题。xml与bean转换
采用XStream读取返回信息转为bean

3.第三个问题。传递xml报文,编码问题,一定要写成gbk编码

 public static String getPKServerResult(String xmlcontent, Object... objs) {
        logger.info("log输入为======\r" + xmlcontent);
        Pointer pIn = null;
        Pointer pOut = null;
        try {
            String res = JNAUtil.class.getClassLoader().getResource("NISEC_SKSC.dll").getFile();
            // 加载动态库及函数
            JNative jnPKServer = new JNative("NISEC_SKSC.dll", "PostAndRecvEx");
            byte[] bytes = (xmlcontent + '\0').getBytes("GBK");
            MemoryBlock   memoryBlockIn=MemoryBlockFactory.createMemoryBlock(bytes.length);
            pIn = new Pointer(memoryBlockIn);

            // 设置传入参数
            pIn.setMemory(bytes);
            jnPKServer.setParameter(0, pIn);
            // 处理传出参数
            if (objs != null && objs.length == 1 && objs[0] instanceof Number) {
                MemoryBlock   memoryBlockOut=MemoryBlockFactory.createMemoryBlock(((Number) objs[0]).intValue());
                pOut = new Pointer(memoryBlockOut);

            } else {
                MemoryBlock   memoryBlockOut=MemoryBlockFactory.createMemoryBlock(1000000);
                pOut = new Pointer(memoryBlockOut);
            }
            jnPKServer.setParameter(1, pOut);
            // 执行调用
            jnPKServer.invoke();

//            String bak ="";
//            String bak =pOut.getAsString();
            byte[] mm=pOut.getMemory();
            String bak = new String(mm,"GBK");
//            String bak = new String(pOut.getAsByte(0),"GBK");

//            for(int i=0, sumi=((Number) objs[0]).intValue(); i< sumi; i++){
//                bak+=((char) pOut.getAsByte(i));
//            }
            logger.info("log输出为======\r" + bak);
            return bak.trim();
        } catch (Exception e) {
            logger.error("Jnative遇到错误", e);
        } finally {
            try {
                if (pIn != null) {
                    pIn.dispose();
                }
                if (pOut != null) {
                    pOut.dispose();
                }
            } catch (NativeException e) {
                logger.error("Jnative遇到错误", e);
            }
        }
        return null;
    }

网址:http://bbs.csdn.net/topics/390806040,String就是一段字符串,需要通过byte[]进行编码的操作

到此技术点基本搞定了,突然有一天客户打电话说网页打不开了,看了一下,tomcat关掉了,开启后,运行一段时间又挂了。。。后来想想可能是因为JNA需要申请内存空间,如果一次申请太多,会导致程序异常,所以将调用接口改为递归形式,每次只读一个开票设备一天的数据。问题解决了,看一下效果吧

2015-06-17 16:30:44 u013166918 阅读数 883

准备工作:

1.要有jnative.jar包

2.JNativeCpp.dll 文件放入到system32目录和本地工程目录下;

3.test.dll文件放入system32目录和本地工程目录下;

注:tomcat发布项目要将*.dll文件放入到tomcat的bin目录下。

一些遇到的问题:

报错信息DLL 。。。not found可能就是你的.dll文件没有放到相应的目录,见准备工作。

报错信息function not found是在你的.dll文件中没有找到这个方法。

2011-10-11 14:39:43 Leon1509 阅读数 70
ref: TermTx.dll接口调用说明书

1. 将目标DLL库文件及其依赖的DLL文件复制到:%JAVA_HOME%\bin目录下
2. 下载JNative.zip并解压,获得三个文件,分别是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar。
3. 将第2步中解压出来的JNativeCpp.dll复制到windows/system32目录
JNative.jar复制到%JAVA_HOME%\jre\lib\ext目录

程序中使用System.loadLibrary("TE_Adapter")载入DLL动态库,其中的TE_Adapter为DLL文件名(不含扩展名)。

jnative 调用dll

阅读数 658

java 通过jnative调用dll

阅读数 10470

JNative调用DLL

阅读数 52

没有更多推荐了,返回首页