IDL调用程序

准备工作。你需要安装Visual C++,注意要保证设置cl编译器的环境变量,一个简单的检验方法是在MS-Dos中键入cl命令,看是否正常运行。打开IDL,在命令行中输入

IDL> help,!make_dll,/structure

我们可以得到:

** Structure !MAKE_DLL, 4 tags, length=48, data length=48:
COMPILE_DIRECTORY
STRING 'C:\Documents and Settings\Dave\.idl\rsi\compile_dir-118-idl_6_2-win32-x86-m32-f64'
COMPILER_NAME STRING 'Microsoft Visual C++ 7.0'
CC STRING 'cl %X -D_DLL -DMSWIN -DWIN32 -D_MT /nologo /I"D:\RSI\IDL62\external\include" /c %C /Fo%O'
LD STRING 'link /out:%L /nologo /nodefaultlib /dll %O /def:%E "D:\RSI\IDL62\bin\bin.x86\idl32.lib" msvcrt.lib kernel32.lib %X'
IDL中的make_dll命令就是利用!make_dll系统变量中的参数来编译c语言文件的。COMPILE_DIRECTORY表示编译生成文件存放的地方,COMPILER_NAME是编译器名称,CCLD分别是编译命令和编译选项。这是个参数是系统默认值,都可以通过make_dll命令的参数改变。

2. 编写C语言文件,我们选用安装目录下external\call_external\C中的sum_array.c作为例子,如下
#include
#include "idl_export.h"
float sum_array_natural(float *fp, IDL_LONG n)
{
float s = 0.0;

while (n--) s += *fp++;
return(s);
}
float sum_array(int argc, void *argv[])
{
return sum_array_natural((float *) argv[0], (IDL_LONG) argv[1]);
}
为了方便,我们把sum_array.c放入COMPILE_DIRECTORY目录中。
程序中我们注意到:
a) 需要包含头文件idl_export.h,该文件的目录已经在CC参数中设置,/I"D:\RSI\IDL62\external\include"
b) 定义一个适用于IDL调用的函数float sum_array(int argc, void *argv[]),该函数的参数必须是int argcvoid *argv[]。该函数以后要被CALL_EXTERNAL调用,通用的形式是return_type example(int argc; void *argv[])
c) sum_array函数中调用自己设计的函数sum_array_natural,有两个参数通过指针数组argv[]传递,argv[0]是数组的指针,argv[1]是长整型变量,关于参数的传递可参考帮助;

3. 利用make_dll命令编译sum_array.c文件,
IDL> make_dll,'sum_array','sum_array_examples',['sum_array_natural','sum_array']
这时在COMPILE_DIRECTORY目录中生成sum_array_examples.dll文件。这里'sum_array'是需要编译的c语言文件名,省略扩展名。'sum_array_examples'为生成dll文件的名称,['sum_array_natural','sum_array']是需要输出的函数。

4. 下面我们就可以利用CALL_EXTERNAL命令来调用sum_array_examples.dll中的函数了,例如
IDL> arr_l=FINDGEN(10)
IDL> result = CALL_EXTERNAL('C:\Documents and Settings\Dave\.idl\rsi\compile_dir-118-idl_6_2-win32-x86-m32-f64\call_external_examples.dll','sum_array',arr_l, n_elements(arr_l),VALUE=[0,1], /F_VALUE, /CDECL)
IDL> print,result
得到
45.0000
上面CALL_EXTERNAL的参数:
a) 'C:\Documents and Settings\Dave\.idl\rsi\compile_dir-118-idl_6_2-win32-x86-m32-f64\call_external_examples.dll'call_external_examples.dll文件的目录
b) 'sum_array'是需要调用call_external_examples.dll里面的函数;
c) Value选项定义参数传递的方式,指针传递用0表示,非0表示值传递;
d) /F_VALUE表示函数返回float类型变量;
e) /CDECL定义call_external_examples.dll文件传递参数的方式,适用于C语言,详细参考dll文件的生成。
IDL 6.4如何生成调用了envi函数的独立运行程序呢
我把论坛里的帖子都看了一遍,大伙都用IDL7.0了。可我用的是envi 4.4,所以IDL还是6.4 版。我遇到的问题是,我写了个小程序,调用了envi 函数,如何在IDL6.4 生成独立运行的程序呢。是否必须安装envi呢?
收藏 分享 评分
回复 引用
订阅 TOP
有两种方法:
      一、模仿ENVI+IDL的运行方式。 
         1、先建一个文本文件,命名为protes.run,里面写上程序的名字protest
          2、打开idl编辑器把打包程序目录(包含sav文件的目录)修改成Idl工作目录或者是添加到IDL搜索路径
         3、建立一个快捷方式。在快捷方式的属性中 目标 加上一下命令
idlde路径 -minimized -nodemowarn -noconfirmexit -nosplash @ "run文件路径"例如:D:\Program\envi44\IDL64\bin\bin. -minimized -noconfirmexit -nosplash @"D:\protest\protest.run",最好的方式是直接赋值修改ENVI+IDL的快捷方式^_^
      二、直接保存为sav文件,
           1、在程序开始部分加入:compile_opt idl2 加在End
           2、调试完成后,新开一个IDL编译器,打开程序,编译
           3、不使用Resolve_all,使用Save,file='.sav',/routines保存Save文件
         注意:如果在编译的时候IDL编译器如提示不能识别ENVI的函数,可在程序开始前使用Forward_function ENVI函数标识出ENVI函数,然后就可以直接双击运行打包后程序了,也可以使用运行,前提当然你的系统上要同时安装有ENVI
2#
发表于 2009-8-4 08:48 | 只看该作者
IDL 与 外部语言的几种集成方式(一)——connector
      IDL与外部语言的集成内容包括IDL内调用外部语言和外部语言调用IDL。以下几篇博客简要介绍常用的几种调用方式,希望与大家共同学习和进步。
      一、外部语言调用IDL
            Connector(连接器):即使用IDL事先做好的ActiveX控件和com控件集成到调用语言中。(本实验环境为VS2005 C#IDL6.4,ENVI4.4
          1. IDLDrawWidget
            draw方式(窗口模式): VS工具箱添加comIDLDrawWidget control 3.0,在form窗口添加该控件,初始化:
Code
 1int n;
 2this.axIDLDrawWidget1.IdlPath = @"E:\Program Files\ITT\IDL64\bin\bin.x86\idl.dll";
 3n = axIDLDrawWidget1.InitIDL((int)this.Handle);
 4if (n == 0)
 5{
 6    MessageBox.Show("IDL 控件初始化失败");
 7}
 8axIDLDrawWidget1.SetOutputWnd((int)richTextBox1.Handle);
 9axIDLDrawWidget1.ExecuteStr("restore,'satstretch.sav'");//satstretch.sav必须置放于运行目录下
10axIDLDrawWidget1.ExecuteStr("satstretch");
11
          如果pro没有编译成sav,可将pro置放于运行目录下,直接运行axIDLDrawWidget1.ExecuteStr("satstretch");
          nodraw方式:VS资源管理器添加引用comIDLDRAW3Lib。初始化:
Code

 1int n;
 2IDLDrawWidget idl = new IDLDrawWidgetClass();
 3idl.IdlPath = @"E:\Program Files\ITT\IDL64\bin\bin.x86\idl.dll";
 4n = idl.InitIDL((int)this.Handle);
 5if (n == 0)
 6{
 7    MessageBox.Show("IDL 控件初始化失败");
 8}
 9idl.SetOutputWnd(0);   //注意:如果IDL中要调用envi函数,加上这句会防止出错
10idl.ExecuteStr("restore,'satstretch.sav'");
11idl.ExecuteStr("satstretch");
          2. COM_IDL_Connectnodraw方式)
            VS资源管理器添加引用comCOM_IDL_ConnectLib,初始化:
Code
 1COM_IDL_connect com = new COM_IDL_connectClass();
 2try
 3{
 4    com.CreateObject(0nullnull);
 5    com.ExecuteString("restore,'satstretch'");
 6    com.ExecuteString("satstretch");
 7}
 8catch (Exception ex)
 9{
10    //MessageBox.Show(ex + com.GetLastError());
11}
          此调用过程VS会报错,但IDL程序会正常运行,一直不知道什么地方出了问题,我catch了错误没有理会它。有知道的看过后烦请指教一下。
          说明:
          1. IDLDrawWidgetIDL6.4以后的版本已经被ITT放弃,不再更新,公司以后会朝着COM方向发展。使用Export Bridge Assistant可以将IDL 程序包装成com组件在其他支持com的语言中使用。这个是下篇博客介绍的内容。
          2.参数传递问题,参数传入很好解决。参数传出也提供了相应的接口。IDLDrawWidget提供getNameData方法,具体使用如下:
Code
1string d = "d";
2IDLDrawWidget idl = new IDLDrawWidgetClass();
3idl.IdlPath = @"E:\Program Files\ITT\IDL64\bin\bin.x86\idl.dll";
4int n = idl.InitIDL((int)this.Handle);
5idl.SetOutputWnd(0);
6idl.ExecuteStr("d=test()");//testfunction
7int result=Convert.ToInt16(idl.GetNamedData(d));
          COM_IDL_Connect提供的接口是GetIDLVariable,调用方法和getNameData一样。
        3. 如果VS运行于64bit的机器,生成目标平台最好改为x86,否则会出错。(VS for 64x我没有测试过)

本文发布于:2024-09-20 11:31:44,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/815490.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:程序   参数   调用   语言   文件
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议