Java調用ocx控件以及dll


下載jacob包

網址http://sourceforge.net/projects/jacob-project/?source=directory

這個包中有jacob-1.17-M2-x64.dll和jacob-1.17-M2-x86.dll兩個dll和jacob.jar一個jar包,兩個dll一個是64位一個是32位,這個對應的是jdk,不是指系統

Jacob包放置位置

如果系統是64位的就將dll文件放到C:\Windows\SysWOW64下,如果系統是32位的就將dll文件放到C:\Windows\System32下

Jar文件可以放到jdk下也可以加載到自己工程的外部jar包,我是加載到工程中的 文件名稱不能修改

注冊ocx插件

注冊ocx插件,建議64位系統放到C:\Windows\SysWOW64下,32位系統放到放到C:\Windows\System32下,

打開命令行,通過命令regsvr32 C:\Windows\SysWOW64\mc2.ocx進行注冊,C:\Windows\SysWOW64\為放置ocx的目錄,mc2.ocx為ocx名稱,注冊成功失敗都會有窗口提示,這是windows的事情,此處不再說明。

卸載注冊命令可以用regsvr32/u C:\Windows\SysWOW64\mc2.ocx

新建java工程

新建java工程,將jacob.jar放到工程中新建的lib目錄下,右鍵工程名打開配置環境變量窗口,導入jar包

   

代碼舉例

 packagecom.hsh.ocx;

 

import com.jacob.activeX.ActiveXComponent;

importcom.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 {

 

       publicstatic void main(String[] args) throws InterruptedException {

 

              //HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{74E58985-15BD-483D-A281-4F6D4BB6387E}

 

              ComThread.InitMTA(true);

              //通過ProgID調用OCX控件,組件的ProgID對應注冊表中mc2.ocx注冊后的ProgID值,可以打開注冊表查找ocx文件名找到對應的值

              //ActiveXComponentcom = new ActiveXComponent("組件的ProgID") ;

              ActiveXComponentcom = new ActiveXComponent("MC2.Mc2Ctrl.1") ;

              //通過CLSID調用OCX控件

              //ActiveXComponentcom = new ActiveXComponent("CLSID:74E58985-15BD-483D-A281-4F6D4BB6387E") ;

              Dispatchdisp = (Dispatch) com.getObject();

              /**

                      先調用Init方法進行初始化       

                [id(1)] long Init(BSTR AccountNo, BSTR Extno,BSTR Password);

                     既可以用接口名稱"Init"調用,也可以用id(1)來調用

         Init為ocx插件中對應的方法名,accountno,extno,password為該方法中對應的參數

              */

String accountno="*********";

              Stringextno = "**";

              Stringpassword = "******";

              intInit = Dispatch.call(disp,"Init",new Variant(accountno),newVariant(extno),new Variant(password)).getInt();

             

              //intInit =Dispatch.call(disp,"Init",accountno,extno,password).getInt();//用接口名稱"Init"調用

              //intInit = Dispatch.call(disp,1,accountno,extno,password).getInt();//用id(1)來調用

              System.out.println("初始化結果為"+Init);

 

              //初始化后需要等一下,不能馬上調用其他接口,所以這里加了延時以等待初始化結束

              Thread.sleep(3000);

                           

              //調用isLogin接口查看是否還在登錄狀態,只有在登錄狀態才可進行其他操作

//[id(1)]LoginEvent(iStatus,szVoipNo,szServiceTel);

             

Boolean isLogin2 =  Dispatch.call(disp,2).getBoolean();

              System.out.println("登錄結果為"+isLogin2);

       If(isLogin2){

//[id(11)]long SendShortMessage(BSTRszRecvTelNo, BSTR szContent);

              intSendShortMessage = Dispatch.call(disp,11,"********","********").getInt();

              System.out.println("短信發送結果為"+SendShortMessage);

}

             

              //釋放線程

              ComThread.Release();

             

       }

 

}

問題總結

常見的幾個錯誤

1、java.lang.UnsatisfiedLinkError: no jacob injava.library.path

這個是沒有找到jacob.dll,需要把對應的dll放到對應目錄下

2、Exception in thread "main"com.jacob.com.ComFailException: Can't get object clsid from progid

這個應該是注冊表中找到的progid不對,檢查一下

3、Exception in thread "main"com.jacob.com.ComFailException: A COM exception has been encountered:

At Invoke of: isLogin

Description: 災難性故障

 

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

       atcom.jacob.com.Dispatch.invokev(Dispatch.java:804)

       atcom.jacob.com.Dispatch.callN(Dispatch.java:440)

       atcom.jacob.com.Dispatch.call(Dispatch.java:510)

       atcom.vflow.sms.InitOcxFunctions.isLogin(InitOcxFunctions.java:36)

       atcom.vflow.test.TestOcx.main(TestOcx.java:14)

 

       原因是: 這個錯誤是由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;

 }

4、An unexpected error has been detected by JavaRuntime Environment:

#

# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x77c9e3be, pid=1140, tid=4900

#

# Java VM: Java HotSpot(TM) Client VM(11.3-b02 mixed mode windows-x86)

# Problematic frame:

# C [ntdll.dll+0x2e3be]

#

# If you would like to submit a bug report,please visit:

#  http://java.sun.com/webapps/bugreport/crash.jsp

# The crash happened outside the JavaVirtual Machine in native code.

# See problematic frame for where to reportthe bug.

#

這個應該是jacob版本問題,我開始用的一個jacob報這錯誤,后下載了新版本的重試就可以了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM