WEB开发网      濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻橀弻锝夊箣閿濆棭妫勯梺鍝勵儎缁舵岸寮诲☉妯锋婵鐗婇弫楣冩⒑閸涘﹦鎳冪紒缁橈耿瀵鏁愭径濠勵吅闂佹寧绻傚Λ顓炍涢崟顖涒拺闁告繂瀚烽崕搴g磼閼搁潧鍝虹€殿喛顕ч埥澶娢熼柨瀣垫綌婵犳鍠楅〃鍛存偋閸℃ɑ鍙忔繛鎴炴皑绾捐棄霉閿濆懏鎯堥柍璇茬墢缁辨帡鎮╁畷鍥р拰閻庢鍠涢褔顢樻總绋块唶妞ゆ劧缍嗛埀顒€娲缁樻媴閸涘﹤鏆堥梺瑙勭摃椤曆囷綖濠靛惟闁宠桨鑳堕澶愭⒑闂堟稓绠冲┑顕呭幖鍗遍柛顐ゅ枔缁犻箖鏌涢埄鍏狀亝鎱ㄩ崶銊d簻閹兼番鍨哄畷灞炬叏婵犲啯銇濈€规洏鍔嶇换婵嬪磼濮樺吋缍嬮梺璇插椤旀牠宕伴弽顓熷亯濠靛倸鎽滃畵渚€鏌″搴″箹缂佺姵绋掗妵鍕籍閸屾矮澹曢梺鎸庣☉缁绘ê顫忓ú顏勫窛濠电姴鍟惁鐑芥⒑閸涘﹥澶勯柛瀣嚇閹箖顢楅崟顑芥嫽婵炶揪绲介幗婊堝几閸愨斂浜滄い鎰╁焺濡偓閻庤娲栫紞濠傜暦缁嬭鏃堝焵椤掑倻涓嶉柡宥庡幗閻撳啴鏌涘┑鍡楊仼闁哄棗锕弻娑氣偓锝庡亝瀹曞瞼鈧娲滈崗姗€銆佸鈧幃娆撳箛閳轰胶浠鹃梺闈涙搐鐎氱増淇婇悜鑺ユ櫆闁告挆鍛緰濠电姵顔栭崰鏍晝閵堝绠规い鎰剁稻濞呭繘姊绘担瑙勫仩闁稿孩绮撻崺鈧い鎺戝绾惧鏌熼悙顒傜獮闁哄啫鐗嗗婵囥亜閹捐泛顎撶紒閬嶄憾濮婄粯鎷呯粵瀣秷閻庤娲橀敃銏ゃ€佸鎰佹Ъ濡炪們鍨归敃顏勵潖缂佹ɑ濯撮柛娑橈工閺嗗牆鈹戦悙棰濆殝缂佺姵鎸搁悾鐤亹閹烘垹顓煎銈嗘煥瑜扮偟绮径濞炬斀闁绘劖娼欓悘鐔兼煕閵婏附銇濋柟顕嗙節瀵挳鎮㈢紙鐘电泿闂備浇顫夊妯绘櫠鎼达絿鐭欓柤濮愬€楃壕濂告煃瑜滈崜鐔风暦濮椻偓閸╃偞寰勯崫銉ф晨闂備胶顢婃竟鍫ュ箵椤忓棙顫曢柡鍥╁枑濞呭繐鈹戦悩鎰佸晱闁哥姵鐗犻弫鍐Ω閵夈垺鐎洪梺鎸庣箓濞层倝宕瑰┑鍥╃闁糕剝顨堢粻姘舵煛鐎n亪鍙勯柡宀€鍠栭、娑㈠幢濡も偓閺嗘瑦銇勯妷锕€濮嶆慨濠傤煼瀹曟帒鈻庨幋顓熜滈梻浣侯攰婵倗鍒掑澶婄疄闁靛ň鏅滈崑銊х磼鐎n厽纭舵い锔诲枛閳规垿鎮欓崣澶樻!闂佸憡姊圭敮鐐哄箲閵忋倕骞㈡繛鎴炵懅閸樹粙姊洪棃娑氱畾闁硅櫕宀稿畷鐑筋敇閻樼數鍔堕梺璇插嚱缂嶅棝宕戞担鍦洸婵犲﹤鐗婇悡娑氣偓骞垮劚閸燁偅鎱ㄩ埀顒佺節閵忥綆娼愰柨鏇樺灲瀵鈽夐姀鈥斥偓閿嬨亜韫囨挸顏╂い顐㈡搐閳规垿顢欑涵閿嬫暰濠碉紕鍋犲Λ鍕亱闂佸憡鍔﹂悡浣姐亹閹烘嚦褔鏌涢埄鍐喛濠殿喖娲娲偡閺夋寧些闂佺娅曢敃銏ゆ偘椤曗偓楠炴ḿ鎷犻懠顒夊敽闁诲骸绠嶉崕閬嶅箯鐎n€稑饪伴崼鐔叉嫽闂佺ǹ鏈悷褔藝閿旂晫绡€闁逞屽墴閺屽棗顓奸崨顖ょ吹闂備線娼ч悧鍡浰囬銏犵劦妞ゆ巻鍋撻柛鐔告綑閻g兘宕¢悙鈺傤潔濠碘槅鍨抽崢褔鐛崼銉︹拻濞达絽鎲$拹锟犳煕鎼存稑鈧繈濡撮崘顔煎耿婵炴垶鐟ユ禍妤呮⒑閸濆嫭鍌ㄩ柛銊︽そ閹€斥槈閵忥紕鍘遍梺闈涱檧缁蹭粙宕濆顑芥斀闁挎稑瀚敮鍫曟婢跺绡€濠电姴鍊搁顐︽煟椤撶儐鍎旈柡灞炬礋瀹曟儼顦叉い蹇e墰缁辨帡鎮╁畷鍥ㄥ垱闂佽桨鐒﹂崝娆忕暦閵娾晩鏁囬柣妯虹仛缂嶄線姊婚崒姘偓椋庣矆娓氣偓楠炴牠顢曢敐鍛獮闂佹悶鍎洪崜娆撴倿閸偁浜滈柟鍝勬娴滃墽绱掗崜褑妾搁柛娆忓暙椤曪綁骞庨挊澶婅€垮┑鐐村灦閻熴儵鍩€椤掑倹鏆柡灞诲妼閳规垿宕卞☉鎵佸亾濡も偓椤儻顦遍柛妤佸▕瀵鏁撻悩鎻掕€垮┑鐐叉缁诲棝寮搁崨瀛樷拺闁告繂瀚ḿ銈夋煕閺囥劌浜介柛銈冨€曢埞鎴︽倷閸欏妫¢梺鎼炲妿閺佽鐣烽崫鍕殕闁告洦鍏橀幏娲⒒閸屾氨澧涚紒瀣浮钘熼柣鎰劋閸嬨劍銇勯弽銊р槈婵炴惌鍣i弻銊モ攽閸繀绮堕梺瀹狀潐閸ㄥ綊鍩€椤掑﹦绉甸柛瀣缁傚秴螖閸涱喚鍘甸梺鐓庢贡婢ф銇愯缁辨帡骞撻幒瀣划闂佽鍠曠划娆撳箠閿熺姴围闁搞儮鏅槐鍐测攽閻愯埖褰х紓宥佸亾濡炪倖娲橀悧鏇㈠煝閹捐鍗抽柕蹇ョ磿閸橀亶姊洪棃娴ㄥ綊宕曢搹顐ゎ浄闁靛緵棰佺盎濡炪倖鍔戦崹鑽ょ不瀹曞洨纾奸弶鍫涘妼缁楁帡鎽堕敐澶嬪仯闁搞儜鍕ㄦ灆闂侀€炲苯澧柟绋垮⒔濡叉劙骞樼€涙ê顎撻梺闈╁瘜閸樼ǹ危閸繍娓婚柕鍫濇閻忋儵鏌熼崘鏌ュ弰闁糕斂鍨介獮妯好虹紒妯绘珝闂備胶绮崝蹇涘疾濠婂牆妫橀柍褜鍓氭穱濠囨倷椤忓嫧鍋撻弽褜娼栫憸鐗堝笒閸戠姴鈹戦悩瀹犲缂佲偓閸屾稏浜滈柟鐑樺灥閳ь剝宕垫竟鏇熺附閸涘﹦鍘藉┑鈽嗗灡鐎笛囨偟椤忓棌鍋撶憴鍕闁活厼鍊垮濠氬即閵忕姴鑰块梺鍝勬川婵厼危椤旂⒈娓婚柕鍫濋娴滄繄绱掔拠鑼ⅵ闁绘侗鍣e畷鍫曞Ω閿曗偓椤庢捇姊虹粙璺ㄧ妞わ缚鍗抽幃妤呭川婵犲嫮鐦堥梺姹囧灲濞佳冩毄闂備浇妗ㄧ粈渚€骞夐敓鐘茬疄闁靛ň鏅╅弫鍥煏韫囨洖啸闁挎稒鐩铏规喆閸曨偆顦ㄧ紓浣割樈閸犳盯濡甸幇鏉跨闁规儳鐡ㄩ悵鎶芥⒒娴h鍋犻柛搴櫍瀵剟宕掗悙鑼姦濡炪倖宸婚崑鎾绘煥閺囥劋閭€殿喖顭烽弫鎾绘偐閼碱剙濮︽俊鐐€栫敮濠囨嚄閸洏鈧懘鎮滈懞銉モ偓鐢告煥濠靛棝顎楀ù婊呭仱閺屾稑螣閹稿寒妫勯梺瀹狀潐閸ㄥ潡宕洪妷鈺佸耿婵°倕鍟╅悽缁樹繆閻愵亜鈧牠宕归崼鏇熷仭闁宠桨鑳堕弳锕傛煟閵忋埄鏆柛瀣崌閺佹劖鎯旈垾鍐茬闂備胶枪椤戝棝骞愭ィ鍐ㄧ疅闁圭虎鍠栫粈瀣亜閹哄棗浜炬繛瀵稿Л閺呯姴顫忛搹鍦煓闁圭ǹ楠搁弨顓犵磽娓氬洤娅嶇紒鐘崇墵楠炲啫顫滈埀顒€鐣峰鈧、娆戞喆閿濆棗顏圭紓鍌氬€搁崐鐑芥倿閿曞倸鐓熼柕鍫濐樈閺佸倿鏌涢弴銏℃锭婵炲牄鍔戝娲礈閹绘帊绨煎┑鐐插级閻楃娀骞冮崸妤婃晪闁逞屽墴瀵鏁愭径濠勭杸濡炪倖妫佹慨銈呅掗崟顓犵<闁绘劦鍓欓崝銈夋煏閸喐鍊愮€殿喛顕ч埥澶婎潩椤愶絽濯伴梻浣虹帛閸旓箓宕滃☉妯锋灁闁靛牆顦伴悡娑樏归敐鍛喐濠⒀嶇畵閺岀喖顢欑粵瀣暭闂佺懓寮堕幐鍐茬暦閻旂⒈鏁嗛柛灞诲€栬ⅷ缂傚倸鍊搁崐椋庢閿熺姴绐楅柡宥庡亝瀹曞弶淇婇娑橆嚋妞ゃ儯鍊濆铏规嫚閺屻儱寮板┑鐐板尃閸パ咁啈濠电姴锕ら崥妯衡槈閵忊晜鏅梺缁樺姇椤曨參宕㈤棃娑辨富闁靛牆妫涙晶顏呬繆椤愶絾鈷掔紒顔肩墛閹峰懘宕烽褎绁俊鐐€栧ú宥夊磻閹剧粯鐓欐い鏃傜摂濞堟棃鏌嶇紒妯诲磳鐎规洖缍婇、娆撴偩鐏炲ジ鍋楅梻鍌氬€烽懗鍓佸垝椤栫偞鍋嬫繝濠傜墕閸屻劎鎲搁弮鍫濈畺濡わ絽鍟崐濠氭煠閹帒鍔氬ù婊勵殜閺岀喖鎮℃惔锝嗘喖闁藉啳椴搁妵鍕敃閵忊懣銏ゆ煃鐟欏嫬鐏撮柛鈹垮劦瀹曞崬螖閸愌勫煕闂備浇宕垫慨顓㈠磻閹剧粯鐓ラ柡鍥╁仜閳ь剙缍婂畷鎰版偨绾版ê浜鹃悷娆忓缁€鈧┑鐐茬湴閸斿孩绔熼弴鐔侯浄閻庯綆鍋嗛崢閬嶆煟韫囨洖浠滃褌绮欓獮濠囧川鐎涙ḿ鍘遍梺鍝勫€藉▔鏇熺墡闂備線娼уú銈団偓姘卞娣囧﹪骞栨担鑲濄劑鏌ㄩ弮鍌滃笡妞ゃ儻缍佸缁樻媴妞嬪簼瑕嗙紓浣瑰絻婢т粙骞戦姀銈呴唶闁靛/鍐偊闂備礁鎼粔鏌ュ礉瀹ュ棗鍨旈悗娑櫳戦崣蹇旂節闂堟稒顥炴繝鈧导瀛樼厵闂婎偒鍘煎畵鍡樻叏婵犲嫮甯涢柟宄版嚇閹煎綊鎮烽幍顕呭仹濠电姷顣藉Σ鍛村磻閸曨垰鐤痪鎯ь儐閿涘倿姊绘担绛嬫綈鐎规洘锕㈤、姘愁槻閺佸牓鏌$仦璇插姕闁稿﹦鏁婚弻銊モ攽閸℃侗鈧鏌$€n剙鏋涢柡宀嬬秮楠炴ḿ鎹勯悜妯尖偓鐐箾閿濆懏鎼愰柨鏇ㄤ簼娣囧﹪宕奸弴鐐碉紲濠殿喗锕╅崑鍕夊鑸碘拻闁稿本鐟ㄩ崗宀€绱掗鍛仸闁靛棗鍟村畷銊╊敇閸ャ劎鈽夐摶鏍煕濞戝崬骞橀柛妯绘そ濮婃椽宕烽鐐板缂備礁澧庨崑銈咁嚕椤曗偓瀹曠厧鈹戦崱娆戝春濠碉紕鍋戦崐鏍涙笟鈧敐鐐村緞鐏炵ǹ浜炬慨姗嗗厵閸嬨垺鎱ㄦ繝鍐┿仢闁圭绻濇俊鍫曞川閸涱偄鐏紒缁樼洴閹崇娀顢楅埀顒勫煝閸儲鐓曢柍瑙勫劤娴滅偓淇婇悙顏勨偓鏍暜閹烘鐤い鏍仦閸嬬喐銇勮箛鎾跺闁绘挾鍠栭悡顐﹀炊瑜濆銉ッ瑰⿰鍫㈢暫婵﹤顭峰畷鎺戭潩椤戣棄浜惧瀣捣閻棗銆掑锝呬壕濡ょ姷鍋為悧鐘汇€侀弴銏℃櫇闁逞屽墰缁鎮╃紒妯煎幍闂備緡鍙忕粻鎴︾嵁濡ゅ懏鐓曟繛鍡楃箳缁犲鏌″畝鈧崰鎾舵閹烘顫呴柣妯虹-娴滃爼姊绘担鍛靛綊顢栭崒鐐茬柧闁绘ǹ顕ч拑鐔兼煥濠靛棭妲搁崶鎾煙閼圭増褰х紒杈ㄦ礃缁傛帒饪伴崟顓狀啎闁诲孩绋掑玻鍧楁儗婵犲嫮纾界€广儱鎷戦煬顒傗偓娈垮枛椤兘骞冮姀銈呯闁绘挸绨堕崑鎾剁磼濡湱绠氬銈嗙墬缁诲倹绂嶈ぐ鎺撶厽闁挎繂妫欓妵婵囨叏婵犲啯銇濈€规洦鍋婂畷鐔碱敆閳ь剙鈻嶉妶鍥╃=濞达絿鐡旈崵娆撴煟濡も偓濡繈鏁愰悙鍓佺杸闁瑰彞鐒﹀浠嬨€侀弮鍫濇そ濞达綀顕栧Λ鍐ㄢ攽閻樺灚鏆╅柛瀣仱瀹曞綊宕奸弴鐔锋疄婵°倧绲介崯銊╁焵椤掆偓閸婂灝鐣烽锕€绀嬮柕濠忛檮閺夋悂姊绘担鍝ユ瀮婵☆偄瀚灋婵°倓鑳堕々鍙夌節闂堟侗鍎愰柣鎾跺枛閺岋綁寮崹顔鹃獓濠电偛鎳庨敃顏堝蓟閺囥垹骞㈤柡鍥╁濡差噣姊虹€圭媭鍤欓梺甯秮閻涱噣骞掑Δ鈧猾宥夋煕鐏炲墽鈯曠紒棰濆亰濮婂宕掑▎鎴М闂佸湱鈷堥崑濠傜暦椤栫儐鏁冮柨鏇楀亾缁惧墽鎳撻埞鎴︽偐瀹曞浂鏆¢梺绋块閿曨亪寮诲☉銏╂晝闁绘ɑ褰冩慨鏇㈡⒑閹惰姤鏁遍柛銊ョ埣楠炲牓濡搁埡鍌氫画闂佺粯顨呴悧濠囧箖濞嗘挻鈷戦悹鍥皺缁犳壆鈧鍠栨晶搴ㄥ箲閵忕姭妲堟繛鍡樺姇椤庢捇姊洪崨濠傚鐟滄澘鍟撮、鏃堫敃閿濆啩绨婚梺鍐叉惈閸燁偊宕㈤幘顔界厸閻忕偠顕ф慨鍌溾偓娈垮枟閹告娊骞冨▎寰濆湱鈧綆浜欐竟鏇㈡偡濠婂懎顣奸悽顖涱殜瀹曟垿宕掗悙瀵稿幐闂佹悶鍎崕閬嶆倶椤忓牊鐓熼柟鎯х-缁犱即鏌嶇憴鍕伌闁诡喗鐟╅幊鐘活敄閼愁垱顎楅梻鍌欑閹诧繝寮婚敐澶婄9婵犻潧顑呴拑鐔哥箾閹存瑥鐏╅柣鎾寸洴閹鏁愭惔鈥愁潾闁藉啳椴告穱濠囨倷椤忓嫧鍋撻幋锕€绀夊┑鐘叉搐绾惧潡鏌i姀鈶跺湱绮婚弽銊х闁糕剝蓱鐏忣厾绱掗悪娆忔处閻撴瑩鎮楀☉娆嬬細缂佺姰鍎茬换娑㈠礂閼测晩鏆℃繛锝呮搐閿曨亝淇婇崼鏇炵倞妞ゎ剦鍠撻崕鐢稿蓟濞戞埃鍋撻敐搴″濞寸娀浜堕弻鈩冩媴缁嬫寧娈绘繝娈垮枓閸嬫捇姊洪棃娑氬闁哥喓濞€瀹曟垿骞樼€涙ê顎撶紓渚囧灡濞叉﹢鎮楁繝姘拺闁革富鍘兼禍鐐箾閸忚偐鎳冮柍缁樻崌楠炲洭鎮ч崼姘闂備礁鎲¢崝鏇烆嚕閸洖绠氶柛顐ゅ枂娴滄粓鏌熺€涙ḿ绠栭柛鐘筹耿閺岋絽鈽夐崡鐐寸彎婵犳鍠掗崑鎾绘⒑闂堟稓澧曟俊顐㈢焸楠炲繑绻濆顓涙嫼缂備礁顑嗙€笛冿耿娴煎瓨鐓熼柣鏇炲€搁々顒傜磼椤旂》韬柟顔ㄥ洤閱囨繛鎴烆殘閻╁孩淇婇悙顏勨偓鏍礉閹达箑鏄ラ柛鏇ㄥ€犻敐澶婄濞达絽婀遍崢浠嬫⒑閹稿海绠撻柟鍐查鍗卞┑鐘崇閹虫岸鏌ㄥ┑鍡╂Ч闁绘挾濮电换娑㈠级閹搭厼鍓卞┑鐐叉噹濞差參寮婚敐澶婄闁归绀侀崜鏉款渻閵堝簼绨婚柛鐔风摠娣囧﹪宕奸弴鐐茶€垮┑顔筋殔濡瑩鍩涢弽顓熲拻濞达綀濮ょ涵鍫曟煕閻樺弶顥㈢€规洘娲熼幊鐘活敆閸屾粎鍔归柣搴$畭閸庨亶鎮ч崟顒傤洸鐟滅増甯楅悡娆撴煟閹寸倖鎴犱焊閻㈠憡鐓曟俊顖氬悑閺嗩剚鎱ㄦ繝鍛仩缂佽鲸甯掕灒闁惧繘鈧稒顢橀梻浣芥閸熷瓨绂嶉崼鏇炵畺婵☆垵娉曢悿鈧梺鎸庣箓閹冲海绮昏ぐ鎺撯拻闁搞儜灞拘х紓浣虹帛缁诲啰鎹㈠┑瀣<婵﹩鍘介宥囩磽閸屾瑧顦︽い锕備憾瀹曟洟濡舵径濠勭杽闂侀潧饪垫俊鍥╁姬閳ь剟姊洪崨濠佺繁闁革綆鍠楃粋鎺楀煛閸愵亞锛濇繛杈剧导缁瑩宕ú顏呭仺妞ゆ牗绋戠粭鈺呮煟韫囨柨娴慨濠冩そ楠炲棜顦寸紒鐘差煼閺屽秷顧侀柛鎾存皑缁瑩骞掑灏栧亾娴e壊娼ㄩ柍褜鍓欓~蹇旂節濮橆剛锛滃┑鐐叉閸ㄥ灚淇婃禒瀣厽閹艰揪绲块幊妤呮煕韫囨洖孝闁圭⒈鍋婇、姗€宕楅悡搴g獮婵犵數濮寸€氼參鎮¢敐鍡欑瘈闁汇垽娼ф禒锕傛煕閵娿儱顣抽柛鎺撳笚閹棃濮€閵忊晜閿ら梻鍌欑贰閸撴瑧绮旈悽绋跨厱闁圭儤鍤氳ぐ鎺撴櫜闁告侗鍠栭弳鍫ユ⒑閸濄儱鏋旈柛瀣仧閹广垹鈽夊顓炵彴閻熸粌绻橀幃楣冩偨绾版ê浜鹃悷娆忓缁€鈧紓鍌氱Т閿曨亜顕f繝姘耿婵°倕锕ら幃鎴︽⒑閸涘﹣绶遍柛銊ゅ嵆閻涱噣宕奸妷锔规嫽婵炶揪绲肩拃锕傚绩娴煎瓨鐓欐繛鑼额唺闁垱鎱ㄦ繝浣虹煓鐎规洜鍠栭、娑樷槈濡湱鏆楀┑鐘垫暩閸嬫稑螞濞嗘挸绠板┑鐘崇閸嬪倿鏌eΟ铏癸紞缂佺娀绠栭弻鈩冨緞鐎n亞鍔搁梺绋垮閸旀牜鎹㈠☉銏犲窛妞ゆ挾鍠庡▍锝夋⒒閸パ屾█闁哄矉绲借灒闁惧繒娅㈢槐鐐烘⒑濞茶骞栭柨鏇ㄤ邯瀵顓奸崶銊ユ瀭闂佸憡娲﹂崑鍡樺瀹€鍕拺闁硅偐鍋涙慨鍌滅磼閻樺磭澧垫鐐插暙閳诲酣骞橀弶鎴犳濠电姰鍨煎▔娑⑺囬鐐插瀭婵犻潧顑嗛埛鎺楁煕鐏炲墽鎳勭紒浣哄閵囧嫰寮撮悢鍝勨拰閻庤娲樺妯跨亙闂佸憡渚楅崑鈧柛瀣崌瀹曟﹢顢欓悡搴g崺闂備礁鎼ˇ浼村垂瑜版帒鐭楅柍褜鍓欓埞鎴︽偐椤旇偐浼囬梺绯曟櫆閻楃姴鐣峰┑瀣嵆闁绘ê鍚€缁楀姊虹憴鍕姸濠殿喓鍊濋幃鈥斥枎閹惧鍘靛銈嗙墪濡鎳熼姘f灁闁割偅娲橀崑鈩冪節婵犲倸顏紒璺哄级缁绘稓浠﹂崒姘瀷濠碘€冲级閸旀瑩鐛Ο鍏煎珰闁肩⒈鍓ㄧ槐鍙夌節閻㈤潧浠滄俊顐g懇瀹曞綊鎳栭埡鍐箵濠德板€曢幊蹇涘煕閹达附鐓曟繝闈涘閸旀岸寮介敓鐘斥拺缂備焦锕╁▓妯衡攽閻愨晛浜鹃梻渚€娼уΛ鏃傛濮橆剦鍤曞ù鐘差儛閺佸洭鏌i幇顖氱毢闁绘稈鏅犲缁樻媴閸涘﹨纭€闂佸啿鍢查悧鎾崇暦閵忥紕顩烽悗锝庝簽閺屟囨⒑閹稿海绠撴い锔垮嵆閸╂盯骞嬮悩鐢碉紲闁诲函缍嗛崢鐣屾兜閸撲胶纾奸柣妯哄暱閳绘洟鏌$仦鍓р槈閾伙綁鏌eΟ鍝勭骇闁革絿鍎ら妵鍕箛椤忓棛鐓撻梺鍝勭焿缂嶄線鐛崶顒夋晩闁告挆鍛潓缂傚倸鍊峰ù鍥敋瑜嶈灋婵炲棙鎸告闂佸憡娲﹂崹浼村礃閳ь剟姊洪棃娴ゆ盯宕ㄩ姘瑩闂傚倷鐒﹂惇褰掑春閸曨垰鍨傞弶鍫氭櫇閻瑩鏌熼悜妯烩拹鐎规洖寮剁换娑㈠箣濞嗗繒浠奸悗鐟版啞缁诲啴濡甸崟顖氱閻犺櫣鍎ら悗濠氭⒑閸濆嫷鍎戝┑顔芥尦閸╃偤骞嬮敂缁樻櫓缂佺虎鍘奸崲鍙夋叏濞戞氨纾藉〒姘搐濞呮﹢鏌涢妸銉у煟闁绘侗鍠涚粻娑樷槈濡櫣鐛╅梺璇插缁嬫帡鏁嬫繛瀵稿閸欏啫顫忕紒妯肩懝闁搞儜鍐х礋缂傚倷鑳舵慨鐢稿垂閻㈢ǹ鐓濋柟鐐灱閺€浠嬫煕椤愮姴鐏柨娑欑箞濮婅櫣绮欓幐搴㈡嫳闂佽崵鍣︽俊鍥╁垝婵犲洦鍋嬮柛顐g◥缁ㄥ姊洪崫鍕悙婵☆偅顨呯叅闁靛牆娲らˉ姘辨喐閻楀牆绗氶柣鎾存礃閵囧嫰顢橀悢椋庝淮濠电偛鎳忛敃銏ゅ蓟濞戙垹围闁糕剝岣块ˇ顓犵磽娴d粙鍝洪柟绋款煼楠炲繘宕ㄩ娑橆伕濡炪倖鐗楃划搴g玻濡ゅ啰纾介柛灞剧懆椤斿淇婇悪娆忔搐绾惧鏌熼崜褏甯涢柍閿嬪笒闇夐柨婵嗙墱濞兼劙鏌涚€n剙鈻堥柡灞剧⊕閹棃顢欓懖鈺€妗撻柣搴ゎ潐濞叉ḿ鎹㈤崒鐑嗘晣濠靛倻枪瀹告繃銇勮箛鎾村櫧闁逞屽墯濡炶棄顫忓ú顏勭闁绘劖褰冩慨鍫曟⒑閸涘﹥灏扮€光偓閹间礁鏄ユ繛鎴欏灩缁狅綁鏌eΟ鍏兼毄闁挎稒绮撻弻锝嗘償椤栨粎校闂佺ǹ顑呯€氫即銆佸顑藉牚闁告洦鍘鹃惁鍫ユ⒑闁偛鑻晶瀛橆殽閻愯尙效妞ゃ垺鐟╁畷婊嗩檪缂佽鲸鐓″铏规嫚閹绘帒姣愮紓鍌氱Т濡繂鐣烽幋锕€宸濇い鎾跺У濞堥箖鎮楅崗澶婁壕闂侀€炲苯澧撮柛鈹惧亾濡炪倖甯掗崰姘缚閹邦厾绠鹃柟缁樺笧缁犺崵鈧娲濋~澶岀矉閹烘柡鍋撻敐搴濈敖闁伙絿鍎ょ换娑氣偓鐢登瑰瓭濡炪倖鍨甸幊搴敊韫囨挴鏀介柛鈥崇箲閺傗偓闂備胶绮摫鐟滄澘鍟撮、鏃堝煛閸屻倖顔旈梺缁樺姈閹苯鈻撳⿰鍕弿濠电姴鍟妵婵嬫煙椤旀儳鍘寸€殿喖鐖奸獮鎰償閳锯偓閸嬫捇顢涢悙绮规嫼婵炴潙鍚嬮悷褏绮旈棃娴㈢懓饪版惔婵堢泿闂佷紮缍侀ˉ鎾诲箟閹绢喖绀嬫い鎾跺Х濡插洦绻濆▓鍨灍闁挎洍鏅犲畷婊冣槈閵忕姴鍋嶉梺瑙勫婢ф鍩涢幋锔界厱婵犻潧妫楅顏堟煕鐏炶濮傞柡灞剧洴婵℃悂鏁傛慨鎰檸闂備浇顕栭崳顖滄崲濠靛洣绻嗛柣鎴eГ閺呮粓鏌﹀Ο渚Ц濞寸厧瀛╃换婵堝枈濡椿娼戦梺鎼炲妺閸楁娊骞冨Ο琛℃斀閻庯綆鍋勬禍妤呮⒑鐟欏嫬顥嬪褎顨婇幃锟犳偄閸忚偐鍘甸梺纭咁潐閸旀牜娑垫ィ鍐╃厸閻庯綆鍋嗗ú鎾煛瀹€瀣М妤犵偞鐟╁畷姗€濡搁妶鍛€抽梺璇叉唉椤煤閺嶎厽鍋夐柛蹇涙?缁诲棝鏌i幋锝嗩棄閸烆垶姊洪棃娑辨Ф闁稿孩鐩獮瀣偐閻㈢绱抽梻浣呵归張顒勬偡瑜旇棟闁挎柨顫曟禍婊堟煙鐎涙ḿ绠樺褎娲熼弻锝夋晲閸パ冨箣闂佽鍠曠划娆忕暦瑜版帩鏁冩い鎰剁悼缁嬫劙姊婚崒娆戭槮婵犫偓闁秴纾块柕鍫濇媼濞兼牠鏌ゆ慨鎰偓鏇⑺夊鑸电厱闊洦绋掗敍鐔虹磼鐠囧弶顥為柕鍥у瀵粙濡歌閻e灚绻涚€涙ḿ鐭婄紓宥咃躬瀵鏁愭径瀣珳闂佸壊鍋嗛崳銉︾閳哄啰纾藉ù锝勭矙閸濇椽鏌熺粙娆剧吋妤犵偛绻樺畷銊р偓娑櫳戦崕顏堟⒑閼姐倕鏋戝鐟版椤㈡洟鎳栭埡鍐紳闂佺ǹ鏈悷锔剧矈閻楀牄浜滈柡鍥ф濞诧箓宕戠€n喗鐓曢柍鈺佸暟閳洟鏌涚€Q勬珖闁逞屽墰閹虫挾鈧矮鍗冲畷鎴炵節閸屾牜绱伴梺闈浥堥弲婊堟偂閸愵亝鍠愭繝濠傜墕缁€鍫熸叏濮楀棗骞橀柍鐟扮Т閳规垿鎮╅幓鎺嶇敖濠电偛鍚嬫竟鍡涘焵椤掆偓閸樻粓宕戦幘鏂ユ斀闁绘ɑ褰冮弫顏堟煏婵炑冩噽閿涙繈姊虹粙鎸庢拱闁荤噦濡囩划濠囧级濞嗙偓瀵岄梺鍝勵槹閸ㄥ爼骞夐幖浣圭厵妤犵偛鐏濋悘鑼偓瑙勬礈閸樠囧煘閹达箑绠涙い鎾跺Х閳诲绱撻崒姘偓鎼佸磹閻戣姤鍊块柨鏇氱劍閹冲苯鈹戦悩鎰佸晱闁搞劋鍗抽、姘额敇閻樻剚娼熼梺鍦劋閸ㄧ喎危閸喐鍙忔俊銈傚亾婵☆偅顨婂畷婊堝级鎼存挻鏂€闂佺粯鍔樼亸娆愭櫠濞戙垺鐓曢柡鍐e亾闁荤喆鍎甸敐鐐剁疀閹句焦妞介、鏃堝礋椤撗冩櫍闂傚倷鑳剁划顖炲礉閺嶎兙浜归柛鎰靛枓閳ь剚鐗犲畷鍗炩槈濞嗗本瀚奸梻浣告啞缁嬫垿銈弶鎴旀灁闁哄啫鐗婇悡鏇㈡煟閺冨牊鏁遍柛瀣ㄥ劦閺岀喖顢氶埀顒傜不閺嶎厼绠栨繝濠傛噽妞规娊鎮楅敐搴′簼婵炲懏鐗犲缁樻媴閾忕懓绗¢梺鍛婃⒐宀f寧绂嶇粙搴撴瀻闁规澘鐏氶鏃堟⒑閹肩偛鍔撮柛鎾村哺閸╂盯骞嬮敂鐣屽幗闂佺粯姊婚崢褎绂嶆导瀛樼厱闁靛牆娲ら弸搴ㄦ煃鐟欏嫬鐏存い銏″哺閸┾偓妞ゆ巻鍋撳畝锝堝劵椤﹀綊鏌涢埞鍨伈妤犵偞锚鑿愭い鎺嗗亾濞存粍绻堝娲川婵犲倸顫呴梺鍝勫€风欢姘剁嵁韫囨稒鎯為柛锔诲幘閿涙繈姊虹粙鎸庢拱闁荤啙鍥х鐎广儱顦扮€氬懘姊洪鈧粔鐢告偂閸愵喗鈷戦柛顭戝櫘閸庡繑绻涢幖顓炴珝闁哄矉绱曟禒锕傛偩鐏炴縿鍨介弻锝夋晲韫囨洜鐦堝Δ鐘靛仜缁夊綊銆佸▎鎴滅剨闁哄诞鍐榾闂傚倷娴囬褏鈧稈鏅犻、娆撳冀椤撶偤妫峰銈嗘磵閸嬫挾鈧娲橀崹鍓佹崲濠靛纾兼繝濠傚椤旀洟姊绘担鍛婅础闁稿簺鍊濋妴鍐幢濞戞ḿ锛欓梺缁樺灱婵倝宕愰悽鍛婄厽闁靛繈鍨洪銏㈡喐閻楀牆绗х€规挷绶氶弻娑㈩敃閻樻彃濮曢梺鎶芥敱鐢帡婀侀梺鎸庣箓濞诧箓宕甸埀顒勬⒑瀹曞洨甯涙繛鑼枛瀵鍩勯崘顏嗘嚌闂佹悶鍎滈崟顓炵秵闂佽姘﹂~澶娒哄鈧畷褰掑锤濡ゅ啫绁﹀┑鈽嗗灥閸嬫劗澹曢崗闂寸箚妞ゆ牗绮岀敮鑸殿殽閻愭潙濮嶆慨濠勭帛閹峰懘宕ㄦ繝鍌涙畼濠电偞鎸荤喊宥夈€冩繝鍌滄殾闁哄顑欏ḿ鈺呮偣妤︽寧顏犻柣銈呮喘濮婃椽宕ㄦ繝浣虹箒闂佸摜濮靛ú婊堝箲閵忋倕骞㈡繛鎴炵懅閸樺崬鈹戦悙鍙夘棞婵炲瓨鑹惧嵄缂佸绨遍弨鑺ャ亜閺傚灝鎮戦柛鐘筹耿閺岀喖鎸婃径灞界厽闂佽桨鐒﹂崝鏍ь嚗閸曨厸鍋撻敐搴濈胺闁告繃顨嗙换婵嬫偨闂堟稐娌梺鎼炲妼婢у酣寮鈧獮鎺楀箻鐎涙ḿ褰块梻浣告惈鐞氼偊宕曢弻銉﹀亗婵炴垯鍨洪悡鏇㈡倶閻愪絻妾告繛鍫熸煥闇夋繝濠傜墢閻g儤鎱ㄦ繝鍌ょ吋鐎规洘甯掗~婵嬵敄閽樺澹曢梺缁樺灱婵倝宕甸崟顖涚厱闁规崘灏欓ˇ锕傛煕閵婏妇绠栭柕鍥у瀵粙顢曢~顓犳崟缂傚倷璁查崑鎾愁熆閼搁潧濮堥柣鎾寸洴閺屾盯濡烽姀鈩冪彅闂侀€炲苯澧剧紓宥勭窔楠炲啴濮€閵堝懍绱堕梺闈涳紡閸涱噮娼撻梻鍌氬€烽悞锕傚箖閸洖纾挎繝濠傜墕缁€鍐煃鏉炴壆顦﹀┑顔煎暣濮婂宕掑顑藉亾閻戣姤鍤勯柛鎾茬閸ㄦ繃銇勯弽顐粶闁藉啰鍠栭弻鏇熺箾閻愵剚鐝曢梺绋块缁夌數鎹㈠┑瀣棃婵炴垵宕崜鎵磽閸屾瑨顔夐柡鍛█瀵濡舵径濠勭暢闂佸湱鍎ら崹鍨叏鐏炲墽绠鹃悗娑欋缚閻绱掗鑺ュ磳鐎殿喖顭烽弫鎾绘偐閼碱剦妲伴梻渚€娼чオ鐢电不閹次诲洭鍩℃笟鍥ㄥ瘜闂侀潧鐗嗛崯顐﹀礉濮橆厹浜滈柨鏃傚亾閺嗩剛鈧鍠涢褔鍩ユ径鎰潊闁绘ɑ鍓氬Λ鐔兼⒑閼姐倕孝婵炶濡囩划濠囧箻椤旇偐锛涢梺鍦亾閺嬪ジ寮ㄦ禒瀣€甸柨婵嗙凹缁ㄨ姤銇勯弮鈧崹鍨潖濞差亜绀堥柟缁樺笂缁ㄧ厧鈹戦悙鎻掔骇闁挎洏鍨归悾鐑藉箛閻楀牆鈧鏌ら幁鎺戝姢闁告ü绮欏娲偡闁箑娈堕梺绋款儏缁夊墎妲愰幘鎰佹僵闁煎摜鏁搁崢鍗炩攽椤斿浠滈柛瀣尭闇夋繝濠傛绾偓銇勯銏㈢閻撱倖銇勮箛鎾愁仹缂佸崬鐖煎娲川婵犲啫顦╅梺鍛婃尰閻熲晛鐣烽幋婵愬悑濠㈣泛顑傞幏娲⒑閸涘﹦鈽夐柨鏇樺劦閹繝濡烽埡鍌滃幐闂佸壊鍋掗崑鍕櫠鐎电硶鍋撳▓鍨灍闁绘挴鈧磭鏆﹀┑鍌溓归崡鎶芥煏婵犲繘妾繛鍛墵濮婄粯鎷呴搹鐟扮闂佸憡姊瑰ú鐔笺€佸棰濇晣闁靛繒濮撮崑宥夋⒑閸涘⿴娈橀柛瀣姍瀵劍绂掔€n偆鍘介梺褰掑亰閸撴瑧鐥閵囧嫰濡烽敂鍓х厒缂備浇椴哥敮鐐垫閹烘嚦鐔兼惞鐠団€冲壃缂傚倸鍊风欢锟犲窗濮樺崬鍨濇い鏍ㄧ矋瀹曞弶绻濋棃娑欙紞婵炲皷鏅滈妵鍕箻鐠虹洅銏☆殽閻愭潙濮嶆慨濠呮閹风娀鎳犻鍌ゅ敽闂備胶枪椤戝洭宕伴弽褜鍤曢柡灞诲労閺佸啴鏌ㄥ┑鍡橆棡闁绘繐绻濆缁樻媴缁涘娈┑顔斤公缁犳捇鏁愰悙鏉戠窞濠电偞甯楀浠嬪极閸愵喖纾兼慨妯诲敾缁卞崬鈹戦悩鍨毄濠殿喗鎸冲畷鎰節濮橆剚杈堥梺鎸庢礀閸婂綊鎮¢悢鍏肩厸闁告劑鍔岄埀顒傛暬楠炲繘鏁撻悩宕囧幐婵炶揪绲介幉锟犓夐姀銈嗙厸閻忕偟鏅暩濡炪伇鍌滅獢闁哄本鐩獮妯尖偓闈涙啞閸d即姊虹化鏇熸澓闁搞劌缍婇、姗€宕楅悡搴g獮闁诲函缍嗛崑鍛存偟閹惰姤鈷掑ù锝堫潐閸嬬娀鏌涙惔顔兼珝鐎殿喗褰冮埞鎴犫偓锝庡亝濞呮牕鈹戦悩缁樻锭婵炲眰鍔庣划缁樸偅閸愩劎楠囬梺鍓插亝缁诲倿鍩涢弮鍌滅<閻庯綆鍘奸崥褰掓煙閸欏鍊愮€殿喖鐖煎畷褰掝敊閼恒儺鍞圭紓鍌氬€风粈渚€宕愰崫銉х煋鐟滅増甯掔粻鏍ㄧ箾閸℃ɑ鎯勯柡浣告閺屾稓浠﹂崜褏鐓傚┑鈩冨絻濞差厼顫忕紒妯肩懝闁逞屽墮宀h儻顦虫い銊e劥缁犳盯寮撮悙鐢电摌闂備礁鎲¢幐鍡涘礋椤愩垹绠查梻鍌欒兌缁垶宕濋敃鍌氱婵炲棙鍔楅々鍙夌節婵犲倻澧涢柣鎾寸懇閹鈽夊▎瀣窗缂備胶濮甸悧婊堝焵椤掑倹鍤€闁硅绱曢幑銏ゅ礋椤撶噥娼熼梺鍦劋椤ㄥ繘寮繝鍥ㄧ厱闁圭偓顨呴崯浼搭敃婵傚憡鈷掑〒姘e亾婵炰匠鍥ㄥ亱闁绘劗鏁哥粈濠偯归敐鍛喐闁哄棴闄勯幈銊ヮ渻鐠囪弓澹曢梻浣虹《閺咁亞鎹㈠┑鍡欐殾婵せ鍋撳┑鈩冩倐婵$柉顧侀柛姘儔濮婂宕掑顑藉亾瀹勬噴褰掑炊椤掑鏅悷婊冪箻閸┾偓妞ゆ帊鑳堕埢鎾绘煛閸涱喚绠橀柛鎺撳笒閳诲酣骞樺畷鍥跺敽闂備胶鎳撻顓熸叏鐎靛摜涓嶉柣銏犳啞閻撶喖鏌eΟ鍝勫笭闁煎壊浜弻娑㈠棘閸噮鍔夌紓浣割儏椤︻垶顢樻總绋垮耿婵☆垰鎼导搴㈢節绾板纾块柛瀣█椤㈡俺顦崇紒鍌氱У閵堬綁宕橀埞鐐闂備礁鎲$换鍌溾偓姘煎灦閿濈偤鏁冮崒娑氬幈闂佸搫鍊藉▔鏇㈡倿閹间焦鐓曢柍鐟扮仢閸旀粎鈧灚婢樼€氼厾鎹㈠☉銏狀潊闁靛繒濮甸悗楣冩倵閸偅绶查悗姘嵆楠炲棝宕掗悙韫炊闂侀潧顦介悘鏍箣閿旇В鎷洪梻鍌氱墛缁嬫帡骞栭幇鐗堝€垫慨妯哄船椤g厧菐閸パ嶈含妤犵偞鐗楅幏鍛喆閸曨剛褰搁梻鍌欑閹测剝绗熷Δ鍛偍闁煎綊鍋婇弶娲⒒閸屾艾鈧悂宕愬畡鎳婂綊宕堕澶嬫櫔闂佸搫绋侀崢鑲╃玻濡や椒绻嗛柕鍫濇噺閸f椽鏌涚€e墎绡€闁哄苯绉瑰畷顐﹀礋椤掆偓濞咃繝姊洪柅鐐茶嫰閸樺摜绱掗懜浣冨妞ゆ洩缍侀、姘跺焵椤掆偓閻g兘鎮℃惔妯绘杸闂佸壊鍋掗崑鍛櫏濠电姷顣槐鏇㈠磻閹达箑纾归柡宥庡幖缁犱即鏌ゆ慨鎰偓鏍х暦閺屻儲鐓曢柡鍥ュ妼楠炴﹢鏌i鐐搭棦闁哄本鐩鎾Ω閵壯傜敾闂備焦濞婇弨杈╂暜閿熺姴钃熸繛鎴炵煯濞岊亪鏌涢幘妤€瀚▍妤冪磽閸屾瑦顦烽柤瀹犲煐閺呰泛螖閸涱厙锕傛煕閺囥劌鐏犻柛妤佸▕閺岋綁寮幐搴㈠創闂佸啿鍢查惌鍌炲箖濡ゅ啯鍠嗛柛鏇ㄥ墰閿涙盯姊洪崨濠庢當闁哥喎娼¢、姘舵晲閸℃瑯娴勯柣搴到閻忔岸寮插┑瀣拺闂傚牊绋撴晶鏇熺箾閺夋垵鈧ǹ宓勭紓浣割儏缁ㄩ亶寮ㄦ禒瀣厽婵☆垵娅f禒娑㈡煛閸″繑娅呴柍瑙勫灴椤㈡瑩鎳為妷銉ユ敪闁诲氦顫夊ú姗€宕濋弽顐e床婵犻潧妫ḿ鈺傘亜閹哄秵绁扮紒韬插灲濮婄粯鎷呴悷閭﹀殝濠电偛寮堕悧鐘茬暦閹邦垬浜归柟鐑樻尭娴滄鈹戦悙鍙夘棡闁告梹鍨剁粋宥呪堪閸喓鍘搁悗骞垮劚妤犲憡绂嶅⿰鍏犲綊鎮╁畷鍥╃厐闂傚洤顦扮换婵囩節閸屾稑娅e銈忕悼閸樠嗗絹闂佹悶鍎滃鍫濇儓闂備胶鎳撶壕顓熸叏閻㈠憡鏅柟閭﹀厴閺€浠嬫煕閳╁喛渚涢柛鐐寸叀濮婂宕掑▎鎴М闂佹眹鍊曞ú顓㈡晲閻愭潙绶為柟閭﹀墮閻庮參姊虹粔鍡楀濞堟棃鏌¢崟鈺佸姦闁哄本鐩鎾Ω閵壯傚摋缂傚倷璁查崑鎾绘煕閹伴潧鏋熼柣鎾崇箰閳规垿鎮欓幋婵嗘殲闁革絿鍏橀弻娑氣偓锛扁偓閸嬫捇寮妷锔芥澑闂備焦瀵х粙鎴犫偓姘煎墯缁傚秵绺介崨濠勫幈婵犵數鍋涢悘婵嬪焵椤掍胶绠撻柣锝囧厴婵偓閹烘娊宕戦崨瀛樼厱闁规壋鏅涙俊鎸庛亜锜婚崘锝嗘杸闂佸疇妫勫Λ妤呮倶閻斿吋鍋i柍褜鍓熼弫鍐磼濮橆剚鍎梻浣告惈濞层垽宕瑰ú顏勭;闁挎繂顦伴悡鏇㈡煏婢舵稓鍒板┑鈥虫健閺屾洟宕煎┑鍫熸喖婵烇絽娲ら敃顏堢嵁閹捐绠抽柡鍌氱氨閸欐椽姊绘担鍛婃儓闁哄牜鍓欑叅婵犻潧鐗忔稉宥嗙箾閹存瑥鐏╅柛妤佸▕閺岋綁骞嬪┑鍥舵!缂傚倸绉撮惌鍌氼潖缂佹ɑ濯寸紒瀣濮f劙姊洪崷顓涙嫛闁稿锕悰顔界節閸涱垳鏉稿┑鐐村灦閻熴儲绂嶅Δ鍛棅妞ゆ劑鍨烘径鍕煙鐏忔牗娅婇柟顔哄灲瀹曞崬鈽夊▎蹇庡寲濠德板€ч梽鍕偓绗涘浂鏁傞柣妯烘▕閻斿棛鎲告惔鈭舵椽鎮㈤悡搴ゆ憰濠电偞鍨崹鍦尵瀹ュ鐓冪憸婊堝礈閻旇偐宓侀柟鐗堟緲缁狀噣鏌﹀Ο渚Ъ闁硅姤娲栭埞鎴︽倷閺夋垹浠ч梺鎼炲妿閹虫捁鐏嬪┑鈽嗗灥瀹曠數绮绘ィ鍐╃厱闁斥晛鍟伴幊鍐瑰⿰鍕姢閾绘牠鏌¢崘銊モ偓鑽ゅ娴犲鐓曢悘鐐插⒔閹冲嫮绱掓担瑙勭凡妞ゎ亜鍟伴埀顒佺⊕钃遍柛濠冨姈椤ㄣ儵鎮欓弶鎴濐潔缂備胶绮换鍌烇綖濠靛鏁嗛柛灞诲€曢弫鎼佹⒒閸屾瑧顦﹂柟娴嬪墲缁楃喎螖閸涱厼鐎梺瑙勫劶婵倝宕曞Δ浣虹闁糕剝蓱鐏忣厾绱掗悩鑼Ш闁诡喗顨呴埥澶娾枍閾忣偄鐏╁ù婊勬倐椤㈡﹢鎮橀懡銈嗗殌妤楊亙鍗冲畷濂稿閵忊剝鐦掗梻鍌欑閹碱偊寮甸鍌滅煓闁硅揪绠戦悡姗€鏌熸潏鍓х暠缂佲偓鐎n偁浜滈柟鎵虫櫅閻忊晝鎮鈧濠氬磼濞嗘垵濡藉┑锛勫仜濞尖€崇暦閵忥紕顩烽悗锝庝簽椤斿洦淇婇妶蹇曞埌闁哥噥鍋嗙划濠氭偄閸忚偐鍘甸梻鍌氬€搁顓㈠礉瀹ュ鐓曢悗锝庝憾閸庢棃鏌$仦鍓ф创妞ゃ垺娲熼弫鎰板炊閳哄啯姣夐梻鍌欐祰瀹曠敻宕伴崱娑樼闁瑰瓨绻嶅ḿ鏍ㄧ箾瀹割喕绨诲ù鑲╁█閺屾盯寮撮姀鈩冮敪闂佸憡鎼╅崰姘辨閹惧瓨濯撮柦妯侯槺閸橆偊鎮楅崗澶婁壕缂備礁顑嗛娆撳吹閺囩偐鏀介柣妯虹-椤f煡鏌涚€n亜顏柡宀嬬秮楠炴﹢鎼归锝呴棷婵$偑鍊х€靛矂宕i崘顔肩畺鐎瑰嫭澹嬮崼顏堟煕閹板吀绨芥い鏂匡躬濮婄儤娼幍顔跨獥闂佸摜濮甸悧鐘诲春閵夛箑绶為柟閭﹀墻濞煎﹪姊洪幐搴b槈閻庢凹鍓熼悰顕€骞囬悧鍫氭嫽婵炶揪绲介幉锟犲疮閻愬眰鈧帒顫濋褎鐤侀悗瑙勬礃濠㈡ǹ鐏冮梺鍛婁緱閸橀箖鏁嶅▎鎾粹拺閻熸瑥瀚ˉ瀣熆瑜庨〃濠囧箖閳ユ枼妲堥柕蹇娾偓鏂ュ亾閸洘鐓熼柟浼村亰閺夋椽鏌涢妶鍡欐噧闁宠鍨块、娆撴偂鎼存ê浜鹃柛褎顨呴拑鐔兼煟閺冨倵鎷¢柡浣革躬閺屾稑鈹戦崱妤婁槐闂佺ǹ顑嗛幐鎼佸煘閹达箑骞㈡繛鍡樺姈椤旀洟姊绘担鍛婅础闁稿簺鍊濆畷褰掓偄閼茬尨缍佸畷濂告偄缁嬪灝浼庢繝寰锋澘鈧劙宕戦幘缈犵箚妞ゆ劧绲鹃埛鎺撲繆閸欏濮嶉柡浣规崌閺佹捇鏁撻敓锟� ---闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁绘劦鍓欓崝銈囩磽瀹ュ拑韬€殿喖顭烽弫鎰緞婵犲嫷鍚呴梻浣瑰缁诲倿骞夊☉銏犵缂備焦岣块崢杈ㄧ節閻㈤潧孝闁稿﹤缍婂畷鎴﹀Ψ閳哄倻鍘搁柣蹇曞仩椤曆勬叏閸屾壕鍋撳▓鍨珮闁革綇绲介悾閿嬬附閸涘﹤浜滈梺鍛婄☉楗挳宕崼鏇熲拻闁稿本鐟ㄩ崗宀勫几椤忓懌浜滈柟瀛樼箖椤ャ垺顨ラ悙鏉戝鐎规洘绮忛ˇ鏌ユ煕閵婏妇绠栭柕鍥у楠炴ḿ鎹勬潪鐗堢潖婵犵鍓濊ぐ鍐偋婵犲啰鈹嶅┑鐘叉祩閺佸秵鎱ㄥ鍡楀箺闁稿孩鎸剧槐鎾存媴閸濆嫅顒併亜閺囧棗娲ら悡姗€鏌熸潏楣冩闁稿﹦鍏橀弻娑樷枎韫囷絾孝闂佸搫顑嗛悷锔炬崲濞戞埃鍋撳☉娆嬬細闁活厼顑囩槐鎺楊敊閼恒儱纾冲Δ鐘靛仜閸熸挳宕规ィ鍐ㄦ闁靛瀵屽ḿ鏃堟⒒娓氣偓濞佳勵殽韫囨洘顫曢柡鍥ュ灩閸屻劑鏌涘Δ鍐ㄤ汗闁衡偓娴犲鐓熼柟閭﹀幗缂嶆垿鏌h箛瀣姢闁逞屽墲椤煤閿曞倸绀堥柣鏂垮悑閸嬫ɑ銇勯弬鎸庮潔闁绘梹鍝鸿瀹曞爼鏁傞崜褎鏅ㄩ梻鍌氬€风粈渚€骞栭锕€纾归柛锔诲幐閸嬫挾绮☉妯荤〗濠㈣埖鍔曢~鍛存煃閳轰礁鏆欑€殿喗瀵х换婵嬫偨闂堟刀銏ゆ煙閸愯尙绠绘い銏℃閹晝绱掑Ο鐓庡箥闂備浇宕甸崰鎰熆濮椻偓椤㈡棃顢橀悙鈺傛杸闂佹枼鏅涢崯顖炲磹閹邦兘鏀介柨娑樺閸樻挳鏌℃担绋库偓鍧楃嵁閸℃凹妲剧紓浣割儏閻楁挸顫忔繝姘<婵﹩鍏橀崑鎾绘倻閼恒儱娈戦梺鍓插亝濞叉牜绮婚悩缁樼厵闁硅鍔﹂崵娆撴煕濮橆剛绉洪柡灞糕偓鎰佸悑閹肩补鈧磭顔愮紓鍌欒兌婵參宕归崼鏇炶摕闁靛ň鏅滈崑鍡涙煕鐏炲墽鈽夋い蹇ユ嫹
开发学院软件开发C++ corba核心规范 阅读

corba核心规范

 2008-03-08 12:54:46 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劎绮妵鍕箳鐎n亞浠鹃梺闈涙搐鐎氫即鐛崶顒夋晬婵絾瀵ч幑鍥蓟閻斿摜鐟归柛顭戝枛椤牆顪冮妶搴′簼缂侇喗鎸搁悾鐑藉础閻愬秵妫冮崺鈧い鎺戝瀹撲礁鈹戦悩鎻掝伀缁惧彞绮欓弻娑氫沪閹规劕顥濋梺閫炲苯澧伴柟铏崌閿濈偛鈹戠€n€晠鏌嶆潪鎷屽厡闁汇倕鎳愮槐鎾存媴閸撴彃鍓卞銈嗗灦閻熲晛鐣烽妷褉鍋撻敐搴℃灍闁绘挻娲橀妵鍕箛闂堟稐绨肩紓浣藉煐濮樸劎妲愰幘璇茬闁冲搫鍊婚ˇ鏉库攽椤旂》宸ユい顓炲槻閻g兘骞掗幋鏃€鐎婚梺瑙勬儗閸樺€熲叺婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閳锋垶銇勯幒鍡椾壕缂備礁顦遍弫濠氱嵁閸℃稒鍊烽柛婵嗗椤旀劕鈹戦悜鍥╃У闁告挻鐟︽穱濠囨嚃閳哄啰锛滈梺褰掑亰閸欏骸鈻撳⿰鍫熺厸閻忕偟纭堕崑鎾诲箛娴e憡鍊梺纭呭亹鐞涖儵鍩€椤掑啫鐨洪柡浣圭墪閳规垿鎮欓弶鎴犱桓闂佸湱枪閹芥粎鍒掗弮鍫熷仺缂佸顕抽敃鍌涚厱闁哄洢鍔岄悘鐘绘煕閹般劌浜惧┑锛勫亼閸婃牠宕濋敃鈧…鍧楀焵椤掍胶绠剧€光偓婵犱線鍋楀┑顔硷龚濞咃絿妲愰幒鎳崇喓鎷犻懠鑸垫毐闂傚倷鑳舵灙婵炲鍏樺顐ゆ嫚瀹割喖娈ㄦ繝鐢靛У绾板秹寮查幓鎺濈唵閻犺櫣灏ㄥ銉р偓瑙勬尭濡繂顫忛搹鍦<婵☆垰鎼~宥囩磽娴i鍔嶉柟绋垮暱閻g兘骞嬮敃鈧粻濠氭偣閸パ冪骇鐎规挸绉撮—鍐Χ閸℃ê闉嶇紓浣割儐閸ㄥ墎绮嬪澶嬪€锋い鎺嶇瀵灝鈹戦埥鍡楃仯闁告鍕洸濡わ絽鍟崐鍨叏濡厧浜鹃悗姘炬嫹闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劌銈搁弻鐔兼儌閸濄儳袦闂佸搫鐭夌紞渚€銆佸鈧幃娆撳箹椤撶噥妫ч梻鍌欑窔濞佳兾涘▎鎴炴殰闁圭儤顨愮紞鏍ㄧ節闂堟侗鍎愰柡鍛叀閺屾稑鈽夐崡鐐差潻濡炪們鍎查懝楣冨煘閹寸偛绠犻梺绋匡攻椤ㄥ棝骞堥妸鈺傚€婚柦妯侯槺閿涙稑鈹戦悙鏉戠亶闁瑰磭鍋ゅ畷鍫曨敆娴i晲缂撶紓鍌欑椤戝棛鈧瑳鍥ㄥ€垫い鎺戝閳锋垿鏌i悢鍛婄凡闁抽攱姊荤槐鎺楊敋閸涱厾浠搁悗瑙勬礃閸ㄥ潡鐛崶顒佸亱闁割偁鍨归獮宥囩磽閸屾艾鈧兘鎮為敃鍌涙櫔缂傚倷鐒﹂妵鍡涘炊閵娧冨笚闁荤喐绮嶇划鎾崇暦濠婂牊鏅濋柛灞炬皑閻撴垿姊洪崨濠傚Е闁绘挸鐗嗗玻鍧楀冀椤撶喓鍘卞┑鐘绘涧濡鎮甸弮鍌涘枑闁哄倽娉曢弳锕傛煙椤栫偛浜版俊鑼亾缁绘稓鈧數枪瀛濋梺闈涚墢鏋い顐㈢箻閹煎湱鎲撮崟顐ゅ酱闂備浇鍋愰埛鍫ュ礈濞戙埄鏁婂鑸靛姈閳锋垿鏌i幘铏崳缂佸娅g槐鎺楁偐瀹曞洤鈷屽Δ鐘靛仜閸燁垶濡堕敐澶婄闁宠桨璁查崑鎾寸節濮橆厾鍙冨┑鈽嗗灟鐠€锕€危婵傚憡鐓欓柤鎭掑劜缁€瀣叏婵犲啯銇濇俊顐㈠暙閳藉娼忛…鎴斿亾閸℃ḿ绡€缁剧増菤閸嬫捇鎼归銏$亷闁诲氦顫夊ú蹇涘垂娴犲绠栧ù鐘差儏瀹告繂鈹戦悙闈涗壕閻庢艾銈稿娲嚒閵堝懏鐎鹃梺鑽ゅ枂閸庢娊鍩€椤掍焦鐨戦柛蹇斆悾鐑筋敍濠靛牏鏉稿┑鐐村灦閻熝囧储闁秵鈷戠紓浣光棨椤忓棗顥氭い鎾跺枑濞呯娀鏌i姀鐘冲暈闁绘挸绻橀弻娑㈠焺閸愮偓鐣堕梺閫炲苯澧繝鈧潏鈺冪=闁规儳顕々鐑芥倵閿濆簼绨荤紒鎰⊕缁绘繈鎮介棃娴躲垽鎮楀鐓庡⒋闁绘侗鍣e畷濂稿Ψ閿旇瀚肩紓浣鸿檸閸樺ジ骞婃惔銊嬪顓兼径瀣幍濠电偠灏濠勮姳閼恒儰绻嗛柛娆忣槸婵秶鈧鍠楅幐鎶藉箖閵忋倕浼犻柛鏇樺妼瑜板繘姊婚崒姘偓鎼佸磹閹间礁纾瑰瀣椤愯姤鎱ㄥ鍡楀幊缂傚倹姘ㄩ幉绋款吋閸パ冪柧闂傚倷绶氬ḿ褔鎮ч崱妞曟椽鎮╃拠鑼紱闂佸湱鍋撻崜姘缚閳哄倶浜滈柟鎵虫櫅閻忊晝绱掓笟鍥ф珝婵﹨娅g槐鎺懳熼崷顓犵畳闂備線娼荤紞鍥╃礊娓氣偓閹即顢氶埀顒勭嵁閹烘绠犻柧蹇e亝椤ュ牓鏌涢埞鎯т壕婵$偑鍊栫敮鎺楀磹缂佹ḿ鈻旂€广儱顦伴悡銉︾節闂堟稒顥炴い銉уХ缁辨帡鍩﹂埀顒勫磻閹剧粯鈷掗柛灞捐壘閳ь剚鎮傞幃褎绻濋崟顓犵厯闂佺鎻粻鎴澬ч崣澶岀闁糕剝顨堢拹鈺呮煟閻旂ǹ顥愰柛顐邯閺屾盯顢曢悩鑼紕闂佸搫妫崑濠傤潖濞差亜浼犻柛鏇ㄥ幘閸斿湱绱撻崒姘毙¢柣鎺炵畵楠炲牓濡搁埡浣哄姦濡炪倖甯掔€氼參鎮¢崘顔界厵妞ゆ牗绮岄。鑲╃棯椤撶姴浜剧紒缁樼箞閸┾偓妞ゆ帊鐒︾紞鍥煏婵炑冩噹妤犲嫰姊绘担鍛婃儓婵炲眰鍔戝畷浼村箻鐠哄搫袣闂侀€炲苯澧柍瑙勫灴椤㈡瑩寮妶鍕繑闂備礁鎲¢敃銏㈢不閺嵮呮殾闁靛繈鍊栭崑銊╂煕濞戞☉鍫ュ箯閾忓湱纾介柛灞剧懅閸斿秹鏌ㄥ顑芥斀妞ゆ洖妫涢悾鐢告煛鐏炲墽娲存鐐达耿瀵爼骞嬪┑鍥ㄥ殘闂傚倷娴囬鏍窗濡ゅ嫭鎳屾繝鐢靛仧閸樠呮崲濡绻嗛柟闂寸鍥撮梺鎼炲劗閺呮繈寮虫导瀛樷拻闁稿本鐟чˇ锔界節閳ь剚娼忛埡浣哥亰濡炪倖鐗楃划宥夊汲濠婂牊鐓熼柟閭﹀墰閹界姵绻涢崨顖毿g紒缁樼洴楠炲鎮欑€靛憡顓荤紓浣哄亾瀹曟﹢宕戦幇顔筋潟闁规儳鐡ㄦ刊鎾偣閹伴潧鐏g紒杈ㄦ緲閳规垿鎮欓弶鎴犵シ濡炪倖娲﹂崣鍐春閳ь剚銇勯幒鎴濇灓婵炲吋鍔栫换娑㈠矗婢跺苯鈪归梺浼欑悼閸忔﹢銆佸Δ鍛妞ゅ繐鍟伴懗娲⒒閸屾艾鈧绮堟笟鈧獮澶愭晸閻樿尙顦梺鍝勬储閸ㄥ綊鎮块鈧弻锝呂熷▎鎯ф缂備讲鍋撻柛顐ゅ枔缁♀偓闂傚倸鐗婄粙鎾存櫠濞戞埃鍋撶憴鍕鐎殿喖澧庨幑銏犫槈閵忕姷顓洪梺缁樺姂閸斿海妲愭导瀛樷拺闁告繂瀚ˉ婊勪繆椤愶綆娈滈柛鈺冨仱楠炲鏁傞挊澶夋睏闂佸搫顦悧婊堝磻閸曨垰鍌ㄩ柨鐔哄У閳锋垿寮堕悙鏉戭棆闁告柨绉归弻锝呂旀担铏圭厒濠碘€冲级閸旀瑩鐛Ο灏栧亾濞戞顏堫敁閹惧绠鹃悗鐢登瑰瓭濡炪倖鍨甸幊姗€鐛Δ鍛仺闁告稑艌閹锋椽姊洪棃鈺佺槣闁告ü绮欏畷鐢稿焵椤掆偓閳规垿鎮欓懠顒佸嬀闂佺ǹ锕ョ换鍫ョ嵁閸愨斂鍋呴柛鎰ㄦ櫅閳ь剙顭烽弻锕€螣娓氼垱楔濡炪倖鏌ㄩ敃顏勵潖閾忚鍠嗛柛鏇ㄥ墮閸撳綊姊洪崨濞掕偐鍒掑▎蹇曟殾闁瑰墽绮崑銊╂煕濞戞☉鍫ュ箯濞差亝鈷戦柤濮愬€曢弸鎴炵節閵忊槄鑰挎鐐插暞缁楃喖鍩€椤掑嫬钃熼柨婵嗩槸缁犳娊鏌i幇顔芥毄闁哄棎鍊濆铏规嫚閳ヨ櫕鐏嶅銈冨妼閿曨亪鎮伴鈧浠嬪Ω閿曗偓椤庢捇姊虹粙璺ㄧ妞わ附澹嗛埀顒佷亢濡嫰鍩為幋锔藉€烽柤鎼佹涧濞懷呯磽娴g懓绲绘繛灏栤偓宕囨殾闁哄洢鍨瑰洿婵犮垼娉涢敃銈夊箚閻愮儤鈷戦梺顐ゅ仜閼活垱鏅剁€涙ɑ鍙忓┑鐘插暞閵囨繃顨ラ悙瀵稿⒌闁诡喗鐟ラ湁閻庯綆浜欐竟鏇㈡⒑閸濆嫮鈻夐柛妯圭矙瀹曟垹鈧綆鍠楅悡鐔镐繆椤栨氨浠㈤柛姘贡閳ь剝顫夐幐椋庢濮樿埖鍋傛い鎰剁畱閻愬﹪鏌曟繛褉鍋撳┑顔兼喘濮婃椽宕崟顒€娅ら梺璇″枛閸婂灝顕f繝姘╅柍鍝勫€告禍鐐烘⒑缁嬫寧婀扮紒瀣灴椤㈡棃鏁撻敓锟�濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻橀弻锝夊箣閿濆棭妫勯梺鍝勵儎缁舵岸寮诲☉妯锋婵鐗婇弫楣冩⒑閸涘﹦鎳冪紒缁橈耿瀵鏁愭径濠勵吅闂佹寧绻傚Λ顓炍涢崟顖涒拺闁告繂瀚烽崕搴g磼閼搁潧鍝虹€殿喛顕ч埥澶娢熼柨瀣垫綌婵犳鍠楅〃鍛存偋婵犲洤鏋佸Δ锝呭暞閳锋垿鏌涘☉姗堝姛闁瑰啿鍟扮槐鎺旂磼濡櫣浼屾繝纰夌磿閺佽鐣烽悢纰辨晬婵﹢纭搁崯瀣⒒娴e憡鍟炴い銊ョ墦瀹曟垿鎮㈤崫銉祫闂佸吋绁撮弲婵堝閽樺褰掓晲閸涱喗鍎撳銈呴閻倿寮诲☉銏犖╅柕澹啰鍘介柣搴㈩問閸犳盯顢氳閸┿儲寰勯幇顒夋綂闂佺粯岣块弫鎼佸级閹间焦鈷掗柛灞捐壘閳ь剚鎮傞幃褎绻濋崟顓犵厯闂佸湱鍎ら〃鍡涘磹閸洘鐓曟い鎰Т閸旀粓鏌涙繝鍕毈闁哄矉缍侀幃銏ゅ传閸曞灚姣夐梻浣告憸閸犳捇宕戦悢鐑橆潟闁圭儤姊圭€氭岸鏌熺紒妯虹瑲婵炲牏绮换婵堝枈婢跺瞼锛熼梺杞版祰椤曆囨偩閻戣姤鍋勭痪鎷岄哺閺咁剙鈹戦鏂よ€跨痪顓熸倐瀹曨垳鈧綆鍠楅埛鎴︽偣閸ャ劎鍙€闁告瑥瀚换娑欐媴閸愬弶鎼愮紒鐘靛劋缁绘繃绻濋崒婊冾杸闂佺ǹ顑傞弲娑㈠煘閹达箑纾兼慨姗嗗幖閺嗗牓姊洪幎鑺ユ暠闁搞劌缍婇幆鈧い蹇撶墱閺佸洭鏌i幇顓熺稇妞ゅ孩绋戦埞鎴︽倷閹绘帗鍊梺鍛婃⒐閻楁粓骞戦姀鐘闁靛繆鈧櫕顓绘俊鐐€栧濠氬磻閹剧粯鐓涢悗锝庝簻椤掋垽鏌曢崶褍顏い銏℃礋婵偓闁靛繈鍩勯崬铏圭磽閸屾瑦绁板鏉戞憸閺侇噣骞掗弴鐘辫埅闂傚倷绀侀崥瀣矈閹绢喖鐤炬繝濠傜墕閸氬湱鈧厜鍋撻柛鏇ㄥ厴閹风粯绻涢幘鏉戠劰闁稿鎹囬弻宥堫檨闁告挻鐩畷鎴濃槈閵忊€虫濡炪倖鐗楃粙鎺戔枍閻樼偨浜滈柡鍐ㄦ搐娴滃綊鏌¢崱妤侇棦闁哄被鍔岄埞鎴﹀幢濞嗗浚鏆梻浣告啞閺屻劑鎮樺璺何﹂柛鏇ㄥ灡閺呮粓鏌i敐鍛板鐎殿喓鍔戝铏规嫚閳ヨ櫕鐝紓浣虹帛缁诲啯绌辨繝鍥ㄥ殝闂傚牊绋撶粣鐐烘煟鎼搭垳绉甸柛鎾寸懅閺侇喗銈i崘鈹炬嫽婵炶揪绲挎灙妞ゃ儱绻橀弻娑氣偓锝庝簼閸d粙鏌熼獮鍨伈鐎规洘锕㈤、娆撴嚃閳哄骞㈠┑锛勫亼閸婃洜鎹㈤幇鏉跨疇闁归偊鍠氭稉宥夋煕閹炬せ鍋撻柛瀣崌閹兘寮跺▎鐐棏闂備礁鎽滄慨闈浢哄⿰鍫熷殟閺夊牄鍔庣弧鈧┑顔斤供閸撴盯鎮炬ィ鍐┾拺缂備焦蓱閻撱儵鏌涘顒夊剶闁糕晜鐩獮瀣晜閽樺鍋撻悽鍛婄厱闁挎棁顕ч獮鏍冀閿熺姵鈷戦梻鍫熺⊕椤ユ粓鏌涢悢鍛婂唉鐎殿喖顭锋俊鑸靛緞婵犲嫷妲伴梻浣藉亹閳峰牓宕滃▎鎾村亗闁绘柨鍚嬮崐鐢告偡濞嗗繐顏紒鈧崘顏嗙<閻犲洩灏欐晶锔锯偓娈垮櫘閸嬪﹤鐣峰鈧、娆撴嚃閳轰礁袝濠碉紕鍋戦崐鏍暜閹烘柡鍋撳鈧崶褏鍔﹀銈嗗笂閻掞箓藟閸懇鍋撶憴鍕闁挎洏鍨介妴浣糕枎閹惧啿绨ユ繝銏n嚃閸ㄦ澘煤閿曞倹鍋傞柡鍥ュ灪閻撳啴鏌嶆潪鎵槮闁哄鍊栫换娑㈠醇閻曞倽鈧潡鏌″畝瀣М闁诡喓鍨荤划娆撳垂椤曞懏缍掑┑鐘愁問閸犳牠鏁冮妷銉富濞寸姴顑呯粻鏍煃閳轰礁鏆為柛搴e枛閺屽秹鍩℃担鍛婃闂佷紮璁g紞浣割潖缂佹ɑ濯撮柧蹇曟嚀缁楋繝姊虹紒姗嗘畷婵炶尙鍠愭穱濠囧礈娴h櫣鐓撻柣鐘充航閸斿秴鈻撴ィ鍐┾拺缂備焦锚閻忥箑鐣濋敐鍫熺《鐎殿啫鍥х劦妞ゆ帒瀚埛鎴︽煙閼测晛浠滈柛鏂哄亾闂備礁鎲¢崝鎴﹀礉鎼淬劌围妞ゆ洍鍋撴慨濠傤煼瀹曟帒鈻庨幋鐘靛床婵犵數鍋橀崠鐘诲礋閸偒鍟嶉梻濠庡亜濞诧箑煤濮椻偓閿濈偤寮撮姀锛勫幐闂佹悶鍎崕閬嶆倶閳哄懏鐓曢悘鐐额嚙婵′粙鏌曢崶褍顏紒鐘崇洴楠炴ḿ鎹勬笟顖涙緫闂傚倷鐒︽繛濠囧绩闁秴鍨傞柛褎顨呴拑鐔兼煟閺傚灝鎮戦柛銈呭暣閺屽秵娼悧鍫▊缂備緡鍠栭悥鐓庮潖濞差亜宸濆┑鐘插暊閹风懓顪冮妶鍐ㄥ闁挎洦浜滈锝嗙節濮橆厽娅㈤梺缁樕戣ぐ鍐玻濞戞﹩娓婚柕鍫濇椤ュ牓鏌℃笟鍥ф灍闁逛究鍔戝畷鍫曞煛閸愵亷绱冲┑鐐舵彧缁叉寧鐏欓梺閫炲苯澧繝鈧柆宥呮瀬妞ゆ洍鍋撻柟顔哄灪娣囧﹪骞橀搹顐㈢獩闂侀€炲苯澧存繛浣冲洤绠烘繝濠傛噹椤ユ艾鈹戦崒婧撳湱鐥閺屾盯顢曢敐鍥f婵犲痉銈呬汗缂佽鲸甯掕灃濞达絼璀﹂弳锛勭磽娴h櫣甯涢柣鈺婂灦楠炲啴鍩勯崘鈺佸妳闂佹寧绻傚ù鍌炲疮鐎n喗鈷掑ù锝堟閵嗗﹪鏌¢崒娆戠獢鐎规洘绮岄埞鎴犫偓锝庝簽椤斿棝姊洪崨濠勨槈闁宦板姂閹繝濡烽埡鍌氣偓鐢告煥濠靛棙鍣藉ù鐘崇〒缁辨挸顓奸崱鈺傜杹濠殿喖锕ら…宄扮暦閹烘埈娼╂い鎴f娴滃墽鈧懓瀚崳纾嬨亹閹烘垹鍊為悷婊勭矊闇夐柡宥庡幗閻撳繐鈹戦悙闈涗壕婵炲懎妫濋弻娑欑節閸屾稑浠撮梺鍝勮閸旀垵顕i幘顔藉€锋繛鏉戭儏娴滈箖鏌涘┑鍕姢濞戞挸绉归弻锛勪沪鐠囨彃濮曢梺缁樻尰濞茬喖寮婚弴鐔风窞婵☆垳鍎ら悘鍫熺節閳封偓鐏炶姤鐝濋梺鍝勭焿缁辨洟鍩€椤掑﹦宀涢柡鍛箘缁綁寮崼鐔哄幐閻庡厜鍋撻柍褜鍓熷畷浼村冀瑜忛弳锔界節婵犲倹锛嶆俊鏌ョ畺閺岋綁濮€閳轰胶浠梺鐑╂櫓閸ㄨ泛顕f繝姘櫢闁绘ɑ褰冪粣娑橆渻閵堝棙顥嗘俊顐㈠閸┾偓妞ゆ帊绀佹慨宥夋煛瀹€瀣?濞寸媴濡囬幏鐘诲箵閹烘繃缍嗛梻鍌欐祰椤曟牠宕伴幘璇茬9婵犻潧妫涢弳锕傛煙閻戞ê鐏嶆俊鎻掔墛閹便劌螖閳ь剙螞閺冨倹顫曢柨鐕傛嫹闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劎绮妵鍕箳鐎n亞浠鹃梺闈涙搐鐎氫即鐛崶顒夋晬婵絾瀵ч幑鍥蓟閻斿摜鐟归柛顭戝枛椤牆顪冮妶搴′簼缂侇喗鎸搁悾鐑藉础閻愬秵妫冮崺鈧い鎺戝瀹撲礁鈹戦悩鎻掝伀缁惧彞绮欓弻娑氫沪閹规劕顥濋梺閫炲苯澧伴柟铏崌閿濈偛鈹戠€n€晠鏌嶆潪鎷屽厡闁汇倕鎳愮槐鎾存媴閸撴彃鍓卞銈嗗灦閻熲晛鐣烽妷褉鍋撻敐搴℃灍闁绘挻娲橀妵鍕箛闂堟稐绨肩紓浣藉煐濮樸劎妲愰幘璇茬闁冲搫鍊婚ˇ鏉库攽椤旂》宸ユい顓炲槻閻g兘骞掗幋鏃€鐎婚梺瑙勬儗閸樺€熲叺婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閳锋垶銇勯幒鍡椾壕缂備礁顦遍弫濠氱嵁閸℃稒鍊烽柛婵嗗椤旀劕鈹戦悜鍥╃У闁告挻鐟︽穱濠囨嚃閳哄啰锛滈梺褰掑亰閸欏骸鈻撳⿰鍫熺厸閻忕偟纭堕崑鎾诲箛娴e憡鍊梺纭呭亹鐞涖儵鍩€椤掑啫鐨洪柡浣圭墪閳规垿鎮欓弶鎴犱桓闂佸湱枪閹芥粎鍒掗弮鍫熷仺缂佸顕抽敃鍌涚厱闁哄洢鍔岄悘鐘绘煕閹般劌浜惧┑锛勫亼閸婃牠宕濋敃鈧…鍧楀焵椤掍胶绠剧€光偓婵犱線鍋楀┑顔硷龚濞咃絿妲愰幒鎳崇喓鎷犻懠鑸垫毐闂傚倷鑳舵灙婵炲鍏樺顐ゆ嫚瀹割喖娈ㄦ繝鐢靛У绾板秹寮查幓鎺濈唵閻犺櫣灏ㄥ銉р偓瑙勬尭濡繂顫忛搹鍦<婵☆垰鎼~宥囩磽娴i鍔嶉柟绋垮暱閻g兘骞嬮敃鈧粻濠氭偣閸パ冪骇鐎规挸绉撮—鍐Χ閸℃ê闉嶇紓浣割儐閸ㄥ墎绮嬪澶嬪€锋い鎺嶇瀵灝鈹戦埥鍡楃仯闁告鍕洸濡わ絽鍟崐鍨叏濡厧浜鹃悗姘炬嫹  闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁绘劦鍓欓崝銈囩磽瀹ュ拑韬€殿喖顭烽弫鎰緞婵犲嫷鍚呴梻浣瑰缁诲倿骞夊☉銏犵缂備焦岣块崢閬嶆⒑闂堟稓澧曢柟鍐查叄椤㈡棃顢橀姀锛勫幐闁诲繒鍋犻褔鍩€椤掍胶绠撻柣锝囧厴椤㈡洟鏁冮埀顒€鏁梻浣瑰濡焦鎱ㄩ妶澶嬪剨閹肩补妾ч弨浠嬫煟閹邦剚鈻曢柛銈囧枎閳规垿顢氶埀顒€岣胯閿濈偛鈹戠€n€晝鎲告惔顭掔稏闁哄洢鍨洪悡娆撴煙鐟欏嫬濮﹂柛銈嗙懅閻ヮ亪骞嗚閹垹绱掔紒妯兼创鐎规洖宕灒闁惧繐婀遍幊鍡涙⒒娴e憡鍟為柨鏇ㄥ亞濡叉劙寮撮悩鎰佹綗闂佽鍎抽顓㈡偡瑜版帗鐓曢柕澶嬪灥鐎氼喛銇愰鐐粹拻濞达綀顫夐崑鐘绘煕閺傝法鐒搁柟顔哄劦瀹曟姊荤€靛摜鐣鹃梻浣告贡閾忓酣宕伴弽顐ょ焼闁告劏鏂傛禍婊堟煛閸愩劌鈧摜鏁崜浣虹<闁归偊鍘惧ú瀛樻叏婵犲啯銇濈€规洦鍋婂畷鐔煎垂椤愬诞鍥ㄢ拺闁硅偐鍋涙俊鑲╃磽瀹ュ拑宸ラ柣锝囧厴婵偓闁绘ê妫欏浠嬨€侀弮鍫濆窛妞ゆ挻绋戞禍楣冩煕椤垵浜芥繛鍫滅矙閺岋綁骞囬姘辨婵炲濮伴崹浠嬪蓟濞戙垹绫嶉柍褜鍓涢崰濠傤吋婢跺á锕傛煕閺囥劌鐏¢柡鍛矒閹綊宕堕鍕婵炲濮甸幃鍌炲箖濡ゅ啯鍠嗛柛鏇ㄥ墰閳规稓绱撴担铏瑰笡缂佽鐗撻幃浼搭敊閼恒儱鍔呴梺闈涒康缁犳垵鈻撻悢鍏尖拺闂傚牊鍐荤槐锟犳煕閹扳晛濡兼い鈺婂墴濮婂宕掑顑藉亾閹间降鍋戦柟缁㈠枛绾惧鏌涢弴銊モ偓瀣洪鍛珖闂侀€炲苯澧伴柛娆忔嚇濮婃椽宕崟顓夌娀鏌涢弬鍨劉闁哄懎鐖奸弫鎾绘偐閺傘儲瀚介梻浣呵归張顒勬偡閿斿墽鐭堥柣妤€鐗勬禍婊堟煛閸パ勵棞闁瑰啿顦靛畷鎴﹀箻鐠囨彃鐎銈嗗姂閸ㄨ櫣鎷犻悙鐑樺€甸悷娆忓缁€鍐磼椤旇姤宕屾鐐插暣婵偓闁挎稑瀚板顔界節閵忥絾纭炬い鎴濇川缁瑦绗熼埀顒€顫忕紒妯诲闁荤喐婢樻慨銏㈢磽娴h櫣甯涢柛鏃€娲熼弫鍐閳╁啰绉堕梺瀹犳〃缁垛€澄涘⿰鍫熲拺缂佸娉曠粻缁樹繆椤愩儲纭堕柟骞垮灲瀹曞崬螣闂€鎰泿闂備礁鎼粔鏌ュ礉鎼淬劊鈧倿寮婚妷锔惧幍濡炪倖鐗楀銊︽櫠濞戙垺鐓忛柛銉戝喚浼冨銈冨灪濞茬喐鎱ㄩ埀顒勬煏韫囧鐏╁┑顔块哺缁绘繂鈻撻崹顔界亪闂佹寧娲忛崝宀勫煝瀹ュ鏅插璺猴功椤斿棝姊虹紒妯剁細缂侇噮鍨跺畷鐢稿箣閻愵亙绨婚梺鍦劋閸ㄥ灚绂嶉悙鐑樼厱闁绘劙顤傚ḿ鎰磼缂佹ḿ绠撻柍缁樻崌瀹曞綊顢欓悾灞兼喚闂備胶鍘ч悘鏇㈠炊閵娧冨箞闂備礁鎼崯鐘诲磻閹剧粯鐓曢柕濞垮劤娴犮垽鏌i敐鍛Щ閻撱倖銇勮箛鎾愁伀闁告棑绠戦—鍐Χ閸℃鐟愰梻鍌氬缁夌數绮嬪鍛牚闁割偆鍠撻崢鐢告⒑閸涘﹦绠撻悗姘煎枦閸婂瓨淇婇悙顏勨偓褏鎷嬮敐鍥╀笉闁规崘顕ч拑鐔哥箾閹存瑥鐏╅崶鎾煙閼测晞藟闁逞屽墯閺嬪ジ骞忛锔解拻濞达絽鎲¢幆鍫ユ煛閸偄澧撮柟顖氬椤㈡盯鎮欓棃娑氥偊婵犵妲呴崹浼村触鐎n亞鏆﹀鑸靛姈閻撶喖鏌熺€电ǹ浜剁紓鍌涘哺閺屽秷顧侀柛鎾寸箞椤㈡俺顦归柍銉︽瀹曟﹢顢欓崲澹洤绠圭紒顔煎帨閸嬫捇鎳犻鍌涙櫒缂傚倸鍊搁崐鐑芥嚄閸撲礁鍨濇い鏍仜缁€澶嬩繆閵堝懏鍣归柣顓燁殜閺屾稑鈽夐崡鐐插濠电偞鎸搁…鐑藉蓟閺囥垹閱囨繝闈涙搐濞呇呯磽娴e搫小闁告濞婇獮鍐ㄎ旈埀顒勶綖濠靛鍋傞幖绮规閹奉偊姊绘担绛嬪殐闁哥姵顨婇妴鍐╃節閸ャ儮鍋撴担鍓叉建闁逞屽墴楠炲啫饪伴崼婵嗚€垮┑鈽嗗灥濞咃絽危閿濆鈷掗柛灞剧懅缁愭梹绻涙担鍐叉处閸嬪鏌涢埄鍐︿簵婵炴垶菤閺嬪酣鏌熺€电ǹ啸闁绘帒銈稿娲焻閻愯尪瀚板褍鐡ㄩ幈銊︾節閸愨斂浠㈤梺璇″枤閸忔ê顕i崼鏇炵閹兼番鍨诲Σ顏堟⒒閸屾艾鈧绮堟担瑙勫劅婵犲﹤鎳庣欢銈吤归悩宸剱闁稿鏅濋埀顒傛嚀鐎氼厽绔熺€n喖閱囨い蹇撶墛閻撴洟鏌¢崶銉ュ濞存粈绮欓弻娑㈠Χ閸愩劉鍋撳┑瀣摕闁挎繂妫欓崕鐔兼煏韫囧﹥鍣板┑顔兼喘閺屻倗鎲楅妶鍛亾濠靛钃熼柣鏂垮悑閻撱儵鎮楅敐搴′簴濞寸姰鍨归埞鎴︻敊绾嘲濮涚紓渚囧櫘閸ㄥ磭鍒掗銏″亜闁绘挸娴烽崐鐐烘偡濠婂啰鐏遍柤楦块哺缁傛帞鈧綆鍋€閹疯櫣绱撴担鍓插剱妞ゆ垶鐟╁畷鏇㈠箛閻楀牏鍘介梺鍐叉惈閿曘倝鎮橀敂绛嬫闁绘劘顕滈煬顒勬煙椤斿搫鐏柛鐘诧攻濞煎繘濡搁敂鐣屽建婵犵數濮烽弫鎼佸磻閻愬搫鍨傞柛顐f礃閸嬶繝鏌ㄩ弴鐐测偓褰掑磻閻旇 鍋撻悷鏉款伃闁稿锕ら妴鎺撶節濮橆厾鍘梺鍓插亝缁诲啴藟閻愮儤鐓熼柟鎯у船閸旀碍銇勯鈥冲姷妞わ附鎸抽弻锟犲椽娴i晲绨肩紓浣规⒒閸犳牕顕i幘顔碱潊闁炽儱鍘栫花鐢告⒑閻熸澘鎮戦柟顖氱焸瀹曟澘顫濈捄楦垮煘闂佹眹鍨归幉锟犳偂閻斿吋鐓熸俊顖滃帶閸斿銇勮箛鏇炩枅闁诡喗枪缁犳稓鈧綆浜滈~鍥倵鐟欏嫭绀冪紒璇茬墦楠炲啴濮€閵堝棙鍎梺闈╁瘜閸欏繒妲愰幓鎺嗘斀闁绘﹩鍠栭悘杈ㄧ箾婢跺銆掗柍褜鍓氱粙鍫ュ疾閻樻眹鈧線寮崼鐔蜂汗缂傚倷鐒﹀玻鍧楀储閹剧粯鍋℃繝濠傚閻帞鈧娲樼划宀勶綖濠靛浄绱f繝闈涙处濞呮捇姊绘担鍛婃儓缂佸绶氬畷銏ゆ嚃閳哄啰骞撳┑掳鍊曢幊蹇涙偂濞戞埃鍋撻獮鍨姎濡ょ姵鎮傞悰顕€骞囬悧鍫㈠帗閻熸粍绮撳畷婊堝Ω瑜忔稉宥夋煙閹规劦鍤欓柦鍐枛閺屾洘绻涜閸嬫捇鏌涚€n偅宕岄柡浣瑰姍瀹曟帒鈽夊▎鎴濈悼缂傚倸鍊烽懗鑸垫叏閻㈠憡鍤屽Δ锝呭暙閻撴﹢鏌熸潏鎯х槣闁轰礁锕弻锝夋晲閸涱垳浼囬梺浼欑悼閺佽顫忛崫鍔借櫣鎷犻幓鎺旑啇闂備胶绮〃鍛涘Δ鈧悾鐢稿礋椤栨稈鎷虹紓鍌欑劍閿氶柣蹇撳船閳规垿顢欓崫鍕ㄥ亾濠靛鏄ユ繛鎴欏灩缁狅綁鏌eΟ鍏兼毄闁挎稒绮撻弻锝嗘償椤栨粎校闂佺ǹ顑嗙敮鈥崇暦閺囥垹唯闁冲搫鍊婚崢閬嶆煙閸忚偐鏆橀柛銊潐閹便劌顓兼径瀣幐閻庡厜鍋撻柍褜鍓熷畷浼村冀椤撶偟鐣洪梺缁樺灱婵倝宕戠€n喗鐓曟い鎰╁€曢弸鎴︽煕婵犲嫬鍘存慨濠冩そ楠炴垿骞囬鈧幆鐐烘⒑缁嬫鍎嶉柛濠冪箓椤曪絿鎷犲ù瀣潔闂侀潧绻掓慨鐑芥偪閳ь剟姊绘担鍝ユ瀮婵℃ぜ鍔庣划鍫熸媴閸涘﹥娈板┑鐘垫暩婵兘銆傛禒瀣婵犻潧枪娴滃綊鏌涢幇闈涙灍闁稿顑呴埞鎴︽偐閹绘帩浠鹃悗瑙勬礀瀵墎鎹㈠☉銏犵婵炲棗绻掓禒鐓幬旈悩闈涗杭闁搞劎鍎ょ粚杈ㄧ節閸ヮ灛褔鏌涘☉鍗炲箺婵炲牐娉涢—鍐Χ閸℃ḿ鍙嗗銈忓瘜閸ㄥ爼宕洪悙鍝勭闁挎棁妫勯埀顒傚厴閺屻倗鍠婇崡鐐差潻濡炪們鍊愰崑鎾绘⒒閸屾瑧鍔嶉悗绗涘厾楦跨疀濞戞ê鐎悷婊呭鐢亞绱為弽顓犲彄闁搞儯鍔嶇粈鍫㈢棯閹冩倯濞e洤锕、娑樷攽閹邦剚顔勬俊鐐€曠€涒晠骞愮紒妯尖攳濠电姴娲﹂崐椋庘偓鐟板閸犳牠宕滈幍顔剧=濞达綁娼ф慨鈧梺绋款儐閸旀瑩鐛径瀣嚤闁哄鍨甸懓鍨攽閻愬弶顥為柛銊ョ秺閺佸秴鈹戠€n偀鎷虹紓浣割儐鐎笛冿耿閻楀牊鍙忔俊顖溓规慨鈧梺鎰佷簽閺佽顫忕紒妯诲闁告盯娼х紞濠囥€侀弽顓炲耿婵炴垶岣块鍥⒑閻撳寒娼熼柛濠冪墪閻g兘宕f径宀€顔曢梺鐟邦嚟閸嬫盯鎮炶ぐ鎺撶厱閻庯綆鍋呯亸顓㈡煃閽樺妲搁柍璇叉捣閳ь剨缍嗛崜娑氱玻濡ゅ懏鈷掑ù锝堫潐閵囩喖鏌涘Ο铏圭Ш鐎规洘鍔曢埞鎴犫偓锝庝海閹芥洖鈹戦悙鏉戠仧闁搞劌婀辩划缁樼節濮橆厼浠梺鎯х箳閹虫捇宕濈€n喗鐓熼煫鍥ㄦ尵婢э箓鏌熼绛嬫畼闁瑰弶鎸冲畷鐔碱敆閸屻倖袨濠电姷顣槐鏇㈠磻濡厧鍨濇繛鍡楃箳閺嗭附绻涘顔荤盎闁绘帒鐏氶妵鍕箳瀹ュ顎栨繛瀛樼矋缁捇寮婚悢鐓庝紶闁告洦鍘滆娣囧﹪骞嗚濡插妫佹径瀣瘈濠电姴鍊搁顐︽煟椤撶喎娴柡灞糕偓宕囨殕闁逞屽墴瀹曚即寮介鐐电暫濠电姴锕ら崥姗€鎮㈤崗鍏煎劒闂備緡鍋呯粙鎺懳熸繝鍥ㄢ拻闁稿本鐟х粣鏃堟煃瑜滈崜娑㈠磻濞戙垺鍤愭い鏍ㄧ⊕濞呯姵銇勯弬鍨挃缁惧墽鏅埀顒€绠嶉崕閬嶅箯閹存繍鍟呴柕澶涜礋娴滄粓鏌¢崶鏈电敖缂佸鍠楅〃銉╂倷閸欏宕崇紓渚囧枤閺佹悂鍩€椤掑﹦绉甸柛瀣噹閳诲秴鐣濋崟顑芥嫽婵炶揪绲介幉锟犲疮閻愬绠鹃悹鍥囧懐鏆ら悗瑙勬礃缁矂鍩ユ径鎰潊闁绘ɑ褰冩禍鍫曟⒒閸屾瑧璐伴柛鎾寸懅缁棃鎮介崨濠備簵闂佺粯姊婚崢褏绮昏ぐ鎺撶厵缁炬澘宕獮鏍煟韫囥儳鎮肩紒杈ㄥ笚瀵板嫰骞囬鐔兼暘闂傚倸娲らˇ鎵崲濠靛洨绡€闁稿本绋戝▍锝夋⒑閸涘鎴﹀箰閹惰棄钃熼柨婵嗩槸缁犲ジ鏌涢幇鈺佸闁冲嘲顑呴—鍐Χ閸愩劎浠惧銈冨妼閿曘倝鎮鹃悜钘夌闁瑰疇娅曞Λ鍐春閳ь剚銇勯幒宥堝厡妞も晜褰冭灃闁挎繂鎳庨弳鐐烘煕鐎Q冨⒉缂佺粯鐩畷鍗炍旈崘顏嶅敹婵$偑鍊曞ù姘閻愮儤鍎夋い蹇撶墕缁犳氨鎲稿⿰鍫熷亗濠靛倸鎲¢悡娑㈡倶閻愭彃鈷旈柍钘夘樀閹藉爼寮介鐔哄帗閻熸粍绮撳畷婊堟偄妞嬪孩娈惧銈嗙墱閸嬫盯鏌ㄩ妶鍡曠箚闁靛牆鎷戦弨濠氭煛閸滀椒閭慨濠冩そ楠炴劖鎯旈敐鍥╂殼婵$偑鍊х€靛矂宕归搹顐ょ彾闁哄毝棰佹睏闂佸湱鍎ら幐楣冨储娴犲鈷戦柛婵嗗婢跺嫭鎱ㄥΟ绋垮鐎规洘绻傞鍏煎緞鐎e灚顥夐梺璇插嚱缂嶅棝宕板Δ鍛厱闁圭儤顨嗛悡鏇㈡倶閻愭彃鈷旈柟鍐叉噺閵囧嫰鏁傞懖鈺冩殼闂佸搫鐬奸崰鎾诲窗婵犲洤纭€闁绘劖澹嗛惄搴ㄦ⒑閹规劕鍚归柛瀣ㄥ€濋獮鍐ㄎ旈崨顕呮濠电偞鍨堕悷锕傚窗閹邦厾绠鹃柟瀵稿仦鐏忣厾绱掓径濠勭Ш鐎殿喖顭烽幃銏ゆ偂鎼达綆鍞归梻渚€鈧稑宓嗘繛浣冲啠鏋旀い鎾卞灪閳锋垿鏌﹀Ο渚Ц闁哄棛鍠栭弻娑㈡偐瀹曞洤鈷岄悗娈垮枛椤嘲顕i幘顔藉亜闁惧繗顕栭崯搴ㄦ⒒娴h櫣甯涢柛鏃撶畵瀹曟粌顫濋懜闈涗户闂佸搫娲㈤崹娲煕閹寸姷纾奸悗锝庡亽閸庛儵鏌涙惔锛勭濞e洤锕、鏇㈡晲閸モ晝鏉介柣搴㈩問閸犳盯顢氳閸┿儲寰勬繝搴㈠兊濡炪倖鍔х徊鑺ュ垔娴煎瓨鈷掑ù锝呮啞閸熺偤鏌熺粙鎸庮棦闁糕斁鍋撳銈嗗坊閸嬫捇宕¢柆宥嗙厱妞ゆ劧绲跨粻銉︾箾閹炬剚鐓奸柡灞炬礋瀹曠厧鈹戦崶褎鐣婚梻浣虹帛缁嬫帞鍒掗幘璇茶摕闁绘梻鍘х粈鍕煏閸繃顥滄い蹇ユ嫹
核心提示:核心规范 当前最新版本是3.0,是在2002年8月整理发布的,corba核心规范,CCM的3.0规范也已经发布, CORBA规范3.0终于出来了,Java 编程语言有自己的 interface 要害字,它很重要,也许是不能再拖了吧,比较希奇的是3.0规范的编号是2002年6月份的(02-06-33)

核心规范
当前最新版本是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 大学的修辞学教授,在一次演讲中讲述了规则与自由之间的关系,以及二者之间失衡带来的危害。没有自由的规则是专制,而没有规则的自由是混乱。
公司信息系统部门的治理可能会形成过度的规则或过度的自由。规则过度的一个例子是只适用于一个厂商的治理指令,这样您的系统在扩展时,或在与潜在的公司合作伙伴集成时就会有问题。假如自由过多,个人或者开发小组就会根据他们来选择技术,这样,假如这些技术高手碰到他们“生疏的”优先认股权这样的话题时,扩展或集成又会变得很困难。开发人员可能会受业务环境不断变化的影响。
努力实现环境平衡
多种环境因素在决定我们的系统必须遵守的的规则。存在于一个业务环境中的系统应有足够长的寿命,以为公司和客户创造价值。持续为一个组织创造长期价值的系统必须能够应付经常的变化。合并、并购、新的治理和市场力量在改变系统的环境,以及通过使用该系统完成业务过程的用户的需求。变化是一个常数,必须将它添加到评估方程式中。当然,我们无法预知未来,但我们可以分析趋势并努力设计我们的系统,使之能够接受大量潜在的变化或系统扩展,同时对组织产生的影响又可以尽可能小。
为了做出正确的决策和评估,我们需要理解支配着环境的规则,以及我们的应用程序在该环境中应具有的自由。要理解的最重要的规则是,我们的系统处在不断发展的组织中,无论是在公司、政府还是教育组织中,都是业务问题支配技术问题。许多体系结构和平台评估都将主要问题漏掉了。他们通常会将两项或多项技术并排放在一起,然后比较技术特性列表。在完成的时候,大多数参与者会达成一致,因为他们不愿与评估小组中嗓门最大、最强硬、势力最大的派别争吵。显然,这不是作出选择的最有效方法。
确定要害业务问题
将业务问题转换为对组织需要的实际评估意味着应该着重考虑以下问题:
· 组织内的技术力量
· 不抑制程序员的开发环境
· 不对应用程序构成限制的运行时环境
· 运行时环境和开发环境的许可证问题和法律问题(可以说是规则的规则)
· 可找到有经验的开发人员
· 能找到收费合理、有见地的咨询服务公司
· 对组织的客户的影响
· 对厂商或技术合作伙伴的影响
· 组织的文化和策略
· 组织的上级治理联盟
· “大亨们”是否在讨论并购或合并
· 谁是决策者
这些业务问题通常比其他问题(比如采用每个会话一个线程的并发模型还是每个请求一个线程的并发模型)更重要。您可以走进老板的办公室,向他发表足可以充斥一次软件研讨会的技术观点,但是除非您强调了组织的需要,否则您的观点将显得非常空洞。
走近 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 语言”实现。
经过分析和设计阶段的对象将有一些接口,这些接口定义其他组件将如何访问您的服务。现在需要将那些接口转换为一种实现语言。Java 技术同样使这一步很轻易实现。“IDL-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 已经到位并已初始化,并且实现也已经到位,只是尚未创建,此时,需要为实现创建一个完善的生存地点,而这可不像听起来那么轻易,在一个分布式环境中,各个实现要求的环境可能略有不同。可以赋予实现许多特征。实现既可以是单线程的,也可以是多线程的;既可以是具有高度可伸缩性的对象池,也可以是单元素。这许多不同的服务器特征已产生了可移植对象适配器 (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();
客户机
假如您考虑一下正在发生的事件的机制,就会明白客户机和服务器实际上正是互为映像的。客户机将所有的参数打包以创建一个请求,然后以它自己的方式来发送这个请求。服务器只是将请求中的参数解包,执行运算,将返回值和输出参数打包,然后向客户机发回响应。客户机则将返回值和输出参数解包,然后继续处理。这样,客户机打包什么,服务器就解包什么,反之亦然。
这意味着您将会看到客户机和服务器具有相似的结构。客户机还必须创建并初始化一个 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);
看起来眼熟?应该是这样,它看起来与服务器完全一样。现在,客户机已经连接到了一个 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 专门确保让我们不必担心客户机环境和服务器环境之间的差异。客户机对服务器的远程调用是根据远程过程调用 (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 字符串是接口类型,众所周知,它是资源库标识格式。基本上,资源库标识是接口唯一的标识。这个标识可以是 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 的目的就是使客户机能够连接到服务器,以便它能够完成方法调用。客户机必须用 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 调用中将使用的数据类型的正式映射。客户机生成请求时,它不必知道请求要发送到什么地方,或者哪一台服务器将响应该请求。CORBA(作为规范)和 GIOP(作为规范的一部分,定义消息结构和传送)被设计成答应实现一个接口的可能的多种不同服务器之一来响应请求。规范必须定义如何打包操作中的数据,这样所有可能的服务器都可以抽取参数并调用远程操作,并且数据转换不会产生多义性。这种转换问题的典型示例就是指针。客户机中的指针对于在另一台机器上运行另一个进程的服务器意味着什么?毫无意义。或者,变量如何在使用不同寻址方案(大尾数法,小尾数法)的机器间发送?这些数据类型必须转换成服务器能够理解并使用的流。显然,CORBA 规范在公共数据表示方面是十分具体的。这是我们不必涉足的细节层次,但假如您想要了解具体信息,请阅读规范或 Ruh、Herron 和 Klinkeron 合著的 IIOP Complete 一书。
一旦包装了所有数据,就将使用 IOR 中的信息来创建连接。您可以区别 IOR 的结构,通常必须使用 TCP 作为传送机制。但是,也可以使用其它传送(再次提醒,请参阅 CORBA 规范以获取具体信息)。ORB 守护程序负责查找 IOR 指定的对象实现,以及建立客户机和服务器之间的连接。一旦建立了连接,GIOP 将定义一组由客户机用于请求或服务器用于响应的消息。客户机将发送消息类型 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。为了确保互操作性,OMG 必须将 GIOP 定义在所有供给商都支持的特定传输之上。假如有具体和简洁的消息规范,则不会提供互操作性,因为所有供给商使用不同的传送机制来实现这个互操作性。因此,OMG 在最广泛使用的通信传输平台 -- TCP/IP 上标准化 GIOP。GIOP 加 TCP/IP 等于 IIOP!就这么简单。
需要使用已发布对象服务的客户机将使用 IOR 中的值来启动与对象的连接。我们已经绕了一个圈子,又回到了 IOR。IOR 对于 IIOP 是至关重要的,任何要对某个对象调用方法的客户机都要将“请求”消息发送到 IOR 中具体说明的主机和端口地址。在主机上,服务器进程在请求进入时会侦听端口,并将那些消息发送到对象。这就要求服务器主动侦听请求。
生活有阴阳两面,每件事都有缺点,互操作性和 IIOP 也不例外。OMG 推出和运行了 IIOP,对比 ORB 供给商它们自己的服务器上实现此功能,并且没有服务器方可移植性的年代,这是一大改进。但假如要求服务器是位置无关的,我们应该做什么?假如主机和端口值嵌入 IOR 中,每当您将对象从一个服务器移到另一个服务器,以均衡负载时,这个问题就会忽然出现。可喜的是这个问题已经解决了;但又有一条坏消息,每家供给商的解决方法都不同。
结束语
现在,将负载均衡话题留到将来讨论。假如您在几年前有 CORBA“经验”(也就是说在一段时期内),而现在从事另一项研究,我相信您将感到惊喜。CORBA 规范已经获得很大进步,可以确保您为一个 ORB 编写的服务器代码可以移植到运行另一个 ORB 的另一台服务器上。解决方案非常简单,并且以经典的协议为基础。客户机和服务器间的标准交换语法基于某些 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 基本类型
类型 范围 最小大小(以位为单位)
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 用户异常类似于一个结构,在这个结构中,异常可以包含所选类型的任意多错误信息。最终是从方法中使用异常。这里有一个例子:
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)
字符类型的映射有一些困难。首先是所使用的字符集,其次是表示整个字符集所需要的编码位数。不同的语言有不同的字符,它们分别被国际标准化组织映射为不同的字符集。这些字符集代表了某种语言的字母或符号到数字的映射。一种语言中符号的数量决定了这种语言所需要的位宽。现在有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

Tags:corba 核心 规范

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接