⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch06.htm

📁 corba比较入门级的介绍详细间接了corba访问发布各种细节。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<TT>61:     BankList* list = new BankList(myBanks.size());</TT><TT>62:     CORBA::Long i;</TT><TT>63: </TT><TT>64:     for (i = 0; i &lt; myBanks.size(); i++) {</TT><TT>65:         (*list)[i] = Bank::_duplicate(myBanks[i]);</TT><TT>66:     }</TT><TT>67: </TT><TT>68:     return list;69: }</TT> </FONT></PRE><P>Of particular interest in this class are the following highlights:</P><P><TT>BankServerImpl.cpp</TT> makes use of STL-provided algorithms and functions,as evidenced by the <TT>#include</TT> directives in lines 5 and 6.</P><P>The <TT>IsBankEqual</TT> class, occupying lines 8 through 16, is an encapsulationof a function that compares two <TT>Bank</TT> references for equality (that is, theyboth refer to the same <TT>Bank</TT> object). The equality test is performed throughthe <TT>_is_equivalent()</TT> method, which returns a <TT>TRUE</TT> (nonzero) resultif its object and the argument object indeed refer to the same object.<BLOCKQUOTE>	<P><HR><B>Note:</B>According to the CORBA specification, <TT>_is_equivalent()</TT> might	actually return <TT>FALSE</TT> even if two object references are equivalent. The	only guarantee made by the CORBA specification is that if <TT>_is_ equivalent()</TT>	returns <TT>TRUE</TT>, then the object references are equivalent; otherwise, they	may or may not be equivalent. (See the CORBA specification document for more information.)	<HR></BLOCKQUOTE><P>The <TT>registerBank()</TT> method (lines 28-34) simply adds the given <TT>Bank</TT>to the <TT>BankServerImpl</TT>'s internal list of <TT>Bank</TT>s (in the <TT>myBanks</TT>member). Note the use of the <TT>Bank</TT> class's <TT>_duplicate()</TT> method,which increments the <I>reference count</I> of the given <TT>Bank</TT> object byone. This indicates to the <TT>Bank</TT> object that the <TT>BankServerImpl</TT>intends to retain a reference to that object. The reference count for an object,in turn, simply maintains a count of outstanding references to that object. (You'llsee later how the <TT>BankServerImpl</TT> releases its reference to the <TT>Bank</TT>object.)</P><P>Now you'll examine the <TT>unregisterBank()</TT> method in several parts.</P><P>The first part of <TT>unregisterBank()</TT>, in lines 36-52, iterates throughthe <TT>BankServerImpl</TT>'s internal list of <TT>Bank</TT>s (again, stored in the<TT>myBanks</TT> member). The <TT>isBankEqual</TT> class discussed earlier is usedto determine equality of <TT>Bank</TT> references; in this example, the <TT>std::find_if()</TT>method uses an <TT>isBankEqual</TT> object to compare object references. This stepis necessary so that when a <TT>Bank</TT> is unregistered, the <TT>BankServerImpl</TT>can remove it from its internal list of <TT>Bank</TT>s.</P><P>In the last part of <TT>unregisterBank()</TT>, lines 54-56, the given <TT>Bank</TT>is first removed from <TT>myBanks</TT>, via the <TT>erase()</TT> method. Then <TT>BankServerImpl</TT>indicates to the <TT>Bank</TT> that it is no longer keeping a reference to that <TT>Bank</TT>by calling the <TT>_release()</TT> method. <TT>_release()</TT> is the counterpartto the <TT>_duplicate()</TT> method mentioned previously; <TT>_release()</TT> decrementsthe reference count of an object. When that object's reference count reaches zero,the object can be (but not necessarily) destroyed. Because the <TT>BankServerImpl</TT>increments a <TT>Bank</TT>'s reference count when it registers and decrements the<TT>Bank</TT>'s reference count when it unregisters, the net change of the <TT>Bank</TT>'sreference count after it has registered and later unregistered is zero.</P><P>On its own, the <TT>BankServerImpl</TT> class doesn't do anything useful. To realizeits capability, you must provide code that creates a <TT>BankServerImpl</TT> andmakes it available to other objects on the network. This is done in <TT>BankServerMain.cpp</TT>,which appears in Listing 6.4.<H4><FONT COLOR="#000077">Listing 6.4. BankServerMain.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankServerMain.cpp</TT><TT> 2: </TT><TT> 3: #include &quot;BankServerImpl.h&quot;</TT><TT> 4: #include &lt;iostream.h&gt;</TT><TT> 5: </TT><TT> 6: int main(int argc, char *const *argv) {</TT><TT> 7: </TT><TT> 8:     // Initialize the ORB and BOA.</TT><TT> 9:     CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);</TT><TT>10:     CORBA::BOA_var boa = orb-&gt;BOA_init(argc, argv);</TT><TT>11: </TT><TT>12:     // Create a BankServerImpl object.</TT><TT>13:     BankServerImpl bankServer;</TT><TT>14: </TT><TT>15:     // Notify the BOA that the BankServerImpl object is ready.</TT><TT>16:     boa-&gt;obj_is_ready(&amp;bankServer);</TT><TT>17: </TT><TT>18:     // Wait for CORBA events.</TT><TT>19:     cout &lt;&lt; &quot;BankServer ready.&quot; &lt;&lt; endl;</TT><TT>20:     boa-&gt;impl_is_ready();</TT><TT>21: </TT><TT>22:     // When this point is reached, the application is finished.</TT><TT>23:     return 0;24: }</TT> </FONT></PRE><P>The first thing a CORBA application must do is initialize its environment, thatis, its Object Request Broker (ORB) and Basic Object Adapter (BOA). This is accomplishedthrough the <TT>ORB_init()</TT> and <TT>BOA_init()</TT> methods in lines 8-10.</P><P>After the ORB and BOA are initialized, other CORBA objects can be created andmade available to the network. This is done on a per-object basis using the <TT>obj_is_ready()</TT>method (in lines 15-16).</P><P>The preceding code notifies the BOA that the <TT>BankServerImpl</TT> object isready to be used by other objects on the network. The BOA also provides the <TT>impl_is_ready()</TT>method, which you see used in lines 18-20.</P><P>The <TT>impl_is_ready()</TT> method notifies the BOA that the application is readyto receive events. Typically, <TT>impl_is_ready()</TT> will wait for events for animplementation-dependent period of time; usually, this is configurable by the applicationdeveloper. For instance, <TT>impl_is_ready()</TT> can process events until the applicationis interrupted, or it can terminate the application after a predetermined amountof time has elapsed--an hour, for instance--without any events being received.</P><P>Now that the <TT>BankServer</TT> interface has been implemented, you can turnyour attention to the interface that interacts with the <TT>BankServer</TT>: the<TT>Bank</TT> interface.<H3><A NAME="Heading3"></A><FONT COLOR="#000077">Implementing the Bank Interface</FONT></H3><P>The <TT>Bank</TT> interface, as you recall from Day 5, describes the servicesprovided by a <TT>Bank</TT>--generally, the manipulation of <TT>Account</TT>s withinthat <TT>Bank</TT>. The IDL for the <TT>Bank</TT> interface is defined as shown inListing 6.5.<H4><FONT COLOR="#000077">Listing 6.5. Bank.idl.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // Bank.idl</TT><TT> 2: </TT><TT> 3: // Forward declaration of Bank interface.</TT><TT> 4: interface Bank;</TT><TT> 5: </TT><TT> 6: #ifndef Bank_idl</TT><TT> 7: #define Bank_idl</TT><TT> 8: </TT><TT> 9: // sequence of Banks</TT><TT>10: typedef sequence&lt;Bank&gt; BankList;</TT><TT>11: </TT><TT>12: #include &quot;Customer.idl&quot;</TT><TT>13: #include &quot;Account.idl&quot;</TT><TT>14: </TT><TT>15: // A Bank provides access to Accounts. It can create an Account</TT><TT>16: // on behalf of a Customer, delete an Account, or list the current</TT><TT>17: // Accounts with the Bank.</TT><TT>18: interface Bank {</TT><TT>19: </TT><TT>20:     // This Bank's name.</TT><TT>21:     attribute string name;</TT><TT>22: </TT><TT>23:     // This Bank's address.</TT><TT>24:     attribute string address;</TT><TT>25: </TT><TT>26:     // Create an Account on behalf of the given Customer, with the</TT><TT>27:     // given account type (&quot;savings&quot; or &quot;checking&quot;, where case is</TT><TT>28:     // significant), and the given opening balance.</TT><TT>29:     Account createAccount(in Customer customer, in string</TT><TT>30:             accountType, in float openingBalance);</TT><TT>31: </TT><TT>32:     // Delete the given Account. If the Account is not with this</TT><TT>33:     // Bank, this operation does nothing.</TT><TT>34:     void deleteAccount(in Account account);</TT><TT>35: </TT><TT>36:     // List all Accounts with this Bank.</TT><TT>37:     AccountList getAccounts();</TT><TT>38: };</TT><TT>39:40: #endif</TT> </FONT></PRE><P>Here, you'll need to provide implementations for <TT>name()</TT> and <TT>address()</TT>--whichhave both accessor and mutator forms for the <TT>name</TT> and <TT>address</TT> attributes--alongwith <TT>createAccount()</TT>, <TT>deleteAccount()</TT>, and <TT>getAccounts()</TT>,as well as the constructor (or constructors) and destructor for this class.</P><P>After looking at <TT>BankServerImpl.h</TT> (back in Listing 6.2), nothing in <TT>BankImpl.h</TT>should be too surprising (see Listing 6.6). Again, the mapping of IDL methods toC++ methods is straightforward (although you'll notice the use of the <TT>CORBA::Float</TT>type that the IDL <TT>float</TT> type mapped to), and the <TT>BankImpl</TT> makesuse of STL in much the same way as <TT>BankServerImpl</TT>.<H4><FONT COLOR="#000077">Listing 6.6. BankImpl.h.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankImpl.h</TT><TT> 2: </TT><TT> 3: #ifndef BankImpl_h</TT><TT> 4: #define BankImpl_h</TT><TT> 5: </TT><TT> 6: #include &lt;vector&gt;</TT><TT> 7: </TT><TT> 8: #include &quot;../Bank_s.h&quot;</TT><TT> 9: </TT><TT>10: class BankImpl : public _sk_Bank {</TT><TT>11: </TT><TT>12: public:</TT><TT>13: </TT><TT>14:     // Constructor.</TT><TT>15:     //</TT><TT>16:     // name - This Bank's name.</TT><TT>17:     BankImpl(const char* name);</TT><TT>18: </TT><TT>19:     // Destructor.</TT><TT>20:     ~BankImpl();</TT><TT>21: </TT><TT>22:     // These methods are described in Bank.idl.</TT><TT>23:     virtual char* name();</TT><TT>24:     virtual void name(const char* val);</TT><TT>25:     virtual char* address();</TT><TT>26:     virtual void address(const char* val);</TT><TT>27:     virtual Account_ptr createAccount(Customer_ptr customer,</TT><TT>28:             const char* accountType, CORBA::Float openingBalance);</TT><TT>29:     virtual void deleteAccount(Account_ptr account);</TT><TT>30:     virtual AccountList* getAccounts();</TT><TT>31: </TT><TT>32: protected:</TT><TT>33: </TT><TT>34:     // Return the next available account number. The result is</TT><TT>35:     // returned in a static buffer.</TT><TT>36:     char* getNextAccountNumber();</TT><TT>37: </TT><TT>38:     // Return the current date in the form &quot;Mmm DD YYYY&quot;. The result</TT><TT>39:     // is returned in a static buffer.</TT><TT>40:     char* getCurrentDate();</TT><TT>41: </TT><TT>42: private:</TT><TT>43: </TT><TT>44:     // Default constructor.</TT><TT>45:     BankImpl();</TT><TT>46: </TT><TT>47:     // This Bank's name.</TT><TT>48:     char* myName;</TT><TT>49: </TT><TT>50:     // This Bank's address.</TT><TT>51:     char* myAddress;</TT><TT>52: </TT><TT>53:     // This Bank's Accounts.</TT><TT>54:     std::vector&lt;Account_ptr&gt; myAccounts;</TT><TT>55: </TT><TT>56:     // The next available account number.</TT><TT>57:     unsigned int myNextAccountNumber;</TT><TT>58: };</TT><TT>59: 60: #endif</TT> </FONT></PRE><P>You haven't seen it yet, but <TT>BankMain.cpp</TT> defines a global variable called<TT>boa</TT> (see line 14 of Listing 6.7), which is a reference to the Basic ObjectAdapter used by the application. Although the simplicity of a global <TT>boa</TT>variable makes it appropriate for a sample application, in a production applicationyou want a cleaner mechanism for sharing the reference to the BOA. For example, youcan provide a class that makes the BOA available through a static member, or youcan write class constructors to take a BOA as an argument. Regardless of how youaccomplish this, there will sometimes be a need for various objects in an applicationto access the BOA. (In this example, a <TT>BankImpl</TT> needs to call <TT>obj_is_ready()</TT>on <TT>Account</TT> objects that it creates.)<H4><FONT COLOR="#000077">Listing 6.7. BankImpl.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>  1: // BankImpl.cpp</TT><TT>  2: </TT><TT>  3: #include &quot;BankImpl.h&quot;</TT><TT>  4: </TT><TT>  5: #include &lt;time.h&gt;</TT><TT>  6: #include &lt;string.h&gt;</TT><TT>  7: #include &lt;iostream.h&gt;</TT><TT>  8: #include &lt;algorithm&gt;</TT><TT>  9: #include &lt;functional&gt;</TT><TT> 10: </TT><TT> 11: #include &quot;SavingsAccountImpl.h&quot;</TT><TT> 12: #include &quot;CheckingAccountImpl.h&quot;</TT><TT> 13: </TT><TT> 14: extern CORBA::BOA_var boa;</TT><TT> 15: </TT><TT> 16: // STL-derived unary function which returns TRUE if Accounts are</TT><TT> 17: // equal.</TT><TT> 18: class IsAccountEqual : public std::unary_function&lt;Account_ptr,</TT><TT> 19:         bool&gt; {</TT><TT> 20: public:</TT><TT> 21:     IsAccountEqual(argument_type account) { myAccount = account; }</TT><TT> 22:     result_type operator()(argument_type account) { return account-&gt;</TT><TT> 23:             _is_equivalent(myAccount) != 0; }</TT><TT> 24: private:</TT><TT> 25:     argument_type myAccount;</TT><TT> 26: };</TT><TT> 27: </TT><TT> 28: // Constructor.</TT><TT> 29: //</TT><TT> 30: // name - This Bank's name.</TT><TT> 31: BankImpl::BankImpl(const char* name) : myAccounts(),</TT><TT> 32:         myName(strdup(name)), myAddress(strdup(&quot;123 Elm Street, &quot;</TT><TT> 33:         &quot;Anyware USA 12345&quot;)), myNextAccountNumber(0) {</TT><TT> 34: </TT><TT> 35: }</TT><TT> 36: </TT><TT> 37: // Default constructor.</TT><TT> 38: BankImpl::BankImpl() : myAccounts(), myName(NULL), myAddress(NULL),</TT><TT> 39:         myNextAccountNumber(0) {</TT><TT> 40: </TT><TT> 41: }</TT><TT> 42: </TT><TT> 43: // Destructor.</TT><TT> 44: BankImpl::~BankImpl() {</TT><TT> 45: </TT><TT> 46:     cout &lt;&lt; &quot;Bank \&quot;&quot; &lt;&lt; name() &lt;&lt; &quot;\&quot; being destroyed.&quot; &lt;&lt; endl;</TT><TT> 47:     free(myName);</TT><TT> 48:     free(myAddress);</TT><TT> 49: }</TT><TT> 50: </TT><TT> 51: char* BankImpl::name() {</TT><TT> 52: </TT><TT> 53:     return CORBA::strdup(myName);</TT><TT> 54: }</TT><TT> 55: </TT><TT> 56: void BankImpl::name(const char* val) {</TT><TT> 57: </TT><TT> 58:     free(myName);</TT><TT> 59:     myName = strdup(val);</TT>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -