java Jacob调用VB编写的DLL(COM组件)

项目上有调用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.Class1
        ActiveXComponent axc = new ActiveXComponent("Test.Class1");
        //axc.invoke("hello","dll");
        //get MS level dispatch object
        Dispatch myCom = (Dispatch) axc.getObject();
        //调用runme ,返回 hello,world
        Variant 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

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<h3>回答1:</h3><br/>Java通过Jacob可以轻松调用Bartender。Bartender是一款强大的条码标签打印软件,而Jacob是连接Java和Microsoft Office的一种技术。Java可以使用Jacob的API,通过COM接口来调用Bartender的应用程序程序接口(API)。这可以让Java应用程序使用Bartender的打印功能,从而生成和打印条形码标签。最常用的方法是使用Jacob的Dispatch类和Method类,来调用Bartender的API命令,从而实现打印功能。同时,Java和Bartender都支持自定义的脚本和代码,因此可以更加灵活地实现打印的业务逻辑。通过JavaJacob的结合,实现了Bartender和其他应用程序的打印功能的集成,为工业、物流等领域的数据采集和信息管理提供了可靠的技术支持,使得企业的生产管理变得更加高效。 <h3>回答2:</h3><br/>Bartender是一个条码标签打印软件,而jacobJava COM桥接器,可以将Java程序与COM组件进行通信。使用jacob可以在Java程序中调用Bartender的COM 接口,进而实现打印条码标签等功能。 首先,需要下载jacob库并在Java工程中导入相关的jar包。然后,需要安装Bartender软件并通过其开放的COM接口。对于Bartender的COM接口,需要在Bartender的菜单栏中选择“文件”→“打印”→“COM打印对象设置”来打开COM设置窗口。在其中选择“启用COM对象”并保存。 接下来,在Java程序中实现调用Bartender的步骤如下: 1. 创建jacob的ActiveXComponent对象,指定Bartender的COM对象ID“Bartender.Application”。 2. 使用对象方法调用Bartender的COM接口,例如设置打印模板、设定数据源等。 3. 调用jacob的Variant对象,将参数传递给Bartender的COM接口。 4. 调用jacob的Dispatch.call方法传递方法名和参数,实现调用Bartender的COM接口。 示例代码如下: // 创建ActiveXComponent对象 ActiveXComponent bartender = new ActiveXComponent("Bartender.Application"); // 指定模板和数据源 bartender.invoke("Open", new Variant("标签模板")); bartender.invoke("SetNamedSubStringValue", new Variant("数据源名称"), new Variant("数据源值")); // 设定打印机 bartender.setProperty("Printer", new Variant("打印机名称")); // 执行打印 bartender.invoke("StartPrintJob"); bartender.invoke("PrintOut", new Variant(false)); bartender.invoke("CancelPrintJob"); 通过上述方法,我们可以使用Java程序调用Bartender的COM接口,在Java程序中实现打印标签等功能。需要注意的是,Bartender的COM接口需要有相应的权限才能被调用,因此需要确保用户的权限设置正确。同时,也需要按照Bartender的COM接口文档使用正确的方法和参数,才能成功调用Bartender的接口。 <h3>回答3:</h3><br/>Java 通过jacob调用Bartender是一个常见的需求,Bartender是一款非常流行的标签设计和打印软件。jacobJavaCOM桥接器,它可以让Java程序通过COM接口调用Windows平台下的各种COM组件,比如Bartender。下面我们将详细介绍Java通过jacob调用Bartender的步骤。 首先我们需要下载jacob,并添加到Java工程的类路径中。接着我们需要在Java程序中编写Bartender调用的代码。在Java程序中,我们可以通过jacob来连接COM对象,后面的操作跟普通的Java操作一样,包括设置打印参数、调用打印方法等等。 下面是一个简单的Java代码示例,展示如何通过jacob调用Bartender: ```java public class BartenderService { private ComServer bartend; public BartenderService(String bartenderPath) { bartend = new ComServer(); if (bartend.init(bartenderPath)) { return; } throw new RuntimeException("failed init bartender"); } public void printLabel(String filePath, String labelName, Map<String,String> fieldValues) { bartend.call("Format.FileOpen", filePath, true, ""); bartend.call("Document.Open", labelName); for (Map.Entry<String,String> entry : fieldValues.entrySet()) { bartend.setProperty("Document.Variables(\"" + entry.getKey() + "\")", entry.getValue()); } bartend.setProperty("Document.PrinterSetup.PrinterName", "your-printer-name"); bartend.call("Document.PrintLabel", 1, 1); } } ``` 在这个代码示例中,我们定义了一个BartenderService类,它初始化时需要传入Bartender的安装路径。在打印标签时,我们会调用printLabel方法,传入标签文件路径、标签名称和打印参数。这个方法会打开文件、打开标签、设置打印参数和变量(即标签中的占位符),最后调用打印方法来完成打印操作。 总的来说,Java通过jacob调用Bartender是非常方便的,只需要简单地编写几十行代码,就可以实现标签的设计和打印。如果您在工作中有相关需求,建议尝试一下这个技术。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值