失效链接处理 |
jacob开发说明 PDF 下载
本站整理下载:
相关截图:
![]()
主要内容:
通过Java调用OCX控件有几种方法,JNI、JACOB、Jawin等
1.JNI
最直接的方式,也是最麻烦的方式,需要自己完成所有的工作,不推荐。
2.Jawin
尝试了一下,效果不错,但相对来说,其编程风格更贴近Windows,离Java有点远
3.Jacob
使用Jacob非常方便,Java编程风格,需要了解的知识比较少。
下载地址http://sourceforge.net/projects/jacob-project/
(1)在工程中导入 jacob.jar 这个包,有时还需要将相应的动态链接库放到工程根目录下面(与src目录同级)。
(2)把 jacob.dll 拷贝到 jdk\bin或者C:\WINDOWS\system32目录下。 jacob.jar 与 jacob.dll 版本一致。
(3)注册ocx控件
先把***.ocx控件放入c:\windows\system32 文件夹下 , 在cmd命令行下,输入regsvr32 ***.ocx命令进行.
在java项目中具体的调用代码如下:
1.初始化
ComThread.InitMTA(true);
ActiveXComponent com = new ActiveXComponent("组件的ProgID/CLSID") ;
Dispatch disp = com.getObject();
备注一下:(1.首先需要注册jacob.dll,相应的放到C:\Windows\System32\或者C:\Windows\SysWOW64\下面,然后在运行窗口输入regsvr32 C:\Windows\System32\jacob-1.18-x86.dll,2.查看组件的ProgID/CLSID ,win+R___regedit___ctrl+F___输入控件的全称,然后右键导出,既可以得到。Reg文件。也可以通过exeScope软件打开ocx控件,查看Registery下面的注册信息,尤其是控件类信息里面的GUID,即为所求。2. 在工程中导入 jacob.jar 这个包,把 jacob.dll 拷贝到 jdk\bin或者C:\WINDOWS\system32目录下,jacob.jar 与 jacob.dll 版本一致,一般1.17,1.18-jdk7)
2.调用控件里面的方面
2.1调用无参的方法,并返回一个short值
Dispatch.call(disp, "Init").getShort();
2.2调用有一个参数的方法,并返回一个boolean值
Dispatch.call(disp,"Method",new Variant(args)).getBoolean();
调用多个参数依次类推,注意在传递参数前,将Java中的参数转换成Variant。
2.3基本参数的传递
call(Dispatch dispatchTarget,String name,Object... attributes)
返回值为Variant
传递的参数为基本类型,int,long,string,double,float,String
参数也可以包装成Variant,比如Variant var = new Variant(123);
BSTR直接采用new Variant(str);
一维数组的传参:
int[] p_req=new int[1];
p_req[0]=0;
int v =Dispatch.call(dispatch, "XdkAccountUnreg",new Variant(acc_number),new Variant(p_req[0],true)).getInt();
String转Object[]类型:
Object[] objct={filename}; document = Dispatch.call(documents, "Open", objct).toDispatch();
2.4 二维数组的调用,需要封装到SafeArray中。
JAVA代码:
1.int[] arrInteger = {3,4};
2.SafeArray safeArray = new SafeArray(Variant.VariantInt,2);
3.Variant var = new Variant();
4.safeArray.fromIntArray(arrInteger);
5.//如果需要继续使用当前的数据,则使用putSafeArrayRef
6.//如果只是传值,则可以使用putSafeArray(safeArray)
7.var.putSafeArrayRef(safeArray);
8.Dispatch.call(myCom,"testIntegerArr",var)
9.System.out.println(safeArray[0]);
问题解决:
问题一:java was started but returned exit code=13,启动eclipse时出现这个问题,一般为jdk版本的位数与eclipse的版本位数不一致导致的,建议都用32位的,因为一般ocx控件都是32位的,并且一般64位的也包容32的。
问题二:com.jacob.com.ComFailException: Can't co-create object
或者是com.jacob.com.ComFailException: Can't find the moniker
皆是因为jdk、eclipse的版本不是32位的(即与ocx控件的位数不一致)
问题三:Can't map name to dispid:方法名
函数方法名错误,极有可能是多了空格。
问题四:在使用Jacob调用OCX控件时,总是出一个异常
Exception in thread "main" com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: Init
Description: 灾难性故障
通过Jawin调用,会出现8000FFFF错误。
这个错误是由ActiveX结构设计造成的。
在Ole4.0版本之前,外部程序是可以直接调用OCX中方法的。Ole4.0之后,每次调用控件中的方法,系统会自动检查是否允许调用,即运行COleControl.IsInvokeAllowed (DISPID)
该方法检查控件是否正确的初始化或者是否通过持久存储接口正确加载,如果两个条件有一个满足,即返回TRUE,否则返回FALSE。
当控件在MFC中使用时,很多细节,如初始化,都被过滤了,这样,大多数用户都不会遇到这个问题。但是,当我们从C、C++的dll中调用控件时,不满足上述条件,该方法返回FALSE,这时候再调用任何控件方法,都会出现上述异常。
解决方法很简单,在OCX控件中,重写COleControl.IsInvokeAllowed (DISPID)方法,即在控件的CMyNameCtrl中增加一个方法
BOOL CMyNameCtrl::IsInvokeAllowed (DISPID)
{
return TRUE;
}
|