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

📄 ch06.htm

📁 corba比较入门级的介绍详细间接了corba访问发布各种细节。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<TT> 60: }</TT><TT> 61: </TT><TT> 62: char* BankImpl::address() {</TT><TT> 63: </TT><TT> 64:     return CORBA::strdup(myAddress);</TT><TT> 65: }</TT><TT> 66: </TT><TT> 67: void BankImpl::address(const char* val) {</TT><TT> 68: </TT><TT> 69:     free(myAddress);</TT><TT> 70:     myAddress = strdup(val);</TT><TT> 71: }</TT><TT> 72: </TT><TT> 73: Account_ptr BankImpl::createAccount(Customer_ptr customer,</TT><TT> 74:         const char* accountType, CORBA::Float openingBalance) {</TT><TT> 75: </TT><TT> 76:     Account_ptr newAccount;</TT><TT> 77: </TT><TT> 78:     if (strcmp(accountType, &quot;savings&quot;) == 0) {</TT><TT> 79: </TT><TT> 80:         // Create a new SavingsAccountImpl object for the Account.</TT><TT> 81:         cout &lt;&lt; &quot;BankImpl: Creating new SavingsAccount for &quot;</TT><TT> 82:                 &quot;Customer &quot; &lt;&lt; customer-&gt;name() &lt;&lt; &quot;.&quot; &lt;&lt; endl;</TT><TT> 83:         newAccount = new SavingsAccountImpl(getNextAccountNumber(),</TT><TT> 84:                 getCurrentDate(), openingBalance, customer, 10.0);</TT><TT> 85:     } else if (strcmp(accountType, &quot;checking&quot;) == 0) {</TT><TT> 86: </TT><TT> 87:         // Create a new CheckingAccountImpl object for the Account.</TT><TT> 88:         cout &lt;&lt; &quot;BankImpl: Creating new CheckingAccount for &quot;</TT><TT> 89:                 &quot;Customer &quot; &lt;&lt; customer-&gt;name() &lt;&lt; &quot;.&quot; &lt;&lt; endl;</TT><TT> 90:         newAccount = new CheckingAccountImpl(getNextAccountNumber(),</TT><TT> 91:                 getCurrentDate(), openingBalance, customer);</TT><TT> 92:     } else {</TT><TT> 93: </TT><TT> 94:         // Invalid Account type; do nothing.</TT><TT> 95:         cout &lt;&lt; &quot;BankImpl: Customer &quot; &lt;&lt; customer-&gt;name() &lt;&lt;</TT><TT> 96:                 &quot; requested invalid Account type \&quot;&quot; &lt;&lt; accountType</TT><TT> 97:                 &lt;&lt; &quot;\&quot;.&quot; &lt;&lt; endl;</TT><TT> 98:         return Account::_nil();</TT><TT> 99:     }</TT><TT>100: </TT><TT>101:     // Add the created Account at the end of the list and return it.</TT><TT>102:     ::boa-&gt;obj_is_ready(newAccount);</TT><TT>103:     myAccounts.push_back(Account::_duplicate(newAccount));</TT><TT>104:     return newAccount;</TT><TT>105: }</TT><TT>106: </TT><TT>107: void BankImpl::deleteAccount(Account_ptr account) {</TT><TT>108: </TT><TT>109:     std::vector&lt;Account_ptr&gt;::iterator first = myAccounts.begin();</TT><TT>110:     std::vector&lt;Account_ptr&gt;::iterator last = myAccounts.end();</TT><TT>111:     IsAccountEqual predicate(account);</TT><TT>112: </TT><TT>113:     std::vector&lt;Account_ptr&gt;::iterator matchedAccount = std::</TT><TT>114:             find_if(first, last, predicate);</TT><TT>115:     if (matchedAccount == last) {</TT><TT>116: </TT><TT>117:         // Invalid Account; do nothing.</TT><TT>118:         cout &lt;&lt; &quot;BankImpl: Ignored attempt to delete invalid &quot; &lt;&lt;</TT><TT>119:                 &quot;Account.&quot; &lt;&lt; endl;</TT><TT>120:         return;</TT><TT>121:     }</TT><TT>122:     cout &lt;&lt; &quot;BankImpl: Deleting Account \&quot;&quot; &lt;&lt; account-&gt;</TT><TT>123:             accountNumber() &lt;&lt; &quot;\&quot;.&quot; &lt;&lt; endl;</TT><TT>124: </TT><TT>125:     // Delete the given Account.</TT><TT>126:     myAccounts.erase(matchedAccount);</TT><TT>127:     account-&gt;_release();</TT><TT>128: }</TT><TT>129: </TT><TT>130: AccountList* BankImpl::getAccounts() {</TT><TT>131: </TT><TT>132:     AccountList* list = new AccountList(myAccounts.size());</TT><TT>133:     CORBA::Long i;</TT><TT>134: </TT><TT>135:     for (i = 0; i &lt; myAccounts.size(); i++) {</TT><TT>136:         (*list)[i] = Account::_duplicate(myAccounts[i]);</TT><TT>137:     }</TT><TT>138: </TT><TT>139:     return list;</TT><TT>140: }</TT><TT>141: </TT><TT>142: // Return the next available account number. The result is returned</TT><TT>143: // in a static buffer.</TT><TT>144: char* BankImpl::getNextAccountNumber() {</TT><TT>145: </TT><TT>146:     static char accountNumber[16] = &quot;Account        &quot;;</TT><TT>147: </TT><TT>148:     sprintf(accountNumber + 7, &quot;%08u&quot;, myNextAccountNumber++);</TT><TT>149: </TT><TT>150:     return accountNumber;</TT><TT>151: }</TT><TT>152: </TT><TT>153: // Return the current date in the form &quot;Mmm DD YYYY&quot;. The result is</TT><TT>154: // returned in a static buffer.</TT><TT>155: char* BankImpl::getCurrentDate() {</TT><TT>156: </TT><TT>157:     static char currentDate[12] = &quot;           &quot;;</TT><TT>158: </TT><TT>159:     time_t ltime;</TT><TT>160:     time(&amp;ltime);</TT><TT>161:     char* ctimeResult = ctime(&amp;ltime);</TT><TT>162: </TT><TT>163:     memcpy(currentDate, ctimeResult + 4, 3);</TT><TT>164:     memcpy(currentDate + 4, ctimeResult + 8, 2);</TT><TT>165:     memcpy(currentDate + 7, ctimeResult + 20, 4);</TT><TT>166: </TT><TT>167:     return currentDate;168: }</TT> </FONT></PRE><P>Here are the highlights from <TT>BankImpl.cpp</TT> (refer to Listing 6.7).</P><P>Notice that when a string is returned by a CORBA method, as in the first formof the <TT>name()</TT> method (see lines 51-54), it must be done in the proper manner.When a CORBA method returns a string, it must use the <TT>CORBA::strdup()</TT> method(note that this is not the same as the standard library <TT>strdup()</TT> method)on that string. Using <TT>CORBA::strdup()</TT> allows the application to free thememory used by the string after it has been marshaled back to the caller. The precedingexample demonstrates this for the <TT>name()</TT> accessor method; you will noticethat the <TT>address()</TT> accessor method is similar.</P><P>Also, examine the last few lines of the <TT>createAccount()</TT> method (see lines101-104).</P><P>Notice that when a new <TT>Account</TT> object is created, you must inform theBOA that the object is ready, again using the <TT>obj_is_ready()</TT> method. (Thisis why the <TT>BankImpl</TT> object needs visibility to the BOA.) Note also thatbefore the newly created <TT>Account</TT> object is passed back to the caller, itsreference count is incremented by the <TT>_duplicate()</TT> method. This is importantbecause when an object reference is passed back to a caller (either as a return valueor as an <TT>out</TT> or <TT>inout</TT> parameter), the reference count is decremented.Therefore, when returning a CORBA object reference in this manner, you must always<TT>_duplicate()</TT> the object reference before returning it.</P><P>The remainder of <TT>BankImpl.cpp</TT> will be recognized by C++ programmers orremembered from <TT>BankServerImpl.cpp</TT>. Like <TT>BankServerImpl</TT>, the <TT>BankImpl</TT>must also be accompanied by a bit of extra code to start up the <TT>BankImpl</TT>and make it available to the rest of the network. This code can be seen in Listing6.8.<H4><FONT COLOR="#000077">Listing 6.8. BankMain.cpp.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // BankMain.cpp</TT><TT> 2: </TT><TT> 3: #include &quot;BankImpl.h&quot;</TT><TT> 4: </TT><TT> 5: #include &lt;iostream.h&gt;</TT><TT> 6: </TT><TT> 7: #include &quot;../BankServer_c.h&quot;</TT><TT> 8: </TT><TT> 9: CORBA::BOA_var boa;</TT><TT>10: </TT><TT>11: int main(int argc, char *const *argv) {</TT><TT>12: </TT><TT>13:     // Check the number of arguments; there should be exactly one</TT><TT>14:     // (two counting the executable name itself).</TT><TT>15:     if (argc != 2) {</TT><TT>16:         cout &lt;&lt; &quot;Usage: Bank &lt;bankname&gt;&quot; &lt;&lt; endl;</TT><TT>17:         return 1;</TT><TT>18:     }</TT><TT>19: </TT><TT>20:     // Assign the bank name to the first argument.</TT><TT>21:     const char* bankName = argv[1];</TT><TT>22: </TT><TT>23:     // Initialize the ORB and BOA.</TT><TT>24:     CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);</TT><TT>25:     ::boa = orb-&gt;BOA_init(argc, argv);</TT><TT>26: </TT><TT>27:     // Create a Bank object.</TT><TT>28:     BankImpl bank(bankName);</TT><TT>29: </TT><TT>30:     // Notify the BOA that the BankImpl object is ready.</TT><TT>31:     ::boa-&gt;obj_is_ready(&amp;bank);</TT><TT>32: </TT><TT>33:     // Locate a BankServer object and register with it.</TT><TT>34:     BankServer_var bankServer;</TT><TT>35:     try {</TT><TT>36:         bankServer = BankServer::_bind();</TT><TT>37:     } catch (const CORBA::Exception&amp; ex) {</TT><TT>38: </TT><TT>39:         // The bind attempt failed...</TT><TT>40:         cout &lt;&lt; &quot;BankImpl: Unable to bind to a BankServer.&quot; &lt;&lt; endl;</TT><TT>41:         cout &lt;&lt; ex &lt;&lt; endl;</TT><TT>42:         return 1;</TT><TT>43:     }</TT><TT>44:     try {</TT><TT>45:         bankServer-&gt;registerBank(&amp;bank);</TT><TT>46:     } catch (const CORBA::Exception&amp; ex) {</TT><TT>47: </TT><TT>48:         // The registerBank() attempt failed...</TT><TT>49:         cout &lt;&lt; &quot;BankImpl: Unable to register Bank.&quot; &lt;&lt; endl;</TT><TT>50:         cout &lt;&lt; ex &lt;&lt; endl;</TT><TT>51:         return 1;</TT><TT>52:     }</TT><TT>53: </TT><TT>54:     // Wait for CORBA events.</TT><TT>55:     cout &lt;&lt; &quot;Bank \&quot;&quot; &lt;&lt; bankName &lt;&lt; &quot;\&quot; ready.&quot; &lt;&lt; endl;</TT><TT>56:     ::boa-&gt;impl_is_ready();</TT><TT>57: </TT><TT>58:     // When this point is reached, the application is finished.</TT><TT>59:     return 0;60: }</TT> </FONT></PRE><P>A key difference between <TT>BankServerMain.cpp</TT> and <TT>BankMain.cpp</TT>is that, whereas a <TT>BankServer</TT> doesn't need to locate and connect to otherobjects, a <TT>Bank</TT> needs to locate a <TT>BankServer</TT> and register withit. This is accomplished by the code in lines 33-43.</P><P>The <TT>BankServer::_bind()</TT> call attempts to bind, or connect, to a <TT>BankServer</TT>object. Optionally, <TT>_bind()</TT> can specify a name of an object to connect to,but when the name is omitted, <TT>_bind()</TT> will attempt to connect to any availableobject of the requested type. If the <TT>_bind()</TT> attempt fails, a <TT>CORBA::Exception</TT>is thrown, then caught, and its contents printed to the console.<BLOCKQUOTE>	<P><HR><B>Note:</B>Although the <TT>_bind()</TT> functionality is available in several ORB	products (including IONA Technologies' Orbix and Visigenic's VisiBroker products),	it is not included in the CORBA standard. In any case, the <TT>_bind()</TT> mechanism	is probably unsuitable for large-scale production systems anyway; you'll most likely	want to use the CORBA Naming Service or Trader Service to locate objects on the network.	(See Day 12 for a more in-depth discussion of the CORBAservices.) <HR></BLOCKQUOTE><P>If the application successfully binds to a <TT>BankServer</TT> object, it willregister the <TT>Bank</TT> with it, as in lines 44-52.</P><P>Here, <TT>registerBank()</TT> is the remote method of the <TT>BankServer</TT>interface. As with all remote methods, <TT>registerBank()</TT> can throw a <TT>CORBA::Exception</TT>,and thus this exception should be caught by the application. In this case, the exceptionis caught and an error message printed.</P><P>A <TT>Bank</TT> object is essentially a factory for <TT>Account</TT> objects,and the implementations of the <TT>Account</TT> and its derived interfaces are whatyou will study next.<H3><A NAME="Heading4"></A><FONT COLOR="#000077">Implementing the Account Interface</FONT></H3><P>The <TT>Account</TT> interface defines the capabilities of a generic bank account,such as the withdrawal and deposit of funds. The IDL for the <TT>Account</TT> interfaceis defined as shown in Listing 6.9.<H4><FONT COLOR="#000077">Listing 6.9. Account.idl.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // Account.idl</TT><TT> 2: </TT><TT> 3: // Forward declaration of Account interface.</TT><TT> 4: interface Account;</TT><TT> 5: </TT><TT> 6: #ifndef Account_idl</TT><TT> 7: #define Account_idl</TT><TT> 8: </TT><TT> 9: // sequence of Accounts</TT><TT>10: typedef sequence&lt;Account&gt; AccountList;</TT><TT>11: </TT><TT>12: #include &quot;Customer.idl&quot;</TT><TT>13: </TT><TT>14: // An Account is an entity owned by a Bank and held by a Customer</TT><TT>15: // (or multiple Customers). An Account has a balance which can be</TT><TT>16: // affected by deposits and withdrawals.</TT><TT>17: interface Account {</TT><TT>18: </TT><TT>19:     // This Account's account number.</TT><TT>20:     readonly attribute string accountNumber;</TT><TT>21: </TT><TT>22:     // This Account's creation date.</TT><TT>23:     readonly attribute string creationDate;</TT><TT>24: </TT><TT>25:     // This Account's current balance.</TT><TT>26:     readonly attribute float balance;</TT><TT>27: </TT><TT>28:     // Return a list of Customers who hold this Account.</TT><TT>29:     CustomerList getCustomers();</TT><TT>30: </TT><TT>31:     // Withdraw the given amount from this Account. Returns the new</TT><TT>32:     // account balance.</TT><TT>33:     float withdraw(in float amount);</TT><TT>34: </TT><TT>35:     // Deposit the given amount into this Account. Returns the new</TT><TT>36:     // account balance.</TT><TT>37:     float deposit(in float amount);</TT><TT>38: };</TT><TT>39: 40: #endif</TT> </FONT></PRE><P>Thus, you'll need to provide implementations for the following methods: <TT>accountNumber()</TT>,<TT>creationDate()</TT>, and <TT>balance()</TT>, which are accessors for the <TT>accountNumber</TT>,<TT>creationDate</TT>, and <TT>balance</TT> attributes, respectively, as well as<TT>getCustomers()</TT>, <TT>withdraw()</TT>, and <TT>deposit()</TT>, along withthe constructor (or constructors) and destructor for this class. The header filefor the implementation (<TT>AccountImpl.h</TT>) appears in Listing 6.10, followedby the implementation itself (<TT>AccountImpl.cpp</TT>) in Listing 6.11.<H4><FONT COLOR="#000077">Listing 6.10. AccountImpl.h.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT> 1: // AccountImpl.h</TT><TT> 2: </TT><TT> 3: #ifndef AccountImpl_h</TT><TT> 4: #define AccountImpl_h</TT><TT> 5: </TT><TT> 6: #include &quot;../Account_s.h&quot;</TT><TT> 7: </TT><TT> 8: class AccountImpl : public _sk_Account {</TT><TT> 9: </TT><TT>10: // Allow CheckingAccountImpl and SavingsAccountImpl access to the</TT><TT>11: // protected constructor.</TT>

⌨️ 快捷键说明

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