查看帮助
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