ACE+TAO 開源程式設計筆記/建立客戶端
外觀
因此,與伺服器不同,客戶端不需要實現任何由 IDL 生成的程式碼。在客戶端,我們只需例項化工廠的副本(使用在伺服器中生成的 IOR 字串作為地址)並呼叫其函式。對於基本客戶端,這就是全部內容。
在下面的程式碼中,程式的第一個引數用作 TAO 的 orb 的地址引數,以找到我們的伺服器。我們使用之前生成的字串,就像有人使用 IP 地址/埠組合來查詢網際網路上的主機和應用程式一樣。雖然我們會在後面討論,但這個類比有些貼切,因為在網際網路上,我們通常更喜歡使用主機名(使用 DNS)和眾所周知的服務(埠)來訪問我們的服務。在 CORBA 環境中,也是如此,我們將在後面討論。
從 orb 獲取工廠物件後,我們將通用物件向下轉換為由 IDL 生成的 My_Factory_var 物件。請注意,我們不是將其向下轉換為“My_Factory”,而是轉換為“My_Factory_var”。TAO,以及可能還有 CORBA,似乎採用了使用 XXX(如您的 IDL 中定義)作為用於操作 ORB 的類的標準,以及 XXX_var(由 IDL 生成)作為由 XXX 生成的物件的儲存庫。
現在,您已經從接收到的通用 ORB 物件生成了特定於應用程式的工廠物件,您可以像使用任何普通 C++ 物件一樣使用這兩個物件。只需記住,要牢記從查詢返回的資料型別,或者您傳送的資料型別。不用說,如果忽視這些細節會導致記憶體洩漏。
最後,銷燬 ORB。雖然這是一個非常簡單的應用程式,在技術上不需要解構函式,但養成這種習慣仍然是一個好主意,因為讓這些物件懸空會導致分散式程式出現各種問題。
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <iostream>
#include <cstdlib>
#include "ace_serviceI.h"
#include "ace_serviceC.h"
using namespace std;
using namespace CORBA;
int main(int argc, char *argv[])
{
// initialize the ORB
ORB_var orb = ORB_init (argc, argv, "whatever");
// There must be at least two arguments, the first is the factory
// name, the rest are the names of the stock symbols we want to
// get quotes for.
if (argc < 3) {
cerr << "Usage: " << argv[0]
<< " Factory_IOR symbol symbol..." << endl;
return 1;
}
// Bring in the IOR
Object_var factory_object = orb->string_to_object (argv[1]);
// Now downcast the object reference
My_Factory_var factory =
My_Factory::_narrow (factory_object.in ());
// Now get the full name and price of the other arguments:
for (int i = 2; i != argc; ++i) {
// Get the stock object
Widget_var widget =
factory->get_widget (argv[i]);
// Get its name, put it on a _var so it is automatically
// released!
String_var full_name = widget->full_name ();
// Now get the price
Double price = widget->price ();
cout << "The price of a widget in \""
<< full_name.in () << "\" is $"
<< price << endl;
}
// Destroy the ORB
orb->destroy ();
return EXIT_SUCCESS;
}
// Forward declare
interface Widget;
interface My_Factory
{
// = TITLE
// A factory class for the widget interfaces
//
// = DESCRIPTION
// Return the Widget interfaces based on their names
//
Widget get_widget (in string widget_name);
};
interface Widget
{
// = TITLE
// A simple interface to query the name and price of a widget
//
// = DESCRIPTION
// Return the price and name of a single widget
//
readonly attribute string full_name;
// Get the name.
double price ();
// Get the price
};