项目上有调用Visual Basic 6.0编写的DLL文件的需求,在使用JNA调用无果后,在网上找了部分资料,整理如下。

为什么用JNA无法调用?

VB生成的COM组件,虽然是dll后缀,但事实上,它应该叫做activex dll,是一种com组件,与标准dll是两个概念。vb生成的dll,虽然也是dll文件,但是它在生成的时候,屏蔽了输出函数,也就是说,你通过dll查看工具查看dll文件可以调用的方法时,是找不到这些函数的入口的,而标准dll则可以通过这种方式查找到函数入口。(如何让vb生成标准dll文件,实际上已经有成熟方法,只是比较麻烦,具体可以参考http://pydoncy.blog.163.com/blog/static/14380839020111149717308/)

而Java调用dll,根据这种区分,也要使用不同的工具。首先,无论是com组件还是dll文件,它们都是windows下的一种接口规范,对于Java来说,不像C#那样天然可以使用。

Java本身的机制是通过虚拟机运行程序的,这种方式,对于实体机器的利用效率不高。为此,Java的开发工程师发明了Jni。Jni本身是为了实现Java程序与实体机器的链接,通过调用一些本地已编译的其他语言的代码,尤其是c和c++,从而实现提高效率的目的。(也使得代码重用率提高了)

因此,想调用vb的com组件,就必须使用jni。但是jni的调用方法太过于繁琐,而且它首先设计于对c和c++代码的调用,需要对调用的函数编写.h的头文件。因此,有其他的一些开源工具,在基于jni的基础上,简化了开发人员的负担,使得开发人员可以通过简单的代码调用,实现目的。

一开始,我们尝试了jawin这个开源工具。jawin对于如何调用dll这种动态链接库,在jni的基础上实现了简单调用的目的。然而,我们一开始就遇到了找不到函数的问题,也就是前文所说的,vb生成的dll文件是屏蔽了函数入口的。当我们发现这种情况后,我们尝试了让vb生成标准dll,然后还是没有达到目的。

之后,通过对vb的进一步了解,我们终于了解到com组件与dll(动态链接库)的区别,然后找到了另一个工具-JACOB。JACOB就是 JAVA-COM Bridge的缩写,提供自动化的访问com的功能,也是通过JNI功能访问windows平台下的com组件或者win32系统库的。jacob对于com组件的访问调用,在方式上已经大大简化,能够像C#一样通过简单的代码调用。

看到此文章后,在网上搜了下jacob的用法。并且动起手来。

版本选择

jacob-1.18.jar 对应 JDK1.7*32

jar包和环境配置
jacob.jar 放到项目的lib目录
(方案1)
win7
jacob-1.17-x64.dll 放到C:\Windows\System32
jacob-1.17-x86.dll 放到C:\Windows\SysWOW64
(方案2)
把jacob-1.17-x86.dll 放到jdk/jre/bin下,目前选择的这种

判断环境是否配置成功

先使用以下测试代码,判断是否是自己的dll出现问题

    public static void main(String[] args) {ActiveXComponent xl = new ActiveXComponent("Excel.Application");Dispatch xlo = (Dispatch)(xl.getObject());try {System.out.println("version="+xl.getProperty("Version"));System.out.println("version="+Dispatch.get(xlo, "Version"));} catch (Exception e) {e.printStackTrace();} finally {xl.invoke("Quit", new Variant[] {});}}

未出现问题,下一步编写测试代码

    public static void main(String[] args) {//初始化ComThread.InitSTA();//调用Test.Class1ActiveXComponent axc = new ActiveXComponent("Test.Class1");//axc.invoke("hello","dll");//get MS level dispatch objectDispatch myCom = (Dispatch) axc.getObject();//调用runme ,返回 hello,worldVariant result = Dispatch.call(myCom, "runme","world");System.out.println(result.getString());}

控制台打印hello,world。是不是过程很顺利,哈哈哈要是这么顺利,我会写这个嘛~~~

问题主要出现在new ActiveXComponent对象时参数的传递。在网上找了一些资料,用以下方法解决问题。

报错问题:
1.使用jacob时总是报错“com.jacob.com.ComFailException: Can't get object clsid from progid”

解决方案:
出现这个错误的原因,是因为没有把DLL文件注册到系统注册表。
注册方法: regsvr32 dll文件(绝对路径)

对于dll文件,可以通过这个工具打开查看:eXeScope 下载地址:http://pan.baidu.com/s/1bpsPzWz

打开查看dll文件,关注下CLSID值。然后在windows的注册表中搜这个CLSID。

其实我用eXeScope打开这个dll时并没有看到CLSID值,而是看到了GUID

百般无奈下在注册表中搜索到了这个,ProgID的值就是需要传递的参数

最后需要注意,在VB项目工程中,工程名不能为中文名。不知道是不是乱码原因,调用报错。

附:常用操作指令

注册时用 regsvr32     DLL组件名,
卸载时用 regsvr32 /u DLL组件名。            
参考链接:

http://blog.sina.com.cn/s/blog_c0f210170101ctx2.html

https://blog.csdn.net/song_qingwei/article/details/21704429

https://blog.csdn.net/zp357252539/article/details/51586783

java Jacob调用VB编写的DLL(COM组件)相关推荐

  1. python调用c#注意事项_Python调用C#编写的DLL

    起因是工作中需要用的开发编写的DLL,但是它是使用C#编写的,本人不想使用C#去写测试代码,所以需要使用Python来掉这个DLL内的方法 就用这个就很好,不要问为啥不用微软的Ironpython和别 ...

  2. java调用c写的dll jna_jna调用c编写的dll

    我们团队目前开发的产品是用java语言编写的,大家都知道,java编写的代码随便都可以被反编译,导致别人可能会看到你"裸奔"的样子.所以,为了避免这种安全隐患,团队最终商定,将部分 ...

  3. java开发调用C语言的DLL

    通过Java调用OCX控件或者DLL有以下几种方法,使用JNI.JACOB.Jawin等技术完成接口调用: 1.JNI 最直接的方式,也是最麻烦的方式,需要自己完成所有的工作,不推荐. 2.Jawin ...

  4. pb调用c语言dll,PB调用C#编写的Dll类库

    在c# 中编写com组件,供PB调用实例 前言:c#中写的dll直接是不能被pb调用的,只有写成com组件才可以调用,所以用c#写dll时要注意. c#中新建类库 类库类型为通用类库,项目名为AddC ...

  5. 易语言c调用,易语言调用C++编写的DLL

    511遇见网站最近在录制一套易语言编写DLL及调用和Hook,今天记录一下使用VS2015编写一个C++的Dll,易语言来调用. 步骤: 1.启动VS2015 2.创建工程 3.Visual C++ ...

  6. C#调用C++编写的DLL函数各种参数传递问题

    ----在网上查了一个星期,终于找到解决方法 1. 不返回值的参数 C++ 原型: bool    SendNewSms(char *szTel, char *szMessage); C#引用; [D ...

  7. vs2013 c# 中调用 c 编写的dll出错的可能错误

    先说出错原因:    堆栈调用顺序  解决办法:     使用   __stdcall 或 使用C#属性 CallingConvention 起因是我想在c#中调用c函数结果出错了 如下 C 头文件 ...

  8. C#调用C++编写的dll库

    我用vs2008建的C++ dll类库,名字test_interopVC,和C#的CeshiVC项目 一:C++项目dll类库: 1.test_interopVC.h,主要简单的测试,所以就在一个类里 ...

  9. 如何使用VB编写Excel的COM组件

    1 新建工程中选择"外接程序",点击打开之后右侧的属性窗口即显示为MyAddIn工程.(注意如果你使用的是VB精简版的没有"外接程序"的选项,请下载完整版的) ...

最新文章

  1. 用了10多年的 Tomcat 居然有bug,这能忍?
  2. Feature Map of Pytorch示例
  3. codeforces #222 div 1 D Developing Game
  4. 《大西洋月刊》:在线能影响中国高等教育吗?
  5. python编写正则表达式匹配单词_Python正则表达式匹配整个单词
  6. 使用Cross-Page Postback(跨页面提交)在页面间传递数据
  7. jq 比较两个时间是否在同一天_jq: 属性-class
  8. 小鹏汽车2021财年总收入209.9亿元 同比增长259.1%
  9. SoundSource 5 for Mac(音频控制工具)
  10. jsp实验报告(一)
  11. 操作系统教程答案(谢旭升,朱明华版)
  12. oracle dataguard坏块,dataguard主库坏块的修复
  13. 力扣刷题 DAY_79 贪心
  14. [Hive]那些年我们踩过的Hive坑
  15. 2020年海峡两岸最佳职场榜单,38家企业入选
  16. react-router(路由)
  17. 微信小程序:炫酷手持滚动弹幕生成小工具
  18. 水星5口交换机划分Vlan
  19. 微信小程序 view文字水平垂直居中
  20. js获取本机mac地址,IP地址

热门文章

  1. lua 报错:'=' expected near ' '
  2. 2022.1.20-笔记-JSON格式转换(JSON类型str->int\double\string)
  3. 近端串扰NEXT和远端串扰FEXT的ADS仿真
  4. 一个简单的CNN model,训练集MNIST
  5. ERP系统中与BOM有关的常用方法
  6. Java环境配置与eclipse安装破解与汉化
  7. matlab稳态数值解,matlab解稳态导热问题
  8. 一步步学习微软InfoPath2010和SP2010--第一章节--介绍InfoPath2010(2)--InfoPath2010的新功能
  9. Linux 上生成 SSL 证书
  10. 自动生成AES密钥,并使用生成的进行加密解密1