鄭州鐵路職業(yè)技術(shù)學(xué)院 軟件學(xué)院 李海勝 朱紋玉
.NET環(huán)境下C#與IDL集成開(kāi)發(fā)方法研究
鄭州鐵路職業(yè)技術(shù)學(xué)院 軟件學(xué)院 李海勝 朱紋玉
目前,應(yīng)用程序開(kāi)發(fā)商有著眾多的編程語(yǔ)言可供選擇。這些編程語(yǔ)言面向不同的應(yīng)用,并擁有不同的特點(diǎn)。綜合不同編程語(yǔ)言的特點(diǎn),實(shí)現(xiàn)高效的應(yīng)用程序開(kāi)發(fā)是現(xiàn)代軟件開(kāi)發(fā)的一個(gè)重要方向。C#是微軟公司為.NET環(huán)境精心設(shè)計(jì)并開(kāi)發(fā)的下一代編程語(yǔ)言,它具有支持快速開(kāi)發(fā),面向?qū)ο蠛徒M件等諸多優(yōu)點(diǎn)。C#語(yǔ)言可以很方便地利用Windows的系統(tǒng)資源以及.NET平臺(tái)提供的大量基礎(chǔ)類庫(kù),通過(guò)C#能夠在.NET環(huán)境上快速開(kāi)發(fā)出種類豐富的應(yīng)用程序。C#語(yǔ)言與IDL(接口描過(guò)語(yǔ)言)的集成開(kāi)發(fā)可以方便快捷地開(kāi)發(fā)出功能強(qiáng)大的各種應(yīng)用程序。IDL是集科學(xué)數(shù)據(jù)分析可視化表達(dá)與跨平臺(tái)應(yīng)用開(kāi)發(fā)等功能為一體的第4代可視化編程語(yǔ)言。它面向矩陣,可以對(duì)數(shù)組直接進(jìn)行操作,具有快速分析超大規(guī)模數(shù)據(jù)庫(kù)的能力,速度相比C、C++也有很大的提高。基于C#語(yǔ)言與IDL的優(yōu)點(diǎn),本文,筆者介紹了在C#語(yǔ)言中調(diào)用IDL進(jìn)行應(yīng)用程序開(kāi)發(fā)的4種方式。
1..NET環(huán)境。.NET環(huán)境是微軟公司最近推出的一個(gè)全新概念,它支持下一代Internet可編程結(jié)構(gòu)。.NET是一個(gè)革命性的新平臺(tái),它建立在開(kāi)放的Internet協(xié)議之上,采用了許多新的工具和服務(wù)。簡(jiǎn)而言之,.NET環(huán)境是1種面向網(wǎng)絡(luò)度支持各種用戶終端的開(kāi)發(fā)平臺(tái)環(huán)境。C#語(yǔ)言是微軟公司于2000年7月發(fā)布的一款專門為.NET環(huán)境而開(kāi)發(fā)的編程語(yǔ)言。作為.NET環(huán)境的通用開(kāi)發(fā)語(yǔ)言,它能夠建造所有的.NET應(yīng)用。它是一個(gè)高效、安全和靈活的現(xiàn)代化程序設(shè)計(jì)語(yǔ)言?;贑#語(yǔ)言上述優(yōu)點(diǎn),本文,筆者選擇C#語(yǔ)言作為.NET的開(kāi)發(fā)語(yǔ)言。.NET環(huán)境采用統(tǒng)一的集成開(kāi)發(fā)環(huán)境Visual Studio,本文,筆者的開(kāi)發(fā)環(huán)境即為Visual Studio2005。在進(jìn)行.NET應(yīng)用程序開(kāi)發(fā)時(shí),可以方便地引用他人提供的外部程序集。從而,可以方便地實(shí)現(xiàn)程序的調(diào)用。
2.IDL。IDL是美國(guó)ITT公司推出的一種可視化語(yǔ)言,它具有較強(qiáng)的數(shù)據(jù)分析和可視化能力。在IDL語(yǔ)言中往往只需要幾條語(yǔ)句就能執(zhí)行大量、復(fù)雜的數(shù)據(jù)處理或者實(shí)現(xiàn)二維、三維圖形的繪制,而這在其他語(yǔ)言中需要上百條語(yǔ)句才能實(shí)現(xiàn)。通過(guò)IDL鏈接外部程序、或者將IDL作為其他語(yǔ)言的外部程序或圖形引擎,IDL可以成為現(xiàn)有開(kāi)發(fā)工具強(qiáng)有力的補(bǔ)充。在應(yīng)用程序開(kāi)發(fā)中實(shí)現(xiàn)IDL與其他語(yǔ)言的相互調(diào)用,使得語(yǔ)言之間可以得到優(yōu)勢(shì)互補(bǔ),從而大大加快程序的開(kāi)發(fā)進(jìn)程。此外,IDL還可以方便地調(diào)用ENVI函數(shù),實(shí)現(xiàn)復(fù)雜的圖像處理功能,大大節(jié)省了系統(tǒng)的開(kāi)發(fā)時(shí)間。
1.圖形顯示模式。IDLDrawWidget(只用于Windows平臺(tái))是IDL提供的可被嵌套在任何ActiveX語(yǔ)言控件的程序。IDLDrawWidget提供了其他語(yǔ)言調(diào)用IDL語(yǔ)言的機(jī)制。.NET環(huán)境支持新的組件標(biāo)準(zhǔn)Assembly,Assembly兼容ActiveX的機(jī)制,可以通過(guò)封裝ActiveX來(lái)實(shí)現(xiàn)?;谶@種機(jī)制,就使得在.NET環(huán)境中集成IDL成為可能。在這里,需要注意的是,IDLDrawWidget在IDL6.4以后的版本中已經(jīng)被ITT公司所放棄,并不再更新,所以一些新的IDL功能在IDLDrawWidget將無(wú)法調(diào)用。調(diào)用的方法:首先,在應(yīng)用程序添加IDLDrawWidget。其次,初始化IDLDrawWidget。最后,通過(guò)IDLDrawWidget調(diào)用IDL。具體程序如下:
IDLdw.IdlPath="C∶\ITT\IDL71\bin\bin.x86";
int n=IDLdw.InitIDL((int)Handle);
if(n==0)return;IDLdw.Retain=2;
IDLdw.GraphicsLevel=2;
int drawWidget=IDLdw.CreateDrawWidget();
if(drawWidget<0) return;
IDLdw.SetOutputWnd((int)logInfoText.Handle);
在IDLDrawWidget控件初始化完畢后,就可以利用ExecuteStr方法來(lái)執(zhí)行IDL命令了。IDL命令可以是IDL語(yǔ)句也可以是IDL代碼文件或者是已經(jīng)編譯好的.SAV文件。具體程序如下:
IDL dw.Execute Str(".Compile T1.pro");
IDLdw.ExecuteStr("T1");
IDLdw.ExecuteStr("restore,T1.sav");
IDL與C#之間的數(shù)據(jù)通信是系統(tǒng)開(kāi)發(fā)的關(guān)鍵。IDLDrawWidget提供了IDL與外部應(yīng)用環(huán)境之間的數(shù)據(jù)傳輸機(jī)制,使得IDL與外部程序之間的數(shù)據(jù)傳輸變得十分簡(jiǎn)單。IDLDrawWidget與C#數(shù)據(jù)傳遞方式如下所示:首先,通過(guò)SetNamedData在C#下進(jìn)行IDL中變量的創(chuàng)建。GetNamedData在C#下進(jìn)行IDL變量讀取的具體程序如下:
int v1=100;
IDLdw.SetNamedData("v1",v1.ToString());
string v2=(string)IDLdw.GetNamedData("v1");
其次,通過(guò)SetNamedArray在C#語(yǔ)言中進(jìn)行IDL中變量數(shù)組的創(chuàng)建,通過(guò)CopyNamedArray在C#語(yǔ)言進(jìn)行IDL中變量數(shù)組的讀取。具體程序如下所示:
int a1={1,2};
IDLdw.SetNamedArray("a1",a1,true);
int a2=(int)IDLdw.CopyNamedArray("a1");
最后,使用ExecuteStr方法執(zhí)行命令行,同時(shí)傳遞數(shù)據(jù)。具體程序如下:
int v1=100;
IDLdw.SetNamedData("v1",v1);
IDLdw.ExecuteStr(".compile SNF.pro");
IDLdw.ExecuteStr("total=sumNumFun(v1=v1)");
int dd=(int)IDLdw.GetNamedData("total");
在.NET環(huán)境中,IDLDrawWidget通過(guò)“自動(dòng)事件”屬性獨(dú)占IDLDrawWidget所產(chǎn)生的事件。此時(shí),C#語(yǔ)言無(wú)法獲取IDLDrawWidget上所產(chǎn)生的事件。IDLDrawWidget的“自動(dòng)事件”屬性包括OnInit、OnExpose、OnButtonPress等內(nèi)容。若需IDLDrawWidget響應(yīng)事件時(shí),需指定“自動(dòng)事件”屬性的IDL過(guò)程或函數(shù)。若需要C#語(yǔ)言對(duì)事件做出響應(yīng),可通過(guò)設(shè)置IDLDrawWidget的RegisterForEvents方法來(lái)屏蔽IDLDrawWidget的“自動(dòng)事件”屬性,IDLDrawWidget便可在其控件區(qū)域響應(yīng).NET的標(biāo)準(zhǔn)事件,如Mouse Up、Mouse Down和Mouse Move等件。
2.功能調(diào)用模式。若系統(tǒng)開(kāi)發(fā)無(wú)需IDLDrawWidget程序提供的可視化窗口,C#語(yǔ)言可直接使用IDL提供的COM組件IDLDRAW3Lib來(lái)調(diào)用IDL。COM組件是微軟公司為了計(jì)算機(jī)工業(yè)的軟件生產(chǎn)更加符合人類行為方式而開(kāi)發(fā)的一種軟件開(kāi)發(fā)技術(shù)。在COM組件下,人們可以開(kāi)發(fā)出各種各樣且功能專一的組件,然后將它們按照需要組合起來(lái),構(gòu)成復(fù)雜的應(yīng)用系統(tǒng)。IDLDRAW3Lib組件的用法與圖形顯示模式基本相同:首先,在應(yīng)用程序中添加IDLDRAW3Lib組件。其次,初始化IDLDRAW3Lib組件。最后,通過(guò)IDLDRAW3Lib組件調(diào)用IDL功能。IDLDRAW3Lib組件的數(shù)據(jù)傳遞方式與IDLDrawWidget程序的傳遞方法相同,在此就不再贅述了。
3.COM_IDL_Connect組件。COM_IDL_Connect組件是IDL提供的另一種COM組件。COM_IDL_Connect組件提供了對(duì)ENVI/IDL現(xiàn)有功能調(diào)用的支持。COM_IDL_Connect組件的數(shù)據(jù)傳遞方式與IDLDRAW3Lib的數(shù)據(jù)傳遞方式相似。COM_IDL_Connect組件的用法亦與IDLDRAW3Lib的圖形顯示模式相同。首先,在應(yīng)用程序中添加COM_IDL_Connect組件。其次,初始化COM_IDL_Connect組件。最后,通過(guò)COM_IDL_Connect組件調(diào)用IDL功能。
4.輸出COM組件。IDL是1個(gè)COM組件,利用COM技術(shù)可以將IDL圖形功能嵌入到C#、VB、VC等編寫的Window程序中。借助IDL的對(duì)象輸出向?qū)Чδ芸梢栽谄渌浖绦蛑泻苋菀椎厥褂肐DL的可視化和分析功能,且無(wú)需進(jìn)行跨平臺(tái)整合所需的編程工作。IDL對(duì)象輸出向?qū)Э奢敵鰧?duì)象、方法和參數(shù),然后自動(dòng)包裝指定的IDL對(duì)象,它可以很容易地將其導(dǎo)入到本地COM客戶端應(yīng)用程序,縮短了接口開(kāi)發(fā)的時(shí)間。使用IDL輸出向?qū)?dǎo)出COM的步驟如下:
(1)定義IDL對(duì)象并將類定義文件的路徑添加到IDL路徑中。
(2)將C#語(yǔ)言編譯器路徑添加到電腦環(huán)境變量path中。
(3)將類定義文件加載到輸出向?qū)е?,并選擇工程類型為“輸出COM”。
(4)設(shè)置輸出對(duì)象的參數(shù)、過(guò)程與函數(shù)。
(5)編譯輸出對(duì)象。
(6)生成*.DLL和*.TLB文件。
(7)在CMD環(huán)境中使用regsvr32對(duì)*.DLL文件進(jìn)行注冊(cè)。
.DLL文件的用法與COM_IDL_Connect組件相似。首先,在應(yīng)用程序中添加已輸出的COM組件。其次,初始化COM組件。最后,通過(guò)COM組件調(diào)用IDL。具體程序如下所示:
sumnumsClassplusNum=new sumnumsClass();
plusNum.CreateObject(0,0,0);
float total=plusNum.FuncADD(33,56);
圖形顯示模式和功能調(diào)用模式形象直觀,調(diào)用過(guò)程簡(jiǎn)單,方便程序調(diào)試。而輸出COM組件模式則需編寫IDL對(duì)象,打包輸出COM組件,并在.NET環(huán)境下調(diào)用COM組件。在.NET環(huán)境下調(diào)用COM出錯(cuò)時(shí),需不斷重復(fù)上述整個(gè)過(guò)程從而導(dǎo)致程序調(diào)試過(guò)程繁瑣,提高了程序的開(kāi)發(fā)難度。圖形顯示模式與輸出COM組件模式可以在.NET環(huán)境下創(chuàng)建IDL的DRAW顯示組件,在實(shí)現(xiàn)可視化的同時(shí)也提供了ENVI/IDL的功能調(diào)用。但功能調(diào)用模式只提供了ENVI/IDL的功能調(diào)用,并未提供可視化組件的調(diào)用。
本文,筆者采用IDLdrawWidget程序來(lái)實(shí)現(xiàn)圖像3D顯示、波譜曲線瀏覽建庫(kù)、蝕變礦物信息提取等功能,快速地完成了ImageInfor系統(tǒng)的開(kāi)發(fā)工作。ImageInfor程序主界面如圖1所示。
本文,筆者總結(jié)介紹了.NET環(huán)境下C#語(yǔ)言與IDL相結(jié)合的4種開(kāi)發(fā)方式。這些開(kāi)發(fā)方式綜合了C#與IDL的優(yōu)點(diǎn)。C#語(yǔ)言支持快速開(kāi)發(fā),其GUI(圖形用戶界面)設(shè)計(jì)方便且IDL數(shù)據(jù)分析功能強(qiáng)大。此外,IDL借助ENVI的二次開(kāi)發(fā)函數(shù)庫(kù)可以實(shí)現(xiàn)更為強(qiáng)大的圖像處理功能。綜合利用編程語(yǔ)言的這些優(yōu)點(diǎn),實(shí)現(xiàn)不同語(yǔ)言的集成開(kāi)發(fā)在一定程度上加快了應(yīng)用程序的開(kāi)發(fā)速度,但是集成開(kāi)發(fā)需要編程人員對(duì)不同語(yǔ)言都要具有一定深度的理解,這使得集成開(kāi)發(fā)具有較大的技術(shù)難度。