查看幫助
IDL中打開幫助
查看:IDL > IDL Bridges對應的項目
連接器對象
允許您快速地將IDL的處理能力合併到外部的、面向對象的環境(如COM或Java)中開發的應用程序中。
導出橋助手
通過輸入命令從IDL工作臺啓動導出橋助手
IDLEXBR_ASSISTANT
IDL對象
必須安裝Java。javac和java都必須在執行路徑中。
用於編譯和執行的文件必須在Java類路徑中
IDL_DIR/resource/bridges/export/java/javaidlb.jar
相關函數
CALL_EXTERNAL
The CALL_EXTERNAL function calls a function in an external sharable object and returns a scalar value. Parameters can be passed by reference (the default) or by value.
CALL_FUNCTION
CALL_FUNCTION function calls the IDL function specified by the string Name, passing any additional parameters as its arguments.
CALL_METHOD
The CALL_METHOD function or procedure calls an object method by name, passing any additional parameters as its arguments. CALL_METHOD is useful when you want to dynamically determine the method to call at run-time instead of compile-time.
CALL_PROCEDURE
CALL_PROCEDURE calls the procedure specified by Name, passing any additional parameters as its arguments.
簡單應用
測試代碼如下:
ENVI, /RESTORE_BASE_SAVE_FILES
ENVI_BATCH_INIT
ENVI_REPORT_INIT, ['line1', 'line2', 'line3'], $
title='Title', base = base, /interrupt
ENVI_REPORT_INC, base, 100
FOR i = 0, 100-1 DO BEGIN
ENVI_REPORT_STAT, base, i+1, 100, CANCEL=cancelvar
;用來判斷是否點擊了 Cancel 按鈕
IF cancelvar EQ 1 THEN BEGIN
tmp = DIALOG_MESSAGE('是否停止處理?', /cancel)
;用來判斷點擊了“確定”還是“取消”
IF tmp eq 'OK' THEN BEGIN
ENVI_REPORT_INIT, base = base, /finish
BREAK
ENDIF
ENDIF
WAIT,0.1
ENDFOR
ENVI_REPORT_INIT, base = base, /finish
ENVI_BATCH_EXIT
java調用了IDL開放的接口,通過該接口調用了lib庫中的內容
IDL對象構造原理
創建對象類,首先需要創建與類名一致的結構體,IDL中規定的創建格式如下:
PRO ClassName__DEFINE
struct = {ClassName,data1:value1,...dataN:valueN}
END
過程的名稱由類名,兩個下劃線"__"和DEFINE組成。用戶在設計方法的時候,IDL提供了一個方便控制對象本身的隱含對象self,與C++類裏的this指針類似。
創建對象生命週期的方法 包括Init和Cleanup兩個。
Init方法必然是個函數function。原因之一是Init方法運行正確需要返回1,如果有錯誤則返回0。這個方式也是一個初始化,類似於C++裏面的構造函數,顯然Cleanup就類似於析構函數了。這兩個方法需要用戶手動添加編寫。
配置IDL環境
在我的電腦中配置Java環境,測試javac可以正常打包
IDL中新建項目,建議配置成GBK格式,支持中文顯示
編寫IDL對象
首先編寫idl對象文件,保存名默認爲helloworldex__define.pro
;類的方法和過程定義:functon/pro類名::方法名/過程名
FUNCTION helloworldex::HelloFrom,who
print,'2'
return,who
END
;類的方法和過程定義:functon/pro類名::方法名/過程名
;Init方法相當於IDL類的構造函數,要在類定義前,這個方法必須有
;必須有返回值,1成功,0失敗
;此處可以做一些初始化操作,比如初始化envi批處理模式、其他參數等
FUNCTION helloworldex::Init
print,'1'
RETURN,1
END
;在釋放內存時調用
pro helloworldex::Cleanup
print,'3'
END
;IDL類定義,類名爲helloworldex,後面跟兩個下劃線和一個define
;類的裏面是一個結構體,就是這樣的寫法,helloworldex作爲結構體署名
;who和message是結構體的兩個成員
;$是續行符,相當於寫在一行上
;IDL類默認有一個self表示本對象,相當於java中的this
;self.who可以引用who成員
;var=self.HelloFrom,'Java'可以引用HelloFrom方法,
;也可以定義過程,使用方法和function類似
PRO helloworldex__define
struct={helloworldex,$
who:'',$
message:''$
}
END
測試IDL對象
IDL> h=helloworldex()
1
IDL> h.HelloFrom()
2
% PRINT: Variable is undefined: <UNDEFINED>.
% Execution halted at: $MAIN$
IDL> delvar,h
3
導出IDL對象
命令行執行:idlexbr_assistant,彈出助手工具
新建Java項目
選擇保存的__define.pro文件,此處說明,此助手只支持導出__define.pro形式的IDL類
保存此項目,設置導出的類和方法
配置導出類的名稱和包名
如果IDL類中有多個方法,可以只導出需要暴露的方法即可,不需要全部導出
配置導出方法的參數
工具欄第三個按鈕,build,生成HelloWorld1.java和HelloWorld1.class,.class沒什麼用。
// This code has been generated by the code Wizard and should not be
// modified. The recommended manner of changing the behavior is to
// implement a class that inherits from this generated class.
package hello;
import com.idl.javaidl.*;
public class HelloWorld1 extends JIDLObject
{
// Constants set by Wizard
private static String IDL_CLASS = "helloworldex";
private static String OPS_NAME = "HelloWorld1_Process";
// Constructor
public HelloWorld1() {
super(IDL_CLASS, OPS_NAME);
}
// properties generated by Wizard
// class methods generated by Wizard
public JIDLString helloFrom(
JIDLString WHO
)
{
final int ARGC = 1;
Object[] argv = new Object[ARGC];
int[] argp = new int[ARGC];
Object result = null;
final int FLAGS = 0;
// Parameter assignments
argv[0] = WHO;
argp[0] = JIDLConst.PARMFLAG_CONST;
result = super.callFunction("HELLOFROM",
ARGC, argv, argp, FLAGS);
return (JIDLString)result;
}
}
Java調用IDL功能
把helloworldex__define.pro複製到IDL安裝目錄的lib文件夾中,我的是C:\Program Files\Harris\ENVI55\IDL87\lib
在eclipse中創建java項目
引用外部jar包,jar包存放在IDL安裝目錄下,此jar包的位置不能移動,移動後IDL代理類無法找到idl的程序,我的是C:\Program Files\Harris\ENVI55\IDL87\resource\bridges\export\java\javaidlb.jar
把生成的包和.java複製到java項目中
繼承這個類,實現此IDL jar包中提供的JIDLOutputListener接口,我創建了HelloWorld1Ex1類,有幾個注意的地方看註釋,比較簡單。
package hello;
import com.idl.javaidl.JIDLObjectI;
import com.idl.javaidl.JIDLOutputListener;
import com.idl.javaidl.JIDLString;
public class HelloWorld1Ex1 extends HelloWorld1 implements JIDLOutputListener {
private static final long serialVersionUID = 1L;
private HelloWorld1 hello1;
public HelloWorld1Ex1() {
//固定寫法
hello1 = new HelloWorld1();//1.實例化助手導出的類
hello1.createObject();//2.創建對象
hello1.addIDLOutputListener(this);//3.添加監聽,不添加java控制檯不會打印IDL print的內容
String strFromIDL = hello1.helloFrom(new JIDLString("我家寶寶")).stringValue();//調用
System.out.println("-------->來自IDL的問候:"+strFromIDL);
hello1.destroyObject();//JVM虛擬機不負責回收IDL代理對象的垃圾,需要我們自己回收
}
@Override
/**
* 實現此接口,可以將IDL中的print輸出到java控制檯
*/
public void IDLoutput(JIDLObjectI arg0, String arg1) {
System.out.println("IDL:>>"+arg1);
}
public static void main(String[] args) {
HelloWorld1Ex1 ex1 = new HelloWorld1Ex1();
}
}
顯示執行結果
web項目集成
如果是web項目,因爲此處IDL的jar包javaidlb.jar不能移動位置,發佈tomcat後,會出現該jar包中的類找不到的情況,解決辦法是在配置tomcat的類共享類加載器。
在tomcat的catalina.properties配置文件中,將shared.loader項配置爲javaidlb.jar的絕對路徑。
實戰演練
封裝對應的.pro文件,將文件拷貝到IDL對應的lib庫中。
; -----------------------------
; Generated by the ENVI Modeler
; ENVI 5.5.2, API 3.4
; -----------------------------
pro gf1_ndvi
compile_opt idl2, hidden
on_error, 2
ENVI = envi()
; -----------------------------------------------
; GF1_PMS2_20140724_MSS2_reflectance_rpcortho.dat
; -----------------------------------------------
filename = 'C:\Temp\mm.tif'
raster_1 = ENVI.OpenRaster(filename)
; --------------
; Spectral Index
; --------------
task_1 = ENVITask('SpectralIndex')
task_1.input_raster = raster_1
task_1.index = 'NDVI'
task_1.output_raster_uri = "C:\Temp\mm_ndvi.dat"
task_1.Execute
end
編寫調用接口,將文件拷貝到IDL對應的lib庫中,之後就可以通過java來進行調用。
;類的方法和過程定義:functon/pro類名::方法名/過程名
FUNCTION helloworldex::HelloFrom,who
gf1_ndvi
return,who
END
;類的方法和過程定義:functon/pro類名::方法名/過程名
;Init方法相當於IDL類的構造函數,要在類定義前,這個方法必須有
;必須有返回值,1成功,0失敗
;此處可以做一些初始化操作,比如初始化envi批處理模式、其他參數等
FUNCTION helloworldex::Init
print,'1'
RETURN,1
END
;在釋放內存時調用
pro helloworldex::Cleanup
print,'3'
END
;IDL類定義,類名爲helloworldex,後面跟兩個下劃線和一個define
;類的裏面是一個結構體,就是這樣的寫法,helloworldex作爲結構體署名
;who和message是結構體的兩個成員
;$是續行符,相當於寫在一行上
;IDL類默認有一個self表示本對象,相當於java中的this
;self.who可以引用who成員
;var=self.HelloFrom,'Java'可以引用HelloFrom方法,
;也可以定義過程,使用方法和function類似
PRO helloworldex__define
struct={helloworldex,$
who:'',$
message:''$
}
END