亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

corba核心規范

2019-11-17 05:26:49
字體:
來源:轉載
供稿:網友

核心規范
當前最新版本是3.0,是在2002年8月整理發布的。CCM的3.0規范也已經發布。 CORBA規范3.0終于出來了,也許是不能再拖了吧。比較希奇的是3.0規范的編號是2002年6月份的(02-06-33),但是規范是在7月份才整理出來的。在CORBA3.0規范中去掉了 MiniCORBA和實時CORBA。 OMG組織的網站上有一個頁面介紹在3.0規范將要增加的內容,我將其翻譯過來,大家可以點這兒查看。因為新版本規范在不斷推出,所以里面的內容可能會與現在的實際情況有點兒差異。
語言映射
規定IDL語言到Ada、C、C++、java、COBOL、SmallTalk、Lisp、Python和CORBA腳本語言的映射,以及JAVA到IDL的反映射等。
對象服務
共有17個對象服務:命名服務、事件服務、時間服務、對象事務服務、安全服務、收集服務、并發服務、特性服務、持久對象服務、生命周期服務、交易對象服務、外表化服務、關系服務、查詢服務、通知服務、許可服務、增強時間視圖。
通用設施
主要包括國際化和時間、移動代理。
行業標準
主要有商業、金融、生命科學研究、制造業、電信、交通、醫療保健等。
規則與自由
----為何選擇 CORBA 和 Java 技術?
歡迎光臨有關 Java 和 CORBA 技術的這一定期欄目。此第一期將概述 Java 和 CORBA 技術,并幫助您決定如何最有效地讓它們為您工作。以后的欄目將提供 Java 和 CORBA 編程的內行指導和代碼。
在 1855 年,時年 26 歲的 Joshua Chamberlain 是 Bowdoin 大學的修辭學教授,在一次演講中講述了規則與自由之間的關系,以及二者之間失衡帶來的危害。沒有自由的規則是專制,而沒有規則的自由是混亂。
公司信息系統部門的治理可能會形成過度的規則或過度的自由。規則過度的一個例子是只適用于一個廠商的治理指令,這樣您的系統在擴展時,或在與潛在的公司合作伙伴集成時就會有問題。假如自由過多,個人或者開發小組就會根據他們來選擇技術,這樣,假如這些技術高手碰到他們“生疏的”優先認股權這樣的話題時,擴展或集成又會變得很困難。開發人員可能會受業務環境不斷變化的影響。
努力實現環境平衡
多種環境因素在決定我們的系統必須遵守的的規則。存在于一個業務環境中的系統應有足夠長的壽命,以為公司和客戶創造價值。持續為一個組織創造長期價值的系統必須能夠應付經常的變化。合并、并購、新的治理和市場力量在改變系統的環境,以及通過使用該系統完成業務過程的用戶的需求。變化是一個常數,必須將它添加到評估方程式中。當然,我們無法預知未來,但我們可以分析趨勢并努力設計我們的系統,使之能夠接受大量潛在的變化或系統擴展,同時對組織產生的影響又可以盡可能小。
為了做出正確的決策和評估,我們需要理解支配著環境的規則,以及我們的應用程序在該環境中應具有的自由。要理解的最重要的規則是,我們的系統處在不斷發展的組織中,無論是在公司、政府還是教育組織中,都是業務問題支配技術問題。許多體系結構和平臺評估都將主要問題漏掉了。他們通常會將兩項或多項技術并排放在一起,然后比較技術特性列表。在完成的時候,大多數參與者會達成一致,因為他們不愿與評估小組中嗓門最大、最強硬、勢力最大的派別爭吵。顯然,這不是作出選擇的最有效方法。
確定要害業務問題
將業務問題轉換為對組織需要的實際評估意味著應該著重考慮以下問題:
· 組織內的技術力量
· 不抑制程序員的開發環境
· 不對應用程序構成限制的運行時環境
· 運行時環境和開發環境的許可證問題和法律問題(可以說是規則的規則)
· 可找到有經驗的開發人員
· 能找到收費合理、有見地的咨詢服務公司
· 對組織的客戶的影響
· 對廠商或技術合作伙伴的影響
· 組織的文化和策略
· 組織的上級治理聯盟
· “大亨們”是否在討論并購或合并
· 誰是決策者
這些業務問題通常比其他問題(比如采用每個會話一個線程的并發模型還是每個請求一個線程的并發模型)更重要。您可以走進老板的辦公室,向他發表足可以充斥一次軟件研討會的技術觀點,但是除非您強調了組織的需要,否則您的觀點將顯得非??斩础?br />走近 CORBA
現在讓我們用 CORBA 來解決這些問題。CORBA 是一種開放的行業標準,它由參加“對象治理組織 (OMG)”的 600 多家公司支持。這些公司包括硬件或軟件公司、電信公司、金融公司、大學、醫藥研究所和政府機構。OMG 并不實現它們自己的規范;它們依靠廠商的實現,這些實現有助于將竟爭導向到功能、性能、價格和令人鼓舞的質量這些方面。OMG 本身是一個布滿生氣的、活躍的組織,它的許多官員在各種會議上撰寫文章并發表演講。只要留心觀察,您就會發現,他們總在關注將會對他們的組織及您的組織造成影響的各種變化。
除上述優勢外,CORBA 還提供了高度的交互操作性。這保證了在不同的 CORBA 產品基礎之上構建的分布式對象可以相互通信。因此,大型組織不需要讓所有開發工作都使用同一 CORBA 產品。OMG 一直都在辛勤工作,以期通過加強 CORBA 規范來提供更高級別的可移植性。要知道,當廠商分化它們的產品以及開發人員添加限制時,他們往往會忘記源代碼的可移植性這回事。應當指出,可移植性比以前的版本中有了實質性的提高,并且隨著因特網互操作性協議 (IIOP) 形成強大的用戶集團和眾多聯盟,可移植性將越來越好。

我們很快變會轉入 Java 技術的討論,但我們首先應將語言看作一個整體。信息系統有一個確定的規則,那就是不確定性本身。Java 編程語言可能是今天的語言,但誰知道下一種更好的語言哪一天會使它暗然失色呢?應當知道,就在此時此刻,有人正在他們的車庫里加緊編寫一種更好的語言。因此, CORBA 的語言無關性有助于您長期遵守信息系統環境中的這一法則。CORBA 支持一種經典的、穩定的對象模型,此模型將繼續步入未來。它一直在憑借最新的語言不斷發展,并將繼續向極好的新語言(如 Python)擴展。
Java 編程語言及其他
此環境中可確定的另一點是它的復雜性,這是我們所不愿看到的,Java 技術正好可以派上用場。它能很好地滿足需要,因為它的簡單性將有助于使開發免于陷入底層的復雜性中。Java 語言在許多方面隱藏了一些基本的細節,但就整體而言,Java 技術改善從分析、設計到執行的整個過程。
在分析和設計階段要盡可能統一和明確地表示您的系統和設計模式,這一點極為重要。“統一建模語言 (UML)”事實上已成為表述系統設計的標準語言。UML 的開發是協作方面的一個極好的故事。UML 的標準化過程也相當引人注重。UML 的標準化是通過 OMG 來實現的。OMG 熟悉到需要一種標準建模語言,以跨語言和環境表示分布式對象模型。Java 對象模型與 CORBA 對象模型幾乎完全相同,從而很輕易將您的 UML 設計映射到一種實現,同時也很輕易將 UML 圖映射到“Interface Definition Language (IDL)-to-Java 語言”實現。
經過分析和設計階段的對象將有一些接口,這些接口定義其他組件將如何訪問您的服務?,F在需要將那些接口轉換為一種實現語言。Java 技術同樣使這一步很輕易實現?!癐DL-to-Java 語言”映射相當直接。Java 語言和 IDL 分別提供一個接口要害字,這個要害字有助于說明用每種語言表示的數據類型之間的緊密關系。Java 技術提供一種從 Java 接口到 IDL 的反向映射。不管選擇哪個方向,您都應該用 IDL 表示您的接口;這使您能夠使用所有其他語言與 IDL 之間的映射,并為您提供了為了在以后具有更大自由而必需的語言無關性。
體系結構案例
除了設計之外,系統的體系結構也很重要。許多系統體系結構問題涉及對現有系統(數據庫、舊有系統、可用對象或可能用其他語言編寫的應用程序)的包含。Java 和 CORBA 語言使得可以(而不是禁止)將這些強有力的系統帶給更多的用戶。這是一種解放 -- 許多系統可能許多年來都在發揮著作用。實際上,當完成將這些系統帶入新世紀的所有 Y2K 以前的工作以后,在今后幾年它們可能還將存在。由于其編譯后的字節碼結構,Java 語言將使您很輕易創建和分發可移植的對象,而 CORBA 答應您將這些對象與您計算環境的其余部分進行連接和集成。
我并非想用 Java 和 CORBA 技術來排斥 Java 語言的遠程方法調用、EnterPRise JavaBeans 技術、 Microsoft 的 DCOM 甚至 DCE。Java 和 CORBA 語言最自由的方面是,OMG 正在加緊工作,以確保 CORBA 對象能夠與大量的對象交互。當然,這些連接中有些較難實現,并且最終可能會很脆弱。請記住,這些類型的連接經常是因體系結構、成本、時間或業務等原因而建立的。
Joshua Chamberlain,帶著對規則與自由的見解,在他在 Bowdoin 大學的演講過后七年加入北方軍隊。他功勛卓著,并證實是一位有力的領導者,所以格蘭特將軍選擇讓他接受北弗吉尼亞軍隊的正式投降。他向投降的士兵行行軍禮以示尊敬的行動,是恢復被四年內戰破壞的破碎混亂的聯邦系統的新基礎中的第一塊基石。理解規則和自由的平衡為任何類型的組織中的參與者提供了一個清楚的圖像,使他們能夠清楚地理解他們所面對的系統和要避免的混亂之間的相互影響。
小結
異構系統環境中的互連和通信應該是我們的目標。我們要選擇使用的規則應該答應自由地將現有的系統與新系統一起使用以滿足組織的需要。在這個變化的世界中,當變化被強加給您的組織時,這些規則應該提供最大的靈活性。這些規則提供了一個限制我們的自由的操作范圍,這樣就不易陷入盲目開發的境況。
 
謝謝您耐著性子讀完了本文。我不是修飾學教授,我只是一個程序員,所以在下一期我們將開始討論一個簡單的示例 -- 使用 Java 技術實現 CORBA 客戶機和服務器。
 
探索CORBA技術的應用領域---- 一個簡單的CORBA/Java示例

首  頁 CORBA文章 CORBA規范 CORBA實現 CORBA應用 相關技術 CORBA論壇
(本文摘自IBM developerWorks)
Dave Bartlett
顧問、撰稿人兼講師
2000 年 7 月
內容:


IDL 接口
IDL 編譯器
服務器
客戶機
結論

6 月份,我們談過您為什么要使用 CORBA 和 Java 技術。本月,我要通過一個可用的簡單示例,讓您開始探索 CORBA 技術的許多領域。不過,別忘了我們的目標是,創建這樣一種分布式應用程序:使駐留在一臺計算機上的客戶機能向運行于另一臺計算機上的服務發出請求。我們不想為諸如硬件或操作系統軟件等細節問題操心,而只是想讓這種服務能響應客戶機的請求。
IDL 接口
全部 CORBA 結構是從一個接口開始的,理解接口的最佳方法就是想像我的汽車,對,我的汽車。雖然您不熟悉它,但假如我對您說:“開上我的車,帶些三明治回來當午餐”,恐怕您就不會懷疑自己能不能駕駛我的汽車。您可能想知道它停在哪里,以及開它是否安全,但是您會確信開我的車與開您的車差別不大。這是因為,在各種汽車當中,人與汽車之間的接口已高度標準化了。我的轎車和您的跑車之間可能會有一些差異,但汽車的油門踏板、剎車和方向盤的安裝都是標準的,您一定能輕松快速上路。
因為 CORBA 與語言無關,所以它依靠一種接口定義語言 (IDL),來表達客戶機如何向實現接口的服務發出請求。我們的接口就是一個方法:add()。這個方法將取兩個數(兩個 IDL 的 long 型數)并返回這兩個數之和。下面是我們的接口計算程序:

清單 1. calcsimpl.idl
module corbasem { module gen { module calcsimpl { interface calculator { long add(in long x, in long y); }; }; };};
這個接口中的 IDL 要害字有:module、interface、long 和 in。IDL 使用要害字 module 來創建名稱空間,并且此要害字準確地映射為 Java 要害字 package。運行 IDL-to-Java 編譯器時,生成的 Java 文件將會存到名為 calcsimpl 的子目錄中。IDL 要害字 interface 完美地映射為 Java 接口,并代表一種抽象類型,因為兩者都只定義您與對象通訊的方式,而不涉及對象的實現。IDL 要害字 long 是一種基本的整數類型,它至少映射為一個 4 字節的類型,這種類型在 Java 代碼中就是 int。
想一想執行遠程方法調用的機制,您就會發現定義參數傳遞的方向(客戶機到服務器、服務器到客戶機或者雙向傳遞)是多么的有意義。在 IDL 操作中,這些方向用 in、out 和 inout 要害字來聲明,每個參數都必須聲明方向,以便使對象請求代理程序 (ORB) 知道該參數的去向。這會影響到為發送而進行的參數打包、參數解包以及內存治理。ORB 對參數了解得越多,它的效率就越高。要害字 in 表明 long x 和 long y 是從客戶機傳遞到服務器。
圖 1. 參與 CORBA 請求的各個部分

IDL 編譯器
需要 IDL 編譯器嗎?您可能已經有了 ORB 供給商和 IDL-to-Java 編譯器。但假如還沒有,您從哪里獲取呢?這里有好多,而且有些還可以免費下載。我推薦 Object Oriented Concepts, Inc. 的 Orbacus ORB。假如不將其用于商業目的,它還可以免費下載,而且完全符合 CORBA 2.3 規范。另外一個可試用 60 天的編譯器是 Inprise 的 Visibroker,也完全符合 CORBA 2.3 規范并且可下載。如想獲得這兩種產品,請參閱參考資料。

接口定義以后,必須在 ORB 供給商提供的 IDL-to-Java 編譯器上運行。IDL 編譯器是一種精巧的實用程序,它生成 IDL 的 stub 和 skeleton 以及其它支持文件。生成的這些源文件,大部分將增強 CORBA 標準中定義的特定 IDL 類型的打包功能。編譯器將生成大部分網絡探測 (plumbing),這在分布式系統中非常重要。在最基本的級別中,IDL-to-Java 編譯器只是一個按 CORBA 2.3 規范的定義來實現從 IDL 到 Java 語言映射的程序。手動生成這些代碼既枯燥又費時,還輕易出錯;IDL-to- Java 編譯器會處理這一切,所以您就不用操心啦;同時,它會用一定的規則約束您,并強制您執行封裝。IDL-to-Java 編譯器將把 CORBA -land 規則強加給您的系統。
輸入下面的命令,從 Orbacus 執行 IDL-to-Java 編譯器,把所有生成的文件都放在 CLASSPATH 的輸出目錄下。
清單 2. 調用 IDL-to-Java 編譯器
jidl --output-dir c:/_work/corbasem calculator.idl
生成了什么呢?這個命令生成了構建實現所需要的全部 Java 源文件。IDL-to-Java 編譯器可確保所定義的接口遵守 CORBA 規范的規則。
圖 2. IDL-to-Java 編譯器文件生成

下面是這些文件:
· calculator.java - 這個文件叫標記接口文件。CORBA 規范指出這個文件必須擴展 IDLEntity,并且與 IDL 接口同名。這個文件提供類型標記,從而使這個接口能用于其它接口的方法聲明。
· calculatorOperations.java - 這個文件內含 Java 公共接口 -- calculatorOperations。規范指出,這個文件應該與具有 Operations 后綴的 IDL 接口同名,并且這個文件內含此接口映射的操作標記。上面定義的標記接口 (calculator.java) 可擴展這個接口。
· calculatorHelper.java - 設計 helper 類的目的是,讓所需要的許多內務處理功能脫離我們的接口,但又隨時可用到實現過程中。幫助程序文件含有重要的靜態 narrow 方法,這種方法使 org.omg.CORBA.Object 收縮為一種更具體的類型的對象引用;在這種情況下,將是一個計算程序類型。
· calculatorHolder.java - holder 類是一個專門化類,是為了需要通過引用來傳遞參數的任意數據類型而生成的。這個示例中將不使用 holder 類,但我們將會在以后的欄目中經常見到它。
· calculatorPOA.java - skeleton 類為 CORBA 功能提供了請求-響應探測的一大部分。生成 calculatorPOA.java,是因為缺省方式下的實現是基于繼續的,假如我們選擇基于委托的實現方式,輸出就會不一樣。這些主題將在以后的欄目中具體介紹。
· _calculatorStub.java - 顧名思義,這是一個 stub 類。您的客戶機將需要這個類來進行工作。
 
服務器
現在生成的文件必須在服務器上開始工作,用這個服務器實現我們的接口。所幸的是,大部分探測是適合我們的要求的,但別興奮得太早 -- 還有許多工作要做;就是說,所有這些文件都必須用在正確的地方。
讓我們從 add() 方法的實現開始。
清單 3. SimpleCalcSvr.java -- add() 方法
SimpleCalcServant extends calculatorPOA { public int add(int x, int y) { return x + y; }}
請注重,我們的實現類擴展了已生成的類 calculatorPOA。從客戶機發來一個請求時,該請求通過 ORB 進入 skeleton, skeleton 最終將調用 SimpleCalcServant,來完成請求并啟動響應。我們的接口很簡單,所以我們的實現也很簡單。

服務器其余部分的實現,涉及如何圍繞這個接口實現來設置 CORBA 體系結構,由于可移植性和靈活性方面的原因,許多這些調用要按 CORBA 規范執行。
我們需要完成的第一項任務是,具體說明要使用哪一個 ORB,然后予以初始化。下面的代碼處理此任務:
清單 4. SimpleCalcSvr.java -- 初始化 ORB
java.util.Properties props = System.getProperties(); props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORG"); props.put("org.omg.CORBA.ORBSingletonClass", "com.ooc.CORBA.ORBSingleton"); org.omg.CORBA.ORB orb = null; // 初始化 ORB orb = org.omg.CORBA.ORB.init(args, props);
初始化 ORB 時,需要準確地告訴它哪一個類將用作 ORBClass,哪一個類將用作 ORBSingleton 類。我們的實現將不考慮這些,但所有相關的探測則都將考慮這些。正如我前面所說的,這種情況下,我使用的是 Object Oriented Concepts, Inc. 的 Orbacus ORB,而 OOC 類在那兩個 props.put() 調用中已給出。一旦填入了屬性,props 就只作為一個參數傳遞給 ORB.init() 方法。實際情況可能不是這樣;假如我們要把這個服務器移到另一個 ORB,不希望為服務器重新編碼。所以,在理想情況下,我們寧愿改變一個配置文件,使之指向另一個 ORB 類,然后直接重新啟動。
現在,ORB 已經到位并已初始化,并且實現也已經到位,只是尚未創建,此時,需要為實現創建一個完善的生存地點,而這可不像聽起來那么輕易,在一個分布式環境中,各個實現要求的環境可能略有不同??梢再x予實現許多特征。實現既可以是單線程的,也可以是多線程的;既可以是具有高度可伸縮性的對象池,也可以是單元素。這許多不同的服務器特征已產生了可移植對象適配器 (POA)。POA 使我們可以創建完善的環境,供我們的實現在其中駐留。所有符合 2.3 規范的 ORB 都會有一個根 POA,所有其它 POA 都是從根 POA 創建的。在這個簡單示例中,我已將實現專用的代碼分解為它自己的方法 runcalc()。
為實現創建一個環境將是我們的第一項任務,所以必須設置一個 POA。本來,CORBA 服務器使用基本對象適配器 (BOA),但是每個供給商的 BOA 都不一樣,在最新版本的 CORBA 規范中,POA 已完全取代了 BOA。
清單 5. SimpleCalcSvr.java -- 設置 POA
// 從始終存在的 rootPOA // 設置可移植對象適配器 org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper.narrow( orb.resolve_initial_references("RootPOA")); org.omg.PortableServer.POAManager manager = rootPOA.the_POAManager();
從標題和定義可以看出,這是一個簡單的示例。使用根 POA 而不創建新的 POA,將使事情變得簡單。POA 治理器是一種封裝了 POA 處理狀態的對象,所以,我們使用 POA 治理器,將發給 servant 的請求排隊。
還需要實例化實現:
清單 6. SimpleCalcSvr.java -- 實例化實現
// 創建計算程序接口的 servant SimpleCalcServant calcSvt = new SimpleCalcServant(); calculator calc = calcSvt._this(orb);
按照 CORBA 2.3 規范,所有 skeleton 均提供一個 _this() 方法,該方法使 servant 能得到目標 CORBA 對象的對象引用,servant 正是用目標 CORBA 對象來與這些請求相關聯的。
完成實現的實例化以后,就必須把機制放到適當的位置,以便客戶機能夠找到它們。有許多不同的方法和服務可用來找到滿足接口請求的對象。 CORBA Service 定義 Naming Service 和 Trader Services,來專門幫助客戶機查找對象,以處理請求。也可以通過方法調用來傳遞對象。
在這個示例中,我們將使用所有方法中最直截了當的一種 — 將對象引用寫入一個文件,該文件將由客戶機選取。對于所有的 ORB 來說,創建一個對象引用的字符串表示,或者反過來,創建由字符串到對象的引用,都是必備的功能。
清單 7. SimpleCalcSvr.java -- 編寫對象引用
// 將對象引用寫入一個文件 PrintWriter refstr = new PrintWriter ( new FileWriter("calcref.ior")); refstr.println(orb.object_to_string(calc)); refstr.close();
最后要做的一件事,就是激活 POA,使客戶機請求開始排隊,并強制服務器輸入其事件循環,以接收這些傳入的請求。
清單 8. SimpleCalcSvr.java -- 激活 POA
// 使實現成為可用 manager.activate(); System.out.println("SimpleCalcSvr is running!"); orb.run();
客戶機
假如您考慮一下正在發生的事件的機制,就會明白客戶機和服務器實際上正是互為映像的。客戶機將所有的參數打包以創建一個請求,然后以它自己的方式來發送這個請求。服務器只是將請求中的參數解包,執行運算,將返回值和輸出參數打包,然后向客戶機發回響應??蛻魴C則將返回值和輸出參數解包,然后繼續處理。這樣,客戶機打包什么,服務器就解包什么,反之亦然。
這意味著您將會看到客戶機和服務器具有相似的結構。客戶機還必須創建并初始化一個 ORB。它可以是我們正在使用的 ORB,也可以是另一個供給商提供的 ORB;但是,不能是任意的 ORB,而應該是支持 IIOP 的 ORB,IIOP 是由對象治理集團 (OMG) 定義的、基于 TCP/ip 的互操作性協議。假如您的 ORB 比較舊,那么請小心,它可能無法與其它 ORB 通話。

首先,我們以相同的方式創建 ORB,就像創建服務器一樣。
清單 9. SimpleCalcClient.java -- 初始化 ORB
java.util.Properties props = System.getProperties(); props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORG"); props.put("org.omg.CORBA.ORBSingletonClass", "com.ooc.CORBA.ORBSingleton"); org.omg.CORBA.ORB orb = null; // 初始化 ORB orb = ORB.init(args, props);
看起來眼熟?應該是這樣,它看起來與服務器完全一樣?,F在,客戶機已經連接到了一個 ORB 之上,但我們的目標是調用一個服務,而這個服務是在系統中別的地方提供的,需要找到能響應請求的對象。在這個示例中,這意味著要從創建于服務器上的文件中獲取一個對象引用。為了找到計算程序服務器,需要取得存儲在這個文件中的對象引用的字符串版本,然后把它轉換成對象引用,通過這個對象引用就可以進行調用了。
清單 10. SimpleCalcClient.java -- 獲取對象引用
System.out.println("Getting reference from string..."); BufferedReader in = new BufferedReader( new FileReader("calcref.ior") ; String ior = in.readLine(); in.close(); calculator calc = calculatorHelper.narrow( orb.string_to_object(ior));
請注重,這里使用了由 IDL-to-Java 編譯器生成的 calculatorHelper 類。calcref.ior 文件含有一個對象引用,而不是含有計算程序引用。calculatorHelper 類有一個 narrow 方法,可用來將抽象類型集中到特定的計算程序類型。
仔細看一看計算程序 calc,它表示計算機空間中另外某個地方的一個服務器。最后必須做的一件事,就是調用 calc 上的方法 add()。
清單 11. SimpleCalcClient.java -- 調用 add()
System.out.println( calc.add(2,3) ;
結論
已經討論了很多內容,不過請想一想,都學到了什么。我們的客戶機與服務器是完全隔離的,客戶機不知道服務器在什么樣的硬件上運行,使用的是什么操作系統,它是用什么語言編寫的,它是不是多線程的,還有,它位于何處 — 是在隔壁,還是距離半個地球之遙。它只知道一點,即假如它調用 calc 中的 add(),就會得到可以指望的響應。
提供服務的情形全都是這樣,電話或電力公司也是如此。當您拿起電話的時候,您所期望的是聽到拔號音,然后您的呼叫能暢通連接,您并不在乎電話是通過光纜傳輸的還是通過衛星轉發的,同樣的情況在信息產業中也正在成為現實。多虧有了 OMG 和這個基本結構,我們才得以加進這個既簡單而又非常有說服力的例子。
接觸CORBA內幕:IOR、GIOP和IIOP
(本文摘自IBM developerWorks)
Dave Bartlett
顧問、作家和講師
2000 年 8 月
內容:


網絡
IOR
存根
打包:GIOP 和 CDR
IIOP
結束語

 
7 月,我們創建了一個簡單示例 -- SimpleCalc。這個示例不值得多說;它是單一方法 add(),接受兩個 IDL long 型變量,返回一個 long 型變量。講授與學習 CORBA 的一個難題是:已知它是基于分布的客戶機和服務器,從一開始它就變得很復雜。必須立即與網絡打交道。所以,讓我們現在就來談談網絡。
網絡
假如將話題深入一點,將發現許多都值得探討,但又很簡單。我們簡單的計算器服務器設計成被遠程調用,CORBA 專門確保讓我們不必擔心客戶機環境和服務器環境之間的差異??蛻魴C對服務器的遠程調用是根據遠程過程調用 (RPC) 協議生成的,該協議自 20 世紀 80 年代就存在。RPC 是由各種通信模型經過多年測試得到的結果 -- 這是已經在產品環境中測試過的可靠且真實的技術。我們現在使用的 CORBA 模型就基于該模型。
圖 1. 網絡

可互操作對象引用 (IOR)
讓我們跟蹤方法調用。客戶機必須首先獲得計算器的實例。它通過使用 calculatorHelper.java narrow() 方法來達到這一目的。ior 是可互操作對象引用 (IOR) 的字符串表示,是從文件 calcref.ior 中檢索到的。這個文件是由服務器寫的,以便客戶機可以定位并連接到它。對 orb string_to_object() 的方法調用只取得 ior 字符串,并將它轉換成對象引用。以下是客戶機中的代碼,SimpleCalcClient.java:
calculator calc = calculatorHelper.narrow(orb.string_to_object(ior));System.out.println("Calling into the server");System.out.println( calc.add(2,3) ;
IOR 中有什么?IOR 是一個數據結構,它提供了關于類型、協議支持和可用 ORB 服務的信息。ORB 創建、使用并維護該 IOR。許多 ORB 供給商提供了一個實用程序來窺視 IOR 的內部。OOC (Object Oriented Concepts, Inc.) 的 Orbacus 附帶 IORDump.exe,假如您使用 Visibroker,它為您提供了 PrintIOR.exe。也有一些網站為您分析 IOR;可在 Xerox Parc 站點上找到我使用的一個實用程序。因為正在使用 Orbacus,我將對在 SimpleCalc 示例中創建的 IOR 運行 IORDump。得到以下輸出:

C:/_work/corbasem/_sources/calcsimpl>iordump -f calcref.iorIOR #1:byteorder: big endiantype_id: IDL:corbasem/gen/calcsimpl/calculator:1.0IIOP profile #1:iiop_version: 1.2host: 192.168.0.10port: 4545object_key: (36)171 172 171 49 57 54 49 48 "1/2 1/4 1/2 9610" 48 53 56 49 54 0 95 82 "05816._R"111 111 116 80 79 65 0 0 "ootPOA.."202 254 186 190 57 71 200 248 ".?.9G.." 0 0 0 0 "...."Native char codeset: "ISO 8859-1:1987; Latin Alphabet No. 1"Char conversion codesets: "X/Open UTF-8; UCS Transformation Format 8 (UTF-" "ISO 646:1991 IRV (International Reference Version)"Native wchar codeset: "ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit form"Wchar conversion codesets: "ISO/IEC 10646-1:1993; UCS-2, Level 1" "ISO 8859-1:1987; Latin Alphabet No. 1" "X/Open UTF-8; UCS Transformation Format 8 (UTF-" "ISO 646:1991 IRV (International Reference Version)"
IOR 中嵌入的是 type_id、IIOP 版本、主機地址和端口號,以及對象鍵。type_id 字符串是接口類型,眾所周知,它是資源庫標識格式?;旧希Y源庫標識是接口唯一的標識。這個標識可以是 DCE UUID 格式(COM 程序員比較熟悉它)或者是您指定的本地格式。 IIOP 版本將幫助 IOR 閱讀器(通常是 ORB)正確了解 IOR 是哪種格式,因為 OMG 總是改進規范,每個版本的閱讀方法都與以前版本略有不同 。主機地址和端口號將讓我們接觸到與期望的對象通信的 ORB。對象鍵和許多其它資料都是按特定于服務的信息的 OMG 標準構建的。這是幫助 OTB 支持服務器的特定于服務的數據。例如,這些專用 IOR 組件可以編碼 ORB 類型和版本,或者幫助支持 OMG 安全服務的 ORB 實現。以上大多數信息指定了字符代碼集轉換,這樣客戶機和服務器就能夠互相理解。
假如通過 Xerox Parc IOR 語法分析器運行 IOR,將得到以下輸出:
IIOP_ParseCDR: byte order BigEndian, repository id, 1 profile_IIOP_ParseCDR: profile 1 is 124 bytes, tag 0 (INTERNET), BigEndian byte order (iiop.c:parse_IIOP_Profile): bo=BigEndian, version =1.2, hostname=192.168.165.142, port =4545, object_key=<...1961005816._RootPOA......9G......>(iiop.c: parse_IIOP_Profile): encoded object key is <<?AC?9610058 16%00_RootPOA %00%00屎?G? %F8%00%00%00%00>(iiop.c:parse_IIOP_Profile)non-native cinfo is object key is <#AB#AC#AB196100 5816#00_RootPOA #00#00#CA#FE#BA #BE9G#C8#F8#00# 00#00#00>; no trustworthy most-specific-type info; unrecognized ORB; reachable with IIOP 1.2 at host "192.168.165.142", port 4545
IOR 中最主要的部分是幫助客戶機連接到服務器的那些部分。可以在 Xerox Parc IOR 閱讀器的輸出中看到這些部分。但是,其它許多信息是 Orbacus 專有的,其它 IOR 閱讀器不能解釋它。這些專用部分是作為附加到 IOR 的數據序列出現的,并且只有構建 IOR 的 ORB 才懂得這些數據。
存根
現在,我們知道 IOR 帶來了什么功能。IOR 的目的就是使客戶機能夠連接到服務器,以便它能夠完成方法調用??蛻魴C必須用 Add 方法將 IOR 轉換成它可以調用的實際對象。這是通過使用從 IDL 編譯器中生成的兩個 Java 文件來完成的。客戶機將首先使用 calculatorHelper 對象將 IOR 的范圍縮小到 _calculatorStub 代理對象。
以下是 Orbacus 附帶的 jidl 編譯器生成的 narrow() 方法:
public static calculator narrow(org.omg.CORBA.Object _ob_v) { if(_ob_v != null) { try { return (calculator)_ob_v; } catch(ClassCastException ex) { } if(_ob_v._is_a(id())) { org.omg.CORBA.portable.ObjectImpl _ob_impl; _calculatorStub _ob_stub = new _calculatorStub(); _ob_impl = (org.omg.CORBA.portable.ObjectImpl)_ob_v; _ob_stub._set_delegate(_ob_impl._get_delegate()); return _ob_stub; } throw new org.omg.CORBA.BAD_PARAM(); } return null;}

可以看到,它最主要的任務是創建一個新的 _calculatorStub 對象。_calculatorStub 充當駐留在服務器上的實際計算器對象的代理對象。假如您不了解代理模式,我將非常樂意向您介紹“四人組”Design Patterns 一書。實際上,代理模式無非是創建一個代表或充當另一個實際對象的替身的對象,另一個對象將最終將調用或執行服務。代理模式是一種重要且常用的模式。在所有分布式設計中都會用到它。我敢打賭,您肯定用過這種模式,只不過從沒有稱您的設計為代理模式。
一旦創建了 _calculatorStub,它就代表客戶機的計算器接口。add 方法在服務器中實現,而該服務器在 IOR 中定義的地址上的電腦空間中運行。至此,這就所調用的 add() 方法。這里,需要注重兩點:首先,我們必須以 _calculatorStub 的形式調用 add 方法。其次,請注重客戶機將中斷直到調用返回,就像其它同步方法調用一樣。這是一種請求響應協議,它模擬單進程應用程序。編程客戶機,然后使用該請求響應協議執行客戶機就像用庫和 API 調用創建的常用編程開發環境一樣普通自然。這并不表示您不能使用異步調用;您當然可以生成那種類型的調用。我將在以后的專欄文章中討論那些話題。
打包:GIOP 和 CDR
至此,在體系結構中,我們已成功欺騙了客戶機,使它相信服務與它在一起。但事實并為如此,并且在以后幾步中,我們必須將數據和方法調用鑄造成一種形式,它答應在網絡上繼續該調用,并且可以在另一端使用該調用。這并不是無關重要的,且這種模型已經問世好幾年了。您也許已經多次見過 OSI 模型了,在圖 2 中,您將看到 OSI 模型,旁邊就是 OMG 所使用的模型。
圖 2. OSI 的結構 vs. GIOP 協議堆棧

客戶機調用接口操作時,它必須將操作數據(in 和 inout 參數)發送到服務器。此時的困難在于將數據轉換成公共格式,這樣服務器抽取操作數據時不會誤解或錯誤對齊數據。因為服務器可以是任意數量不同的平臺,我們應該預計到客戶機和服務器之間的體系結構差異。CORBA 通過嚴格定義如何將數據轉換或打包成公共格式來處理這種問題。然后在連接的另一端重新組成或解包數據。這是通過用最基本的結構表示數據來完成的,最基本的結構就是字節流,也就是八位元流。
CORBA 規范將八位元流定義成“一種抽象表示法,通常對應于要通過 IPC 機制或網絡傳輸來發送到另一個進程或另一臺機器的內存緩沖區”。IDL 八位元準確映射成 Java 字節。它們都是 8 位值,客戶機或服務器都不打包這種值。將這些參數轉換成八位元序列的根本目的是產生用于信息交換的基本結構。
現在,我們應當窺視 _calculatorStub 生成的代碼的內部信息。請記住這不是由我編寫的 -- 它是由 Orbacus 附帶的 IDL-到-Java 編譯器 jidl 生成的。

【發表回復】【進入論壇此帖】【關閉】
yuxq 回復于:2003-09-17 18:49:03
//// IDL:corbasem/gen/calcsimpl/calculator/add:1.0//public int add(int _ob_a0, int _ob_a1) { System.out.println("Inside _calculatorStub.add()"); while(true) { if(!this._is_local()) { org.omg.CORBA.portable.OutputStream out = null; org.omg.CORBA.portable.InputStream in = null; try { out = _request("add", true); out.write_long(_ob_a0); out.write_long(_ob_a1); in = _invoke(out); int _ob_r = in.read_long(); return _ob_r; } catch(org.omg.CORBA.portable.RemarshalException _ob_ex) { continue; } catch(org.omg.CORBA.portable.applicationException _ob_aex) { final String _ob_id = _ob_aex.getId(); in = _ob_aex.getInputStream(); throw new org.omg.CORBA.UNKNOWN("UneXPected User Exception: " + _ob_id); } finally { _releaseReply(in); } } else { org.omg.CORBA.portable.ServantObject _ob_so = _servant_preinvoke("add", _ob_opsClass); if(_ob_so == null) continue; calculatorOperations _ob_self = (calculatorOperations)_ob_so.servant; try { return _ob_self.add(_ob_a0, _ob_a1); } finally { _servant_postinvoke(_ob_so); } } }}
要注重的部分是包含 _request()、write_long() 調用,和 _invoke() 及隨后的 read_long()。對 _request() 的調用使用要調用的方法名稱,和顯示是否需要響應的布爾 (boolean) 值。它返回 CORBA 規范指定的 org.omg.CORBA.portable.OutputStream 對象。對于可移植性,這是必要的,因為 Java 經常被下載,并且依靠于它運行的機器上的公共庫。對于 ORB 是這樣,對于 IO 也是這樣。因此,CORBA 規范為 Java 語言定義了比其它語言更廣泛的可移植類型集合。

通用 ORB 間協議 (GIOP)
通用 ORB 間協議 (GIOP) 用來為這個由不同計算機及其各種體系結構組成的凌亂世界中傳送消息定義結構和格式。假如使用 GIOP 的結構和格式,并將它們應用于 TCP/IP,那么就得到 IIOP。GIOP 有兩個版本:1.0 和 1.1。這就意味著我們的消息根據其符合的 GIOP 版本可能有不同的格式。
至此,我們必須看一下 GIOP 以了解請求在變成正確格式化的 CORBA 請求時所要經歷的操作。盡管我們將仔細研究請求,響應只是請求的鏡像圖像。假如您知道請求的工作原理,那么您就能了解響應。
GIOP 請求消息分成三部分:GIOP 消息頭、GIOP 請求頭和請求主體。GIOP 消息頭表示這就是一條 GIOP 消息。它包含 GIOP 版本、消息類型、消息大小,然后根據您是使用 1.0、1.1 還是 1.2,包含字節次序 (GIOP 1.0) 或一個位標志字段,該字段包括字節次序以及一些保留位標志。GIOP 1.1 添加了對消息存儲碎片的支持,GIOP 1.2 添加了雙向通信支持。更新的版本都是向下兼容的。
公共數據表示 (CDR)
公共數據表示 (CDR) 是 CORBA 調用中將使用的數據類型的正式映射??蛻魴C生成請求時,它不必知道請求要發送到什么地方,或者哪一臺服務器將響應該請求。CORBA(作為規范)和 GIOP(作為規范的一部分,定義消息結構和傳送)被設計成答應實現一個接口的可能的多種不同服務器之一來響應請求。規范必須定義如何打包操作中的數據,這樣所有可能的服務器都可以抽取參數并調用遠程操作,并且數據轉換不會產生多義性。這種轉換問題的典型示例就是指針。客戶機中的指針對于在另一臺機器上運行另一個進程的服務器意味著什么?毫無意義。或者,變量如何在使用不同尋址方案(大尾數法,小尾數法)的機器間發送?這些數據類型必須轉換成服務器能夠理解并使用的流。顯然,CORBA 規范在公共數據表示方面是十分具體的。這是我們不必涉足的細節層次,但假如您想要了解具體信息,請閱讀規范或 Ruh、Herron 和 Klinkeron 合著的 IIOP Complete 一書。
一旦包裝了所有數據,就將使用 IOR 中的信息來創建連接。您可以區別 IOR 的結構,通常必須使用 TCP 作為傳送機制。但是,也可以使用其它傳送(再次提醒,請參閱 CORBA 規范以獲取具體信息)。ORB 守護程序負責查找 IOR 指定的對象實現,以及建立客戶機和服務器之間的連接。一旦建立了連接,GIOP 將定義一組由客戶機用于請求或服務器用于響應的消息??蛻魴C將發送消息類型 Request、 LocateRequest、CancelRequest、Fragment 和 MessageError。服務器可以發送消息類型 Reply、 LocateReply、CloseConnection、Fragment 和 MessageError。
假如我們扯開 GIOP 消息,它看上去就像:
0x47 0x49 0x4f 0x50 -> GIOP, the key0x01 0x00 -> GIOP_version0x00 -> Byte order (big endian)0x00 -> Message type (Request message)0x00 0x00 0x00 0x2c -> Message size (44)0x00 0x00 0x00 0x00 -> Service context0x00 0x00 0x00 0x01 -> Request ID0x01 -> Response expected0x00 0x00 0x00 0x24 -> Object key length in octets (36)0xab 0xac 0xab 0x31 0x39 0x36 0x31 0x300x30 0x35 0x38 0x31 0x36 0x00 0x5f 0x520x6f 0x6f 0x74 0x50 0x4f 0x41 0x00 0x000xca 0xfe 0xba 0xbe 0x39 0x47 0xc8 0xf80x00 0x00 0x00 0x00 -> Object key defined by vendor0x00 0x00 0x00 0x04 -> Operation name length (4 octets long)0x61 0x64 0x64 0x00 -> Value of operation name ("add")0x20 -> Padding bytes to align next value
您應該了解大概情況了。這種消息流是高度結構化的。它也必須是,為了客戶機可以創建服務器可以轉換成實現的消息 -- 不管實現如何運行,或在哪里運行。服務器也必須為在響應客戶機時使用的返回值和參數執行相同操作。此消息格式在 OMG 成就中非常重要,因為它可以實現可移植性和互操作性目標。這種可移植性將給予您我們在第一篇專欄文章中談到的自由。您無需關心硬件、數據庫或編程語言。只要關心您的信息就行了。
IIOP
我們還沒有徹底結束。GIOP 是 CORBA 方法調用的核心部分。GIOP 不基于任何非凡的網絡協議,如 IPX 或 TCP/IP。為了確?;ゲ僮餍裕琌MG 必須將 GIOP 定義在所有供給商都支持的特定傳輸之上。假如有具體和簡潔的消息規范,則不會提供互操作性,因為所有供給商使用不同的傳送機制來實現這個互操作性。因此,OMG 在最廣泛使用的通信傳輸平臺 -- TCP/IP 上標準化 GIOP。GIOP 加 TCP/IP 等于 IIOP!就這么簡單。
需要使用已發布對象服務的客戶機將使用 IOR 中的值來啟動與對象的連接。我們已經繞了一個圈子,又回到了 IOR。IOR 對于 IIOP 是至關重要的,任何要對某個對象調用方法的客戶機都要將“請求”消息發送到 IOR 中具體說明的主機和端口地址。在主機上,服務器進程在請求進入時會偵聽端口,并將那些消息發送到對象。這就要求服務器主動偵聽請求。
生活有陰陽兩面,每件事都有缺點,互操作性和 IIOP 也不例外。OMG 推出和運行了 IIOP,對比 ORB 供給商它們自己的服務器上實現此功能,并且沒有服務器方可移植性的年代,這是一大改進。但假如要求服務器是位置無關的,我們應該做什么?假如主機和端口值嵌入 IOR 中,每當您將對象從一個服務器移到另一個服務器,以均衡負載時,這個問題就會忽然出現??上驳氖沁@個問題已經解決了;但又有一條壞消息,每家供給商的解決方法都不同。
結束語
現在,將負載均衡話題留到將來討論。假如您在幾年前有 CORBA“經驗”(也就是說在一段時期內),而現在從事另一項研究,我相信您將感到驚喜。CORBA 規范已經獲得很大進步,可以確保您為一個 ORB 編寫的服務器代碼可以移植到運行另一個 ORB 的另一臺服務器上。解決方案非常簡單,并且以經典的協議為基礎??蛻魴C和服務器間的標準交換語法基于某些 OMG 具體說明的需求。OMG 通過使用網絡尋址協議 (IIOP) 獨立于消息傳遞協議 (GIOP),為其規范創建了更多功能。這也確保隨著信息工業的變動(的確發展很快),CORBA 仍能跟上它的步伐。我最喜歡的是,對于我們剛討論的關于如何使之成功完成的 CORBA 對象調用,我不必編寫代碼!在 ORB 中和用 IDL 標準化接口的功能中已經概括了網絡測量和打包的具體信息。

OMG 接口定義語言
----定義分布式服務的能力
(本文摘自IBM developerWorks)
Dave Bartlett
顧問、作家和講師
2000 年 9 月
內容:


IDL 基本類型
用戶定義的類型
常數定義
用戶異常
數組、序列、字符串
名稱和作用域
接口
結束語

 
一切都要從接口定義語言 (IDL) 開始。當我們采用 RPC 或 COM 技術以及 CORBA 技術來編寫分布式系統時都需要它。在各種情況下,接口定義語言提供了將對象的接口與其實現分離的能力。IDL 提供了抽象,它提供了將事務與其具體實現分離的概念。它還為我們提供了一套通用的數據類型使得我們可以使用它們來定義更為復雜的類型。我們將采用所有這些數據類型來定義分布式服務的功能。IDL 的另一個好處是它剝離了編程語言和硬件的依靠性。本文探討了 OMG IDL 的內置類型和要害字。
IDL 是一種規范語言。它答應我們從實現中剝離對象的規范(如何與它交互)。這是一個約定:“客戶機女士,假如您要調用這個方法,請傳送這些參數,然后我,服務器先生,將把這個字符串數組返回給您?!笔褂眠@個接口的客戶機程序員不知道接口背后的實現細節。
OMG IDL 看上去很像 C 語言。這就很輕易將這兩種語言以及它們的要害字做比較。但是,這種相似性只流于表面。每種語言的目的是完全不同的。我們在討論這種語言時,您已經記住 OMG IDL 的目的是定義接口和精簡分布對象的過程。
IDL 基本類型
OMG 接口定義語言有一些看上去應該很熟悉的基本類型。以下就是這些內置類型的表:
表 1. IDL 基本類型
類型 范圍 最小大?。ㄒ晕粸閱挝唬?br />short -215 到 215-1 16
unsigned short 0 到 216-1 16
long -231 到 231-1 32
unsigned long 0 到 232-1 32
long long -263 到 263-1 64
unsigned long long 0 到 264-1 64
float IEEE 單精度 32
double IEEE 雙精度 64
long double IEEE 雙字節擴展浮點數 15 位指數,64 位帶符號小數
char ISO Latin-1 8
wchar 從任何寬字符集編碼寬字符,如 Unicode 依靠于實現
string ISO Latin-1,除了 ASCII NUL 以外 可變化
Boolean TRUE 或 FALSE 未指定
octet 0 到 255 8
any 自己描述的數據類型,可表示任何 IDL 類型 可變化
整數類型
OMG IDL 的整數類型非常簡單。雖然它沒有提供 int 類型,但它不會受到 int 在不同平臺上的取值范圍不同所帶來的多義性的困擾。然而,IDL 確實提供幾種整數類型,2 字節 (short)、4 字節 (long) 和 8 字節 (long long) 的整數類型。
所有這些整數類型都有相應的無符號數類型。這對于 Java 程序又產生了問題,因為 Java 編程語言不支持無符號數類型。盡管這不是 OMG IDL 的特性,它還是在 Java-to-IDL 的映射中創建了一種獨有的局面,我們將在下個月的專欄文章中討論 Java-to- IDL 的映射。但在此之前,您已經考慮如何將 IDL 中的 unsigned short 映射成一種 Java 類型。使用 Java short 還是 Java int?它們各自的利弊是什么?這些是語言映射的作者必須努力解決的問題,并且這是一個很好的練習,可以幫助您為閱讀下一篇專欄文章做好預備。
浮點類型
OMG IDL 浮點數類型 float、double 和 long double 遵循 IEEE 754-1985 二進制浮點數算術的標準。目前,long double 用于巨大數字,您也許會發現您的非凡語言映射還不支持這種類型。
char 和 wchar
我們都使用相同的術語,字符集就是字母或其它構成單詞的字符以及其它本機語言或計算機語言的基本單元的集合。編碼字符集(或代碼集)是一組明確的規則,它建立了字符集和集合的每個字符與其位表示法之間的一一對應關系。
處理 char 時,必須記住 OMG IDL 必須分兩個層次處理字符集。首先必須明確規定從哪個字符集生成 IDL 定義。詞法約定(表示 IDL 文件的要害字、注釋和文字的字符記號)規定 ISO 8859.1 字符集表示 IDL 文件中的字符。是的,連 IDL 都必須有一個標準字符集,它將構建在這個字符集上。ISO 464 定義了空字符(null)和其它圖形字符。
接著,OMG 必須處理從一個計算機系統到另一個計算機系統之間的字符傳輸。這意味著可能涉及到從一個字符代碼集到另一個字符代碼集的轉換,這取決于語言綁定。在上個月的專欄文章中,我們對 Orbacus Object Reference 執行了 IORDump 操作,并且發現了以下信息:
Native char codeset: "ISO 8859-1:1987; Latin Alphabet No. 1"Char conversion codesets: "X/Open UTF-8; UCS Transformation Format 8 (UTF-" "ISO 646:1991 IRV (International Reference Version)"Native wchar codeset: "ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit form"Wchar conversion codesets: "ISO/IEC 10646-1:1993; UCS-2, Level 1" "ISO 8859-1:1987; Latin Alphabet No. 1" "X/Open UTF-8; UCS Transformation Format 8 (UTF-" "ISO 646:1991 IRV (International Reference Version)"
可以看到,IOR 可以包含代碼集信息,以在轉換時協調首選代碼集和可用代碼集。

解決了所有問題后,您應該知道 OMG IDL char 是一個 8 位變量,可以用兩種方法表示一個字符。首先,它可以從面向字節的代碼集編碼單字節字符,其次,當在數組中使用時,它可以從多字節字符集(如 Unicode),編碼任何多字節字符。
Wchar 只答應大于 8 個字節的代碼集。規范不支持非凡的代碼集。它答應每個客戶機和服務器使用本機的代碼集,然后指定如何轉換字符和字符串,以便在使用不同代碼集的環境之間進行傳輸。
Boolean
這里沒有什么可以多說的 -- Boolean 值只能是 TRUE 或 FALSE。
Octet
octet 是 8 位類型。因為保證了 octet 在地址空間之間傳送時不會有任何表示更改,因此這就使它變成了一種非常重要的類型。這就表示您可以發送二進制數據,并且知道當將它打包時,它的形式仍然相同。其它每種 IDL 類型在傳輸時都有表示變化。例如,根據 IOR 代碼集信息的指示,char 數組會經歷代碼集轉換。而 octet 數組卻不會。
any 類型
IDL any 是一種包含任何數據類型的結構。該類型可以是 char 或 long long 或 string 或另一種 any,或者是已經創建的一種類型,如 Address。any 容器由類型碼和值組成。類型碼描述 any 的值部分中的內容是什么。
假如您擁有 C++ 經驗,則可以將 any 看作是自我描述的數據類型,它類似于 void *,但更安全。假如有 Visual Basic 經驗,可以將 any 看作類似于 variant。當我們討論 IDL-to-Java 映射時,any 類型的結構和它如何對用戶定義的類型產生作用將變得一目了然。
用戶定義的類型
基本類型是必不可少的;它們為接口定義提供了構件塊。OMG IDL 為您提供了定義您自己的類型的能力,這可以幫助減少復雜程度并且讓您可以根據基本類型組成更精巧的數據類型。這些復雜的類型可以是枚舉、結構和聯合,或者您可以使用 typedef 來創建類型的新名稱。
命名的類型
應該使用 typedef 創建新的類型名稱,這將幫助解釋接口或保存輸入。
例如,您也許想在方法 PresentWeather(..., in float Pressure, ...) 中傳送氣壓值。假如在該方法中使用 typedef float 語句,這將使該方法更具可讀性。
typedef float AtmosPressure;
在 C++ 中,typedef 要害字表示類型定義,實際上別名也許是更為精確的術語。對于 OMG IDL,也許是這樣,也許不是,這取決于其所映射到的實現語言。CORBA 規范不保證 short 的兩種 typedef 是兼容的和可互換的。
在文體上,應注重不要為現有類型創建別名。您應該嘗試創建不同概念的類型,它將為您的 IDL 添加可讀性和可擴展性。最好是明確定義一次邏輯類型,然后在整個接口中不斷使用該定義。
枚舉
OMG IDL 枚舉是將名稱附加到數字的一種方法,從而讀取代碼的人就可以了解到更多的含義。OMG IDL 版的枚舉看上去象 C++ 版本的枚舉。
enum CloudCover{cloudy, sunny};
CloudCover 現在就成為可以在 IDL 中使用的一種新類型。由于在一個枚舉中可以有最多 232 個標識,OMG IDL 保證枚舉被映射到至少 32 位的類型。規范中沒有規定標識的有序數值,但它規定了將保持順序。因此,不能假設 cloudy 永遠擁有序數值 0 -- 某些語言映射可能將 1 賦值給它。但可以確保 cloudy 小于 sunny。
假如認為 IDL 的目的是定義跨各種系統的接口,那么不指定序數值是明智的。您只將值發送到服務器。即, "cloudy"。在服務器空間中,cloudy 可以由 0、1 或如何實現語言規定的值表示。某些實現語言不答應您控制序數值,而 C++ 答應。OMG IDL 不答應空的枚舉。
結構
struct 要害字提供了將一組變量集中到一個結構的方法。一旦創建了,struct 表示可以在整個接口定義中被使用的新類型。
struct Date { short month; short day; long year;};
定義 struct 時,要確保所創建的類型是可讀的。不要在不同的名稱空間中創建幾個不同的同名結構,這只會使 IDL 的用戶搞糊涂。
識別聯合
OMG CORBA 規范將 IDL 聯合描述成 C 聯合類型和 switch 語句的混合物。IDL 識別聯合必須有一個類型標記字段用于確定在當前實例中使用哪個聯合成員。像 C++ 一樣,一次只能有一個聯合成員是活動的,并且可以從其識別名稱來確定該成員。
enum PressureScale{customary,metric};union BarometricPressure switch (PressureScale) { case customary : float Inches; case metric : default: short CCs;};
在以上示例中,假如識別名稱是 metric,或者使用了不能識別的識別名稱值,那么 short CCs 就是活動的。假如識別名稱是 customary,那么 float 成員 Inches 是活動的。聯合成員可以是任何類型,包括用戶定義的復雜類型。識別名稱類型必須是整數類型(short、long、long long 等,以及 char、boolean 或 enumeraton)。
常數定義
在 IDL 中定義常數的語法和語意與 C++ 一樣。常數可以是整數、字符、浮點數、字符串、Boolean、octet 或枚舉型,但不能是 any 類型或用戶定義的類型。這里有一些例子:
const float MeanDensityEarth = 5.522; // g/cm^3const float knot = 1.1508; // miles per hourconst char NUL = '/0';
可以用十進制、十六進制或八進制記數法定義整數常數:
const long ARRAY_MAX_SIZE = 10000;const long HEX_NUM = 0xff;
對于指數和小數,浮點字符使用常用的 C++ 約定:
const double SPEED_OF_LIGHT = 2.997925E8;const double AVOGADRO = 6.0222E26;

字符和字符串常數支持標準換碼序列:
const char TAB = '/t';const char NEWLINE = '/n';
只要沒有混合的類型表達式,就可以在常數說明中使用算術運算符。
用戶異常
IDL 答應創建異常來指出錯誤條件。IDL 用戶異常類似于一個結構,在這個結構中,異??梢园x類型的任意多錯誤信息。最終是從方法中使用異常。這里有一個例子:
exception DIVIDE_BY_ZERO { string err;};interface someIface { long div(in long x, in long y) raises(DIVIDE_BY_ZERO);};
異常將創建名稱空間 -- 因此,異常中的成員名必須是唯一的。異常不能當作用戶定義類型的數據成員使用。OMG IDL 中沒有異常繼續。
數組、序列和字符串
每次只傳送一個元素是可以的,但我們通常有一個列表或向量或矩陣的信息要在客戶機和服務器之間往返傳送。數組幾乎是所有編程語言所共有的類型,但一種語言的數組與另一種語言的數組實現通常是不同的。OMG IDL 開發者面臨的挑戰是創建一組數組類型,它可以輕易地被映射到實現語言中。這種需求產生了 IDL array 和 sequence。string 類型是一種非凡的序列,它答應語言使用它們的字符串庫和優化。
數組
OMG IDL 有任意元素類型的多維固定大小的數組。所有數組都必須是有界的。數組非常適合于與擁有固定數量元素的列表一起使用,而這些元素通常都是存在的。例如:
// bounded and unbounded array examplestypedef long shares[1000];typedef string spreadsheet[100][100];struct ofArrays { long anArray[1000];};// unbounded arrays NOT ALLOWED// typedef long orders[];
必須指定數組維數,并且它們必須為正的整型常量來表示。IDL 不支持在 C 和 C++ 中的開放數組,這是因為沒有指針支持。必須出現 typedef 要害字,除非指定的數組是結構的一部分。
在許多實例中,CORBA 規范所沒有提及的內容與它提及的內容是一樣重要的。規范不以任何方式、形態或形式指定數組下標編排方法。這表示從一種實現語言到另一種實現語言的數組下標可以是不同的,這樣您不能假定將數組下標從客戶機發送到服務器時,服務器會調整并指向正確的數組元素。某些語言的數組下標從 0 開始,而其它的則是從 1 開始。
序列
在開發接口定義時,會大量使用序列。假如正在處理數據數組,其中許多值相同,那么序列就可以提供靈活性。
序列是變長向量,它有兩個特征:元素的最大大小,在編譯時確定,可以是無限的;長度,在運行時確定。序列可以包含所有類型的元素,不管是基本類型還是用戶定義的類型。
序列可以是有界的,也可以是無界的。例如:
// bounded and unbounded sequence examplestypedef sequence<long> Unbounded;typedef sequence<long, 31> Bounded;
一個無限序列可以擁有任意多個元素,只會受到平臺內存大小的限制。有限序列則有邊界限制。這兩種序列都可以不包含元素、用戶定義的類型,但可以包含其它序列。
string 和 wstring
string 等價于 char 的序列,而 wstring 表示 wchar 的序列。作為 C 和 C++ 的折衷, OMG IDL string 和 wstring 可以包含任何字符,除空字符以外。char 或 wchar 約定確定了類型為 string 的元素大小由 8 個字節表示,wstring 類型的元素大小是 16 個字節或更多。
IDL 中的字符串很非凡,然而在大多數語言中字符串都很非凡。許多語言都用庫和非凡優化來處理字符串處理。通過將字符串歸到它自己的類型,OMG 答應語言映射使用非凡優化,這些優化不會與通用序列一起處理。
名稱和作用域
所有 OMG IDL 標識都是區分大小寫的。這意味著將把兩個只有字符大小寫不同的標識看作是彼此的重新定義。應該注重根據區分大小寫的語言,所有的定義引用必須與定義的大小寫相同。
IDL 作用域規則非常易于把握。整個 OMG IDL 內容和通過預處理器偽指令傳入的所有文件共同組成了命名作用域。任何未出現在某個作用域中的定義都是全局作用域的一部分 -- 只有一個全局作用域。在全局作用域中,以下定義組成了作用域:module、interface、struct、 union、operation 和 exception。
module 要害字用于創建名稱空間;這是其唯一目的。您定義的模塊將創建一個邏輯組,模塊的自由使用防止了全局名稱空間的污染。根或全局空間被認為是空的,文件掃描中每次碰到模塊要害字時,字符串 "::" 和其標識都會附加到當前根的名稱后面。這就可以通過包括其它名稱作用域來引用其它模塊中的類型,如以下示例中的 Pennsylvania::river。
一個標識可以在一個作用域中定義一次,但可以在嵌套作用域中重新定義。下例將解釋這些要點:
module States { // error: redefinition // typedef sequence<string> states; module Pennsylvania { typedef string river; interface Capital { void visitGovernor(); }; }; module NewYork { interface Capital { void visitGovernor(); }; interface Pennsylvania { void visit(); }; }; module NewJersey { typedef Pennsylvania::river NJRiver; // Error // typedef string Pennsylvania; interface Capital { void visitGovernor(); }; };};
每個內部模塊(Pennsylvania、New York 和 New Jersey)都有一個接口 Capital 和一個操作 visitGovernor()。但它們并不相互牽連,因為它們在各自的模塊中。當我們嘗試在模塊 States 中創建一個同名序列時,碰到了一個重新定義 'State' 的問題。重新定義 Pennsylvania 發生在已經將它介紹為 New Jersey 中 'NJRiver' 的作用域解析標識之后。請注重,我們在帶有接口 Pennsylvania 的 New York 模塊中沒有發生錯誤,因為通過某些作用域解析標識介紹外部 Pennsylvania 模塊。

接口
現在該定義接口了,它是我們學習 OMG 接口定義語言的首要原因。有一個好方法來理解 IDL 接口:它指定了服務實現和使用它的客戶機之間的軟件約定。讓我們開始定義接口吧,這將運用我們所學到的 IDL 知識。由于這一切都與通信有關,就讓我們看一些定義 Listener 和 Speaker 的 IDL。Listener 必須連接到 Speaker,然后 Speaker 將消息傳送給 Listener。這是一個回調的例子。
// Thrown by server when the client passes// an invalid connection id to the serverexception InvalidConnectionIdException{ long invalidId;};// This is the callback interface that// the client has to implement in order// to listen to a talker.interface Listener{ // Called by the server to dispatch messages on the client void listen(in string message); // Called by the server when the connection // with the client is successfully opened void engage(in string person); // Called by the server when the connection with the client is closed void disengage(in string person);};// interface on the server sideinterface Speaker{ // Called by the client to open a new connection // Returned long is the connection ID long register(in Listener client, in string listenerName); // Makes the server broadcast the message to all clients void speak(in long connectionId, in string message) raises(InvalidConnectionIdException); // Called by the client to sever the communication void unregister(in long connectionId) raises(InvalidConnectionIdException);};
使用這個定義,我們定義了兩個新的 CORBA 接口類型:Listener 和 Speaker。每個接口都有一些方法,它們將由連接的另一端使用。客戶機將通過獲取對實現 Speaker 接口的服務器對象的初始對象引用來啟動連接。這個對象引用可以傳送給客戶機,或者可以從命名服務中檢索到這個引用。最重要的是,客戶機首先聯系 Speaker。接著,客戶機(即 Listener,因為它實現 Listener 接口)必須注冊到 Speaker,并將引用傳給 Listener 接口。這就使它們可以從 Speaker 處接收到消息。
要注重的一點是在 register 方法中 Listener 接口被當作一個類型使用。接口名稱變成了類型,可以當作參數傳送。看上去就像在傳送 Listener 對象,但實際是一個對象引用。這是提供位置透明性的 CORBA 模型的另一個示例。
有一點值得注重,每個對象引用 (IOR) 僅指向一個接口。每個接口都披露一個或多個分布式對象的具體信息。我說“一個或多個”是因為可以有幾千個對象實現分布式系統中的同一個接口。在這個示例中,Speaker 可以將消息發送到幾千個 Listeners。因而在某種程度上,IDL 接口對應于類定義,CORBA 對象對應于類實例。
結束語
對于 OMG IDL,我只是介紹了其的皮毛。顯而易見,OMG IDL 提供了一組內容豐富的內置類型和要害字,它們可以用來為與分布式系統中的對象的交互創建嚴密的描述。由于這種語言類似于 C 語言,您應該了解所有使 C 語言變得如此成功的描述功能。所有 OMG 服務定義都是用 IDL 編寫的,證實 OMG IDL 的強大功能。所有垂直市場標準化努力(Financial、CORBAMed 等)都是用 IDL 編寫的,這證實了其靈活性。
學習正確和有效地使用 OMG IDL 是您開始學習 CORBA 和編寫優秀的分布式系統的良好起點。每件事都從 IDL 開始,假如您在項目開始時正確運用了 IDL,那么您成功的機會會成倍增長。
IDL-to-Java的映射(1):
怎樣將離散的構件接口定義轉換為 Java 元素
(本文摘自IBM developerWorks)
Dave Bartlett
顧問,作家,講師
2000年10月
內容:


前提
IDL-to-Java 庫
基本數據類型
holder 類
結論

這篇文章開始闡述 IDL-to-Java 的映射。這個月的專欄介紹基本的數據類型、結構和數據傳遞。下個月我們將會介紹更加復雜的類型。語言映射并非無足輕重,COBRA 規范中有很大一部分闡述的就是多語言映射。
COBRA 規范具體說明了接口定義語言(IDL)并具體說明了 IDL 到幾種編程語言的映射,如 C,C++,ADA,COBOL, Lisp,Smalltalk 和 Java。IDL 的優勢在于它完整而具體描述了接口及操作參數。 IDL 接口提供了開發使用接口操作的 Client 和實現接口的 Server 所需要的信息。當然,Client 和 Server 并沒有在接口中編寫,IDL 只是一種純粹的描述性語言。 Client 和 Server 用完全意義上的編程語言來編寫。IDL 語言映射應該為接口定義提供一致的、可移植的構架。那么這些映射的接口就可以在 Server 端實現,或者像其它方法一樣由 Client 端調用。對于使用的每一種編程語言來說,都需要有一種映射來方便的轉換已定義的 IDL 概念。 IDL 概念到 Client 語言結構的映射取決于編程語言的結構和能力。例如,一個 IDL 異常(exception)在不提供 exception 的語言中可能被映射為結構(structure),而在提供 exception 的語言中就可以直接映射為 exception。每種語言的特性和效率必須與之相適應。

IDL 到編程語言映射的前提
所有的語言映射都有近似的結構。它們必須定義語言中的表達方法:
· 所有的 IDL 基本數據類型
· 所有的 IDL 結構數據類型
· IDL 中定義的常量
· IDL 中定義的對象引用
· 對操作的調用,包括傳遞參數和接收結果
· 異常,包括當操作產生異常時的處理和訪問異常參數的方法
· 屬性訪問
· ORB 定義的操作符號,如動態調用接口,對象適配器等等。
一個完整的語言映射答應程序員以對于某種特定編程語言來說很便捷的方式來訪問所有的 ORB 功能。為了支持源代碼的可移植性,所有的 ORB 實現都要支持某種語言的同一映射。
MotherIDL
在本文中將使用一個叫做 MotherIDL 的文件-- motheridl.idl。以上要求這一 IDL 文件都可以做到,它的目的就是示意并檢驗部分映射。你最好先瀏覽它一下,這樣我們逐步講述的時候你就會對它比較熟悉了。
為了檢驗映射,你需要一個 IDL-to-Java 的編譯器。每個 CORBA ORB 都至少帶有一個 IDL 到某種語言的編譯器。它們大多針對 C++ 或 Java 編程語言,當然也有其它的。新增加的還有針對 Python 和 Delphi 的。本欄我們要使用 Object Oriented Concepts, Inc. 的 Orbacus ORB 所帶的 JIDL。(見 參考資料) 當然你也可以使用任何 IDL 到 Java 的編譯器,但是要確定它兼容 CORBA 2.3,因為假如編譯器的版本較早的話你的結果可能有本質的區別。
現在首先要做的就是運行 IDL-to-Java 的編譯器來編譯 motheridl.idl.
jidl --output-dir . . /. . /. . MotherIDL.idl
這一步很奇妙,它在提供支持和通用 CORBA 通道的同時給出了一大堆 IDL 文件所映射的 Java 文件。
IDL-to-Java 的庫結構
我們要學習的第一個映射是 IDL 要害詞 module 到 Java 的要害詞 package 的映射。這是一個簡單的完全映射。假如在 IDL 文件中有要害詞 module ,你的 IDL 到 Java 編譯器將會用要害詞 package 生成一個 Java 類的目錄結構和庫結構。(假如你對于 Java 程序中如何使用要害詞 package 還有什么困惑的話,那你現在應該去復習一下了。)這一映射規定了從 IDL 生成的大部分結構,對 IDL 到 Java 的映射有著重要影響。
以 motheridl.idl 為例,你將在 IDL 文件中看到如下結構:
module corbasem { module gen { module motheridl { module holderexample { ... }; module conflicts { ... }; module basictypes { ... }; module constructedtypes { ... }; module holderexample2 { ... }; module MI { ... }; module MI2 { ... }; }; };};
這轉換為以下的目錄結構:
E:/_work/TICORBA/Projects/corbasem/gen/motheridl>dir /AD /S Volume in drive E has no label. Volume Serial Number is B415-7161Directory of E:/_work/TICORBA/Projects/corbasem/07/15/2000 01:41p <DIR> .07/15/2000 01:41p <DIR> .. 0 File(s) 0 bytesDirectory of E:/_work/TICORBA/Projects/corbasem/gen07/15/2000 01:41p <DIR> .07/15/2000 01:41p <DIR> .. 0 File(s) 0 bytesDirectory of E:/_work/TICORBA/Projects/corbasem/gen/motheridl07/15/2000 01:41p <DIR> .07/15/2000 01:41p <DIR> ..07/15/2000 01:41p <DIR> basictypes07/15/2000 01:41p <DIR> conflicts07/15/2000 01:41p <DIR> constructedtypes07/15/2000 01:41p <DIR> holderexample07/15/2000 01:41p <DIR> holderexample207/15/2000 01:41p <DIR> MI07/15/2000 01:41p <DIR> MI2 0 File(s) 0 bytes

將 IDL 映射為 Java 元素的一個基本思想是一致性。如同其它任何類庫一樣,它們必須存在穩定性,也就是說在修改庫中的類時不必刪除現有的方法;不改變接口。CORBA 在這方面應該做的更好,因為多個 ORB 提供商將要使用這一映射來生成類庫。我們希望在不同 ORB 實現之間有著一致性;這意味著可移植性。假如 ORB 提供商A的 IDL 到 Java 映射在 org.VendA.Excep 的 package 中提供了 UserException ,而提供商B在 org.VendB.UtilTypes 的 package中也提供了相同的 UserException ,Client 或 Server 的代碼將不能夠移植。Client 或 Server 移動到另一個 ORB 時需要改變代碼并重新編譯。這可不是我們選擇 CORBA 的原因!我們希望并要求可移植性;因此 OMG 規定了庫結構。
在 Java 編程語言中,要害詞 package 將 Java 類組成類庫,并控制對類庫中的構件的訪問。我們的 Java 類庫中將包含 Java 編程語言中需要編譯的所有素材,這些我們已經在 IDL 中描述過了。但是為了不同提供商的類庫之間的可移植性,必須定義類庫結構或者類庫包,并且嚴格遵守這些定義。只有這樣 Client 才能依靠于代碼并且保證不用在不同提供商的ORB之間移植時重寫代碼。
在 IDL 到 Java 映射的可移植性部分中規定了 API,它提供了庫結構和最小功能集,使 Java ORB中可以使用可移植的存根和骨架。因為 Java 類經常被下載,它們往往來自獨立于ORB提供商的代碼,因此對于 Java 編程語言的互操作性需求就超過了其它語言。出于這些原因,定義存根和骨架使用的接口是最基本的要求。假如這些結構不加以定義的話,存根(或骨架)的使用將需要一個或兩個方案。一個要求由 IDL 到 Java 編譯器或ORB提供商提供的類似工具(或者與ORB所使用的兼容)生成存根(或骨架),以使生成的存根能夠適合ORB提供商的類庫結構,另一個方案要求下載存根或骨架時同時下載整個ORB運行時環境。我們不希望采用這兩種方案中的任何一個。理想的情況是將 IDL 發送到 Client 端或者由 Client 下載,利用 Client 端選擇的工具生成存根,并從它們的環境連接到我們的 Server。
因此,Java 語言映射高度依靠于標準的結構,它在一套標準的 Java 包中實現 -- org.omg.*。IDL 到 Java 映射中重要的一項就是包含 PIDL,本地類型和ORB可移植接口的壓縮文件。它給出了包中確切內容的定義性聲明。當然,如同這一行中的其它任何事一樣,在不遠的將來 IDL 到 Java 映射的版本也會發生改變。但是以你對目前的映射的理解,你一定會注重到將來的版本中任何可能的二進制不兼容性

yuxq 回復于:2003-09-17 18:50:38
基本數據類型
基本數據類型的映射是很直接的。 下表會讓你了解到映射是多么簡潔:
IDL 類型 Java 類型 異常
boolean Boolean
char Char CORBA:ATA_CONVERSION
wchar Char CORBA:ATA_CONVERSION
octet Byte
string java.lang.string CORBA::MARSHAL, CORBA:ATA_CONVERSION
wstring java.lang.string CORBA::MARSHAL, CORBA:ATA_CONVERSION
short Short
unsigned short Short large number mismatch ?test
long Int
unsigned long Int large number mismatch ?test
long long Long
unsigned long long Long large number mismatch ?test
float Float
double Double
long double **unmapped 現在還不清楚是否會增加這一類型作為新的基本類型或者是類庫的補充,如java.math.BigFloat
要瀏覽練習所有這些基本類型的 module,請訪問 motheridl.idl 的例子.
整型(Integer)
IDL 符號整型(signed integer)到 Java 類型的映射不存在任何問題。IDL 的 short 類型映射到 Java 的 short,IDL 的 long 映射到 Java 的 int,IDL 的 long long 映射為 Java 的 long。這些都是直接映射,不會給你帶來什么麻煩的。
問題在于 IDL 的無符號整型(unsigned)。Java 編程語言沒有 unsigned 類型,并且它所有的整數類型都是有符號的。在多數情況下這不會發生問題,但是當一個 IDL 無符號整數取值正好落在最高位所限制的取值范圍中時,類型轉換就會發生不匹配的錯誤。假如不檢查并改正這種錯誤,轉換為 Java 后的結果就會是一個負數,而不是一個接近無符號整數類型取值上限的數值。
例如,假設有一個從 IDL 接口返回的 unsigned short 類型值,這一類型的取值范圍是0到65535。 Java 的有符號 short 類型能夠接收的取值范圍是-32768到32767。那么你可以看到,對于任何在32767到65535之間的值映射為 Java 的 short 以后將成為負數。這就造成了不匹配的障礙,必須進行測試。對于 unsigned short, unsigned long, 以及 unsigned long long 來說也是這樣。
這意味著什么呢?首先,我建議以后寫 IDL 定義時不要再使用無符號整型。這會使事情簡單的多。其次,假如你在使用或者支持現有的 IDL 接口,那你必須測試 輸入的無符號整數,并確保它在 Java 程序中被作為負數正確的處理,或者被拷貝到取值范圍較大的變量類型中。
布爾型(Boolean)和8位字節型(octet)

這兩種 IDL 類型到 Java 類型的映射也是直接映射。IDL 的布爾常量 TRUE 和 FALSE 映射到相應的布爾量 true 和 false。
IDL 的字節型 octet 長度為8位,它映射為 Java 的 byte 類型。
字符型(Character)和字符串類型(string)
字符類型的映射有一些困難。首先是所使用的字符集,其次是表示整個字符集所需要的編碼位數。不同的語言有不同的字符,它們分別被國際標準化組織映射為不同的字符集。這些字符集代表了某種語言的字母或符號到數字的映射。一種語言中符號的數量決定了這種語言所需要的位寬?,F在有8位和16位兩種字符集。
IDL 的字符型數據用8位來表示字符集中的一個元素,而 Java 的字符型數據用16位無符號整數來表示 Unicode 字符。要正確的進行類型轉換,Java CORBA 運行時環境驗證了所有由 IDL 的 char 型映射來的 Java char 型的有效性范圍。這一方向的映射沒有什么困難,因為我們是把8位的數值映射為16位的數值,Java 程序碰到的任何問題都很輕易處理,因為空間是足夠的。然而,要把 Java 的 char 型映射為 IDL 的 char 型,Java 的 char 型就有可能會超出 IDL 使用的字符集所定義的范圍。這種情況下就會產生 CORBA:ATA_CONVERSION 的異常。 IDL 的 wchar 僅僅是映射為16位字符集的 IDL 類型,它映射為 Java 的基本類型 char。假如 wchar 超出了字符集所定義的范圍,將會產生 CORBA:ATA_CONVERSION 的異常。
IDL 的 string 類型映射為 java.lang.String。別忘了 IDL 的 string 是一個 char 的序列。這意味著 IDL 的 string 必須滿足 IDL char 和 IDL sequence 的要求。因此,在編譯過程中要進行字符串中的字符范圍檢查和字符序列的越界檢查。字符范圍非法會引起 CORBA:ATA_CONVERSION 的異常。越界會引起 CORBA::BAD_PARAM 的異常。對于 IDL 的 wstring 類型來說其注重事項和使用規則也是一樣的。
浮點型(Floating-point)
因為OMG IDL 和 Java 的浮點型數據都遵從 IEEE 754- 1985 Standard for Binary Floating Point Arithmetic,所以浮點型數據的轉換沒有問題。然而,目前 Java 編程語言中還沒有對 IDL 的 long double 類型的支持。現在還不清楚 java.math.* 是否會增加這一類型作為基本數據類型或新的包,或者說什么時候會增加,也許會作為 java.math.BigFloat 吧。這一問題就留待以后修訂了。
映射的合法性檢查
我們可以用 Orbacus ORB 帶有的 IDL 到 Java 編譯器來運行我們的 motheridl.idl 文件:
jidl --output-dir . . /. . /. . MotherIDL.idl
運行結果所產生的 Java 接口定義在 UseAllTypesOperations.java 文件中給出。
這一生成的文件檢查映射的合法性。所有的 Java 類型都像我們所預期的那樣。唯一的訣竅大概就在于 inout 和 out 參數位置上的數據類型--它們都是 holder。
holder 類
在任何語言中,參數傳遞都是一個有趣的話題,當要把OMG IDL 這樣獨立于語言的體系結構進行語言映射時,它又是一個傷腦筋的問題。 Java 程序總是采用傳值的方式。這意味著要把原語傳遞到方法中時,會得到一個原語的本地拷貝。然而,假如方法的參數是 Java 對象的話,則不會傳遞對象本身而是對象的引用。因此,被傳遞的是引用的拷貝,但是這個引用通過值來傳遞。
CORBA 規定了 in 參數和返回類型采用"值調用"(call-by-value)的方式,而 CORBA 的 out 則是"結果調用 "(call-by-result)。inout 的參數類型在輸入服務器時通過"值調用"的方式來傳遞,而在輸出時則采用"結果調用"的方式。 out 和 inout 的參數傳遞模式不能被直接映射到 Java 的參數傳遞機制。要支持 out 和 inout 的參數傳遞模式需要另外使用 holder 類。
IDL 到 Java 的映射為所有的 IDL 基本類型定義了 holder 類,它同時也作為用戶定義類型的標準格式。IDL 到 Java 編譯器可以為用戶定義的類型生成 holder 類,以便以后在 Java 程序中實現這些參數模式時使用。 Client 生成并傳遞一個適當的holder Java 類實例,這個實例的值在 Java 程序中被傳遞給每一個 IDL out 或者 inout 參數。Holder 實例的內容(而不是實例本身)被調用它的程序所修改,Client 使用的是調用返回后(有可能)改變了的內容。
CORBA-Java 類庫中提供了 IntHolder 的例子。要注重 Java 中 public int 的值,以及 _type() 方法的返回值--它的類型是 long。記住這點是因為 Java 的 int 映射為 IDL 的 long。
記住org.omg.CORBA 包中提供了所有基本 IDL 類型的 holder 類,并為所有已命名的用戶定義 IDL 類型生成 holder 類,那些用 typedef 定義的除外。
對于用戶定義的 IDL 類型來說,holder 類根據映射的(Java)類型名再附加一個 Holder 來命名。對于 IDL 基本數據類型來說,holder 類的名字就是數據類型映射的 Java 類型名,開頭字母大寫,并附加一個 Holder(例如,IntHolder)。
每個 holder 類都有一個來自實例的構造函數,一個默認的構造函數,以及一個公有的實例成員(value)),它是一個有類型的值。默認構造函數將值域設置為 Java 語言為不同類型所定義的默認值:boolean 為 false,numeric 和 char 類型為 0, string 為 null,對象引用也是 null。為了支持可移植的存根和骨架,holder 類也實現 org.omg.CORBA.portable.Streamable 接口。
 
結論
這里只是 IDL 到 Java 映射的第一部分。你應該熟悉到,用 Java 編程語言編寫基于 CORBA 的應用程序和構件要求理解 IDL 到 Java 語言映射。CORBA 規范包括很多語言映射。它們在你工作的各方面中都會有所體現。你的代碼的可移植性不僅取決于OMG的庫結構,而且也取決于你自己所生成的庫結構。映射的目的是將接口定義轉化為某種特定語言的實現,這種轉化可能會以犧牲定義的完美性來換取實際的可行性。正如我們在無符號整型的例子中所看到的,你必須保持一定的警惕性以保證你的應用程序能夠正常工作。

語言映射是一種翻譯,因為你在使用一種語言,而要把它轉換為另一種同樣可以工作并且可以理解為一種實現的語言。正如一些短語和結構沒法在兩種自然語言之間很好的翻譯一樣,有些結構也不太輕易映射。我們必須找到解決的方案,雖然它們可能使映射變得更復雜,但是在實現時用起來更輕易。holder 類就是這樣;開始理解它可能要花些功夫,但是長遠來看,它提供了一種通用的、一致的解決方案。

IDL-to-Java映射(2):
使用 IDL 映射創建組件接口
(本文摘自IBM developerWorks)
Dave Bartlett
顧問、作家兼講師
2000 年 11 月
內容:


結構
枚舉
聯合
序列和數組
數組
序列
異常
Any
輔助
結束語

 
我們就本月的 CORBA 連接中更復雜的類型和輔助類的問題,來繼續研究 IDL-to-Java 映射。
上個月,在 IDL-to-Java 映射的第一部分中,我們研究了基本數據類型、結構和數據傳送。本月,我們將集中精力研究映射常數和結構,討論某些更復雜的類型,例如,序列、數組、異常和 Any 類型。最后,將研究輔助類和它們的功能。
首先,應該提醒您我們正在使用接口定義語言,任何 IDL 的目的就是創建某些組件或服務器的接口。這意味著我們正在創建新的類型。因此,讓我們從 interface 要害字的映射和使用 OMG IDL 創建新類型的機制開始討論。
接口
我們將回到所有 IDL 文件的母板 -- MotherIDL.idl。我使用這個文件來研究 IDL-to-Java 映射各個方面。在 MotherIDL 中,有一個名為 FindPerson 的接口。顯示如下:
清單 1. FindPerson 接口
interface FindPerson { Person GetByName(in string sName); Person GetBySSN(in string sSSN); };
我們現在只集中討論接口和兩個方法 GetByName() 和 GetBySSN()。要害字 interface 的確切含義是什么?仔細研究 OMG CORBA 規范,就會發現 interface 要害字后帶有標識(本例中是 FindPerson)。FindPerson 是接口名稱,并且它定義了合法的類型名稱。只要標識符合 IDL 的語法,就可以使用這種類型的標識。將 FindPerson 作為方法參數或結構成員在 IDL 中使用時,一定要記住 FindPerson 表示支持 FindPerson 接口的對象的引用。
IDL-to-Java 映射的目的是生成 Java 編程語言中的接口引用的表示,以供 Java 程序員使用,而且客戶機程序員和服務器程序員都可以使用。我使用以下命令行,使用 Orbacus ORB、JIDL 附帶的 IDL-to-Java 編譯器來運行 MotherIDL:
jidl --output-dir ../../.. motheridl.idl
由于 MotherIDL 中有許多內容,因此將會得到大量生成代碼的文件。而我們對于放入 corbasem/gen/motheridl/ holderexample 目錄下的文件 FindPerson.java 和 FindPersonOperations.java 感愛好。
FindPerson.java 稱為簽名接口。它很簡單:
Listing 2. FindPerson.java
public interface FindPerson extends FindPersonOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { }
接下來如何?毫無結果!而事實上有很多,只不過是隱藏的。首先注重兩個 Java 要害字:public interface。是的,Java 編程語言有自己的 interface 要害字。它很重要,因為它使映射既快速又順暢。
Java 編程語言的 interf

上一篇:用C實現WebService

下一篇:GDB 的文檔

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲在线播放| 自拍偷拍亚洲区| 亚洲免费高清视频| 福利微拍一区二区| 日韩中文有码在线视频| 亚洲精品中文字幕有码专区| 亚洲精品乱码久久久久久按摩观| 色综合天天综合网国产成人网| 韩剧1988在线观看免费完整版| 亚洲欧美日韩中文在线制服| 亚洲国产精品美女| 日韩成人在线免费观看| 亚洲欧美在线看| 亚洲欧美一区二区三区情侣bbw| 高清欧美性猛交xxxx黑人猛交| 国产亚洲精品一区二555| 亚洲欧美国产制服动漫| 国产偷国产偷亚洲清高网站| 国产精品视频区| 国产精品极品美女粉嫩高清在线| 亚洲欧美视频在线| 欧美伦理91i| 中文字幕欧美国内| 欧美国产极速在线| 欧美高清在线观看| 裸体女人亚洲精品一区| 97在线视频免费播放| 黑人巨大精品欧美一区二区免费| 91成人天堂久久成人| xxav国产精品美女主播| 国产精品久久久久久久久久久久久| 国产亚洲免费的视频看| 亚洲欧洲一区二区三区久久| 91牛牛免费视频| 亚洲肉体裸体xxxx137| 色播久久人人爽人人爽人人片视av| 久久综合国产精品台湾中文娱乐网| 日韩美女视频在线观看| 国产精品美女网站| 日韩福利伦理影院免费| 亚洲电影免费观看高清| 91久久久亚洲精品| 欧美国产在线视频| 欧美日韩国产一区中文午夜| 国产精品6699| 国产一区二区欧美日韩| 911国产网站尤物在线观看| 国产视频久久久| 国产欧美日韩精品专区| 中日韩美女免费视频网站在线观看| 国产精品久久久久不卡| 成人黄色av网站| 91在线视频精品| 国产亚洲人成网站在线观看| 亚洲a级在线播放观看| 成人黄色免费片| 亚洲加勒比久久88色综合| 欧美成人免费大片| 91久久精品国产| 亚洲国产精品久久91精品| 亚洲国产精品成人精品| 亚洲色图激情小说| 亚洲乱码av中文一区二区| 久久天天躁狠狠躁夜夜躁2014| 日韩中文字幕视频在线| 久久九九亚洲综合| 国产日韩精品在线| 91青草视频久久| 麻豆成人在线看| 亚洲成人1234| 久久亚洲精品小早川怜子66| 亚洲曰本av电影| 日本一区二三区好的精华液| 欧美视频在线免费| 欧美高清自拍一区| 9.1国产丝袜在线观看| 亚洲精品日产aⅴ| 国产精品视频不卡| 欧美日韩美女视频| 亚洲视频在线观看免费| 国产精品青青在线观看爽香蕉| 欧美日韩成人在线观看| 日韩国产一区三区| 欧美日韩日本国产| 亚洲女在线观看| 欧美激情精品久久久久久变态| 国产精品第一区| 国产亚洲精品久久久久动| 久久精品99久久久久久久久| 精品无人区乱码1区2区3区在线| 91精品在线看| 亚洲午夜激情免费视频| 成人做爽爽免费视频| 91久久嫩草影院一区二区| 国产精品毛片a∨一区二区三区|国| 亚洲free性xxxx护士hd| 乱亲女秽乱长久久久| 黑人狂躁日本妞一区二区三区| 久久精品视频在线播放| 中文字幕日本欧美| 一区二区在线视频播放| 日韩av电影中文字幕| 欧美亚洲国产成人精品| 欧美日韩亚洲一区二区| 亚洲福利在线视频| 欧美激情欧美激情在线五月| 日韩欧美在线第一页| 欧美精品日韩三级| 久热99视频在线观看| 亚洲精品v天堂中文字幕| 国产精品亚洲精品| 一区二区三欧美| 欧美国产在线电影| 精品呦交小u女在线| 91po在线观看91精品国产性色| 久久99久久久久久久噜噜| 亚洲欧美在线磁力| 亚洲第一男人天堂| 91精品久久久久久综合乱菊| 成人精品在线视频| 国产精品美女免费看| 欧亚精品中文字幕| 2019中文字幕全在线观看| 欧美人交a欧美精品| 亚洲老司机av| 久久久女人电视剧免费播放下载| 亚洲免费视频在线观看| 日韩精品在线视频| 久久久久这里只有精品| 成人97在线观看视频| 久久精品久久久久| 在线播放亚洲激情| 亚洲色图狂野欧美| 国产精品夜间视频香蕉| 欧美裸体xxxx极品少妇| 91精品国产99| 日韩精品视频在线| 国产精品18久久久久久首页狼| 成人福利视频在线观看| 欧美成人黑人xx视频免费观看| 91精品91久久久久久| 亚洲欧美日韩在线一区| 久久激情视频免费观看| 亚洲欧美日韩国产中文| 国产精品视频成人| 久久男人资源视频| 这里只有精品在线观看| 中文字幕日韩视频| 日韩高清有码在线| 正在播放欧美视频| 国产精品久久久久福利| 日韩亚洲一区二区| 成人在线中文字幕| 亚洲视频国产视频| 黑人巨大精品欧美一区二区免费| 日韩视频在线免费观看| 亚洲第一天堂av| 亚洲变态欧美另类捆绑| 日韩女优在线播放| 亚洲爱爱爱爱爱| 久久免费在线观看| 久久精品国产精品亚洲| 九九久久精品一区| 91av在线播放视频|