JAVA调用OCX和dll实例 绝对管用的例子

首先声明 这个代码是我千辛万苦写好的 ,我是个小白 刚毕业的 第一次接触控件和动态库 所有几乎把所有坑都踩了一遍  这篇文章也是给小白写的 还请技术大佬路过的求指教

第一个坑:ocx和dll是有区别的 我对它们的理解就是ocx更为简洁  是面向别的平台调用的 其实JAVA的机制 调用ocx很方便 它也算是一个中介 所有它叫控件 意思就是控制其他的组件吧 (指的是dll)

好,步入正题,其实整体下来是很简单很简单,但是对于第一次调用的新手来说,哪怕是最简单的,也犹如登天。

首先,如果我们想调用ocx需要用的工具包了 Jacob http://www.pc6.com/softview/SoftView_463758.html这是下载地址 或者自己在网上下载也可以,里面有两个重要的东西 一个是jacob.jar一个是jacob+版本号+位数.dll

第二个坑:你的电脑是64位的就复制x64的到jdk的bin目录和jre里面的bin目录(最好是lib下也复制)下,32位的就复制x86

接着把jacob.jar复制到你的项目中 这个随便一个目录下面都可以然后 maven依赖导入我给出来

    <dependency>
      <groupId>com.jacob</groupId>
      <artifactId>jacob</artifactId>
      <version>1.19</version>
      <scope>system</scope>
    <!-- 这里填jar包所在的路径 不报红就是对的 -->
      <systemPath>${basedir}/src/main/resources/lib/jacob.jar</systemPath>
    </dependency>

版本号记得要换成你的版本号。

对了 这个我听人家说jdk的版本和jacob的版本还要匹配 我的是jdk1.8配jacob1.19 没问题的 接着往下走

控件注册  这里注册方法我就不给了(这不是个坑 还是要给大家一些难度的)可以在网上搜 很简单 或者你的厂家给的bat自动注册文件

第三个坑:这个也是最气人的一个坑,网上的人全都没说这个坑 真沙雕 是我亲自测出来的

将你需要调用的ocx文件放在C/windows/(如果你的电脑是64位就放在 SysWOW64目录下,32位就放在System32目录下),网上的人都是直接说放32位文件夹下 我就想问 你们良心不痛吗?坑了我好长时间

然后根据你的dll位数(因为是你去调ocx 然后ocx去调dll)32位的就把jdk换成32位的,不然会报错,64位写的 jdk换成64位,

好 准备工作已经完成  接下来 上代码

package com.hsh.ocx;
 
import com.jacob.activeX.ActiveXComponent;
import com.jacob.activeX.ActiveXDispatchEvents;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.InvocationProxy;
import com.jacob.com.Variant;
 
public class JavaOcx {
 
public static void main(String[] args) throws InterruptedException {

// 通过ProgID调用OCX控件,组件的ProgID对应注册表中mc2.ocx注册后的ProgID值,这里要说一下网上说话说一半的沙雕  我要是知道progID是啥 我会写不出来?progID就是在注册完控件后,注册表ROOT下面会有生成一个文件夹然后复制文件夹名称
//CLSID如果知道的话 里面就这样填CLSID:{你的CLSID}
//ActiveXComponent com = new ActiveXComponent("组件的ProgID或者CLSID") ;
ActiveXComponent com = new ActiveXComponent("MC2.Mc2Ctrl.1") ;
//通过CLSID调用OCX控件
//ActiveXComponent com = new ActiveXComponent("CLSID:74E58985-15BD-483D-A281-4F6D4BB6387E") ;
Dispatch disp = (Dispatch) com.getObject();

int result= Dispatch.call(disp,你要调用的方法名,方法里面需要的参数);

System.out.println("返回的结果为"+result);

}
 
}

好了 相信这样调用就很完美了 说一下报错哈 如果是普通的报错 需要去自己百度(还是要锻炼动手能力的),如果出现 "灾难性故障" 这个如果你的ocx控件 厂商不允许修改 那赶快换方法 这个走不通了 如果可以修改 就在控件里面添加个函数 (百度一下就出来了) 

JAVA调用dll

这个是写给需要直接调用dll文件的小伙伴的,坑很多 我只能把我踩过的坑填给大家 

和ocx一样 把要调用的dll放在C/windows/(如果你的电脑是64位就放在 SysWOW64目录下,32位就放在System32目录下)如果放的不对是会报找不到哦

调用dll不用jacob网上的沙雕标题都标不清,我们用JAVA自带的JNA  JNA是JAVA后台调用需要用得 是基于JNI开发的升级版,JNI是在前端页面中用js直接来调 不过这种方法IE8之后就不允许了 不允许前端页面直接调硬件

JNA很简单 话不多说上代码

首先我们需要创建一个接口 这个接口的作用 就是把dll中的方法 映射成接口 

   public interface HDReadCardzx extends Library {
    
        HDReadCardzx INSTANCE = (HDReadCardzx) Native.loadLibrary("这里是dll文件的名称不需要后缀", 这里是接口的名称 需要.class一下);//加载动态库文件
        //动态库中调用的方法 方法名要和dll中的方法名一致 参数也要一致 
        int ReadCertInfo(String pBmpFile, Pointer pName, Pointer pSex, Pointer pNation, Pointer pBirth, Pointer pAddress, Pointer pCertNo, Pointer pDepartment
                , Pointer pEffectData, Pointer pExpire, Pointer pErrMsg
        );
    }
//这句话要加上是转码用的  不过有的小伙伴加上可能没用 这是个坑 我也是在网上找了好久  把项目的编码改一下 只知道idea在哪找 在后面我会有说明
 System.setProperty("jna.encoding", "GBK");
//参数的定义 JAVA和C不同  C中的参数会有输入参数和输出参数 但JAVA中的参数需要对应其类型 并且都需要传进去 目前我只用到了C中char类型 输入参数 JAVA中直接String就可以 输出参数 就需要用到Pointer来给参数分配内存空间 这样才会有值 参数如果是其他 类型的可以百度搜对应类型 原理都一样
      String pBmpFile = "D:\\zb.bmp";
      Pointer pName = new Memory(10);
      Pointer pSex = new Memory(2);
      Pointer pNation = new Memory(2);
      Pointer pBirth = new Memory(50);
      Pointer pAddress = new Memory(80);
      Pointer pCertNo = new Memory(50);
      Pointer pDepartment = new Memory(50);
      Pointer pEffectData = new Memory(50);
      Pointer pExpire = new Memory(50);
      Pointer pErrMsg = new Memory(50);
//这里接收方法返回的结果 通过上面定义的接口常量调用
      int card = HDReadCardzx.INSTANCE.ReadCertInfo(pBmpFile, pName, pSex, pNation, pBirth, pAddress, pCertNo, pDepartment, pEffectData, pExpire, pErrMsg);
      Map map = new HashMap();
//下面就是把值取出来 需要new一个String对象 我给放到map里面 因为我下面还需要调用 
//因为分配的内存空间有空白的字节 需要用到trim()方法 去空
     map.put("pName", new String(pName.getByteArray(0, 10)));
//      map.put("pSex", new String(pSex.getByteArray(0, 2)));
//      map.put("pNation", new String(pNation.getByteArray(0, 2)));
//      map.put("pBirth", new String(pBirth.getByteArray(0, 50)));
      map.put("pAddress", new String(pAddress.getByteArray(0, 80)));
      map.put("pCertNo", new String(pCertNo.getByteArray(0, 50)));
      System.out.println(map);
//      map.put("pDepartment", new String(pDepartment.getByteArray(0, 50)));
//      map.put("pEffectData", new String(pEffectData.getByteArray(0, 50)));
//      map.put("pExpire", new String(pExpire.getByteArray(0, 50)));
//      map.put("pErrMsg", new String(pErrMsg.getByteArray(0, 50)));
//                System.out.print((char) pName.getByteArray(0, 50)[i]);
      return map;

至此放在main方法中可以先测试一下

好 写这篇文章的目的 就是不想让新手被网上的一些沙雕误导 太多的坑都不说 话说一半不说了,整个流程基本都是我自己踩着坑慢慢填好的  当然我可能有些地方遗漏了 大家可以留言 我每天都在 会及时解决的 对了 贴代码不要贴一大串子 那样谁看了都烦 ,贴关键的就好。jacob的作用很多 并不局限于调用ocx 小白可以多研究一下哦

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值