jacob访问ocx控件方法和遇到的问题

最近在进行摄像机的二次开发,摄像机厂商提供了使用C++开发的ocx控件:所以尝试使用jacob来进行访问。

操作步骤如下:

1, 从官网(http://sourceforge.net/projects/jacob-project/)下载了1.18版本的包。

2,jacob.jar放在 C:Program FilesJavajdk1.7.0_25jrelibext  jacob-1.18-M1-x86.dll和 jacob-1.18-M1-x64.dll 放在 C:Program FilesJavajdk1.7.0_25in

3,jacob.jar添加到工程中。

4,将**.ocx放到System32目录下,并用regsvr32注册到系统

 

5, java代码如下:

ActiveXComponent com = new ActiveXComponent("NETVIDEOACTIVEX23.NetVideoActiveX23Ctrl.1");

Dispatch disp = (Dispatch)com.getObject();

Dispatch.call(disp,"Logout");

出现了异常

com.jacob.com.ComFailException: A COM exception has been encountered:

At Invoke of: Logout

Description: 8000ffff / 灾难性故障

at com.jacob.com.Dispatch.invokev(Native Method)

at com.jacob.com.Dispatch.invokev(Dispatch.java:625)

at com.jacob.com.Dispatch.callN(Dispatch.java:453)


6,看到网上有说在ocx中加一个函数,跳过加载时检查是否允许调用的判断(http://lvqingboy-163-com.iteye.com/blog/769358),就把公司以前用的一个ocx加了函数再用jaboc试了一次,能正常运行。

7,知道这个问题的原因了,因为找摄像机厂商比较麻烦,我们已经采取了其他方案,这个方案就不做了。

8,如果要修改这个问题,需要摄像机厂商,添加COleControl.IsInvokeAllowed (DISPID)函数,跳过允许调用的检查,接口就可以正常调用了;

下面是其他人在使用jacob时遇到的问题,记录如下:
1、在测试接口的过程中,出现了过jvm 栈溢出的异常信息(忘记截图了),经过检查,在ocx中使用了一个比较大的局部变量,造成jvm栈内存溢出异常,将ocx的内存改为堆内存,就正常了,没有尝试过修改jvm的参数配置,不知道会不会有效果;

2、引用传递,ocx中使用了引用传递参数作为返回值,在java中调用的时候需要按下面这种写法,才能正常返回数据,否则会报参数类型错误的异常
Variant userId = new Variant(new Integer(0), true);
Dispatch.call(dispatch, "GetOneUserID",userId);

3、因为是B/S结构程序(Spring、Struts、Hibernate),将jacob-1.17-M2.dll放到System32目录下是不行的,需要放到Tomcat的bin目录下面才能正常使用。

结论:java来调用ocx本来就算是很偏门的东西,而且确实不是java的长处。即便能成功,对ocx也有颇多要求,而且还牺牲了java跨平台的特性

原文地址:https://www.cnblogs.com/matthew-2013/p/3480314.html