Đề tài Ánh xạ từ IDL sang C++

Tài liệu Đề tài Ánh xạ từ IDL sang C++: Lời nói đầu Ngày nay cùng với việc phát triển của mạng máy tính việc viết một ứng dụng trên một máy đơn cục bộ không còn được ưa chuộng và thích hợp nữa . Các chương trình và ứng dụng hiện đại phải tích hợp và triệu gọi lẫn nhau trên mạng Intranet (mạng cục bộ), mạng Internet (mạng toàn cầu). Tuy nhiên một vấn đề nảy sinh ra , điểm bất đồng giữa các ngôn ngữ lập trình . Các đối tượng thiết kế bằng ngôn ngữ nào thì sau khi biên dịch ra dạng nhị phân (binary) chỉ có mã lệnh tương ứng với ngôn ngữ đó mới có khả năng truy xuất được đối tượng . Đối tượng C++ không dễ gì truy xuất được từ mã lệnh Delphi hay Visual Basic một cách tự nhiên . (Mặc dù có một số kĩ thuật như sử dụng thư viện liên kết động DLL nhưng đó không phải là các giải pháp toàn diện ). Các nhà lập trình luôn mong muốn tìm được một tiếng nói chung cho tất cả các ngôn ngữ lập trình hiện có . Và thế là CORBA ra đời . CORBA ( Common Object Request Broker Achitecture) - tạm dịch là Kiến trúc môi giới gọi các đối tượng thông...

doc37 trang | Chia sẻ: hunglv | Lượt xem: 1500 | Lượt tải: 0download
Bạn đang xem trước 20 trang mẫu tài liệu Đề tài Ánh xạ từ IDL sang C++, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Lêi nãi ®Çu Ngµy nay cïng víi viÖc ph¸t triÓn cña m¹ng m¸y tÝnh viÖc viÕt mét øng dông trªn mét m¸y ®¬n côc bé kh«ng cßn ®­îc ­a chuéng vµ thÝch hîp n÷a . C¸c ch­¬ng tr×nh vµ øng dông hiÖn ®¹i ph¶i tÝch hîp vµ triÖu gäi lÉn nhau trªn m¹ng Intranet (m¹ng côc bé), m¹ng Internet (m¹ng toµn cÇu). Tuy nhiªn mét vÊn ®Ò n¶y sinh ra , ®iÓm bÊt ®ång gi÷a c¸c ng«n ng÷ lËp tr×nh . C¸c ®èi t­îng thiÕt kÕ b»ng ng«n ng÷ nµo th× sau khi biªn dÞch ra d¹ng nhÞ ph©n (binary) chØ cã m· lÖnh t­¬ng øng víi ng«n ng÷ ®ã míi cã kh¶ n¨ng truy xuÊt ®­îc ®èi t­îng . §èi t­îng C++ kh«ng dÔ g× truy xuÊt ®­îc tõ m· lÖnh Delphi hay Visual Basic mét c¸ch tù nhiªn . (MÆc dï cã mét sè kÜ thuËt nh­ sö dông th­ viÖn liªn kÕt ®éng DLL nh­ng ®ã kh«ng ph¶i lµ c¸c gi¶i ph¸p toµn diÖn ). C¸c nhµ lËp tr×nh lu«n mong muèn t×m ®­îc mét tiÕng nãi chung cho tÊt c¶ c¸c ng«n ng÷ lËp tr×nh hiÖn cã . Vµ thÕ lµ CORBA ra ®êi . CORBA ( Common Object Request Broker Achitecture) - t¹m dÞch lµ KiÕn tróc m«i giíi gäi c¸c ®èi t­îng th«ng dông . CORBA ®­îc h×nh thµnh tõ mét tæ chøc nghiªn cøu quèc tÕ OMG (Object Management Group ) víi sù hîp t¸c cña h¬n 800 c«ng ty . Tham väng cña OMG lµ ®­a ra c¸ch ®Ó c¸c ®èi t­îng viÕt b»ng nh÷ng ng«n ng÷ kh¸c nhau cã thÓ triÖu gäi lÉn nhau theo m« h×nh ®èi t­îng ph©n t¸n . CORBA kh«ng ph¶i lµ ng«n ng÷ lËp tr×nh nh­ C++ hay Java . CORBA lµ mét ng«n ng÷ ®Æc t¶ (description language) . Sau ®©y sÏ tr×nh bµy qu¸ tr×nh ¸nh x¹ (mapping) tõ ng«n ng÷ ®Æc t¶ sang ng«n ng÷ cµi ®Æt I. ¸nh x¹ tõ IDL sang C++ Giíi thiÖu: ¸nh x¹ IDL sang C++ ph¶i tho· m·n c¸c yªu cÇu sau : - ¸nh x¹ ph¶i cã tÝnh trùc quan vµ dÔ sö dông ph¶i b¶o tån ng«n ng÷ chung cña C++ vµ ph¶i gÇn gièng víi C++ th­êng ph¶i an toµn vÒ kiÓu sö dông cã hiÖu qu¶ chu kú cña CPU vµ bé nhí thùc hiÖn trªn c¸c cÊu tróc cña bé nhí ®o¹n vµ bé nhí vËt lý ph¶i ®­îc h­íng néi sao cho nã cã thÓ dïng trong m«i tr­êng ph©n luång ¸nh x¹ ph¶i b¶o toµn tÝnh che giÊu côc bé (tÝnh trong suèt) ViÖc ¸nh x¹ sang C++ phøc t¹p vµ réng lín nh­ng kh«ng ph¶i qu¸ khã. Thø nhÊt, ¸nh x¹ lµ thuËn tiÖn vÝ dô b¹n hiÓu râ vÒ c¸ch tæ chøc vµ qu¶n lý bé nhí cña kiÓu String, vµ c¸c luËt qu¶n lý ®èi víi kiÓu d÷ liÖu Variable-length, thø hai, viÖc ¸nh x¹ lµ an toµn, kh«ng yªu cÇu s¾c th¸i vµ b¾t lçi dÔ dµng trong lóc biªn dÞch Thø 3, sù ¸nh x¹ nµy lµ dÔ nhí mÆc dï líp cã nhiÒu hµm thµnh viªn, nh­ng b¹n chØ cÇn gäi mét sè hµm chÝnh, cßn mét sè hµm kh¸c tån t¹i mÆc ®Þnh ®Ó cung cÊp c¸c chuyÓn ®æi tham sè truyÒn vµ kh«ng cÇn ph¶i gäi râ rµng 2. ¸nh x¹ cho tªn: Các tên của IDL được bảo toàn khi ánh xạ sang C++. Để minh hoạ cho điều này ta xét ví dụ sau: Trong IDL: enum color {red, green, blue}; Khi ánh xạ sang C++: enum color {red, green, blue}; Các ánh xạ sang C++ cũng bảo toàn các toán tử phạm vi. Ví dụ nếu như trong IDL toán tử phạm vi Outer :: Inner là hợp lệ thì khi ánh xạ sang C++ nó cũng vẫn là Outer :: Inner. Một vấn đề phát sinh khi trong IDL ta dùng tên trùng với từ khoá trùng với các từ khoá của C++: Ví dụ định nghĩa sau là hoàn toàn hợp lệ trong IDL: Enum class {if, this, while, case }; nhưng khi ánh xạ sang C++ thì nó sẽ tự động được thêm vào tiền tố: _cxx_. Vì vậy nó sẽ có dạng như sau: enum _cxx_class { _cxx_if, _cxx_this, _cxx_while, _cxx_case }; các tiền tố này làm cho các câu lệnh trở nên khó đọc, do vậy tốt nhất là ta nên tránh dùng chúng. Bây giờ chúng ta sẽ đi xét chi tiết vào từng kiểu dữ liệu một 3. Ánh xạ các kiểu dữ liệu cơ bản Các kiểu dữ liệu cơ bản được ánh xạ sang C++ được mô tả ở bảng sau: OMG IDL C++ C++ Out Type short CORBA::Short CORBA::Short_out long CORBA::Long CORBA::Long_out unsigned short CORBA::UShort CORBA::UShort_out unsigned long CORBA::ULong CORBA::ULong_out float CORBA::Float CORBA::Float_out double CORBA::Double CORBA::Double_out char CORBA::Char CORBA::Char_out boolean CORBA::Boolean CORBA::Boolean_out octet CORBA::Octet CORBA::Octet_out 4. Các kiểu dữ liệu phức: Các kiểu dữ liệu phức ở trong IDL được ánh xạ sang C++ như sau: OMG IDL C++ Object CORBA::Object_ptr struct C++ struct union C++ class enum C++ enum string char * Sequence C++ class array C++ array a>. String Một chuỗi trong IDL được ánh xạ sang C++ là char *. Cả chuỗi giới hạn và chuỗi không giới hạn độ dài thì đều được ánh xạ sang C++ là char *. Các chuỗi CORBA trong C++ được kết thúc bởi con trỏ NULL. Nếu một chuỗi mà có chứa một kiểu tự định nghĩa khác, ví dụ như kiểu struct, thì nó được ánh xạ sang kiểu C ORBA::String_v ar. Điều này đảm bảo rằng mỗi thành phần trong struct được quản lý bởi chính bộ nhớ của nó. Các chuỗi phải được cấp phát và ngừng cấp phát bằng việc sử dụng các hàm thành phần sau trong lớp CORBA: string_alloc // hàm cấp phát string_dup string_free // hàm huỷ Chú ý: hàm string_alloc cấp phát vùng nhớ có độ dài len+1 vì nó còn chứa một ký tự null b>.Enum Các kiểu enum trong IDL được ánh xạ sang một kiểu enum trong C++ // IDL module INVENT { enum Reply {ACCEPT, REFUSE}; } // C++ class INVENT { . . . enum Reply {ACCEPT, REFUSE}; }; Tham chiếu đến các thành phần như sau là hợp lệ: INVENT::Reply accept_reply; accept_reply = INVENT::ACCEPT; c> .Struct Các kiểu struct trong IDL được ánh xạ sang các kiểu struct trong C++. Chúng ta cùng xem xét các cấu trúc có chiều dài cố định với các cấu trúc có chiều dài thay đổi: // IDL module INVENT { // Chiều dài cố định struct Date { long year; long month; long day; }; // Chiều dài thay đổi struct Address { string aptNum; string streetName; string city; string state; string zipCode; }; }; // C++ class INVENT { struct Date { CORBA::Long year; CORBA::Long month; CORBA::Long day; }; struct Address { CORBA::String_var aptNum; CORBA::String_var streetName; CORBA::String_var city; CORBA::String_var state; CORBA::String_var zipCode; Address &operator=(const Address &_obj); }; }; Đối với các kiểu dữ liệu cơ bản trong các thành phần của struct được ánh xạ sang các kiểu tương ứng trong C++. Còn các kiểu dữ liệu như: tham chiếu đối tượng, các tham chiếu giả đối tượng, các chuối thì được ánh xạ các lớp _var tương ứng: CORBA::string_var CORBA::object_var Union Một kiểu Union trong IDL được ánh xạ sang một lớp trong C++. Lớp này chứa: Các hàm tạo lập (Constructors) Các hàm huỷ (Destructors) Các toán tử gán Các thay đổi cho các giá trị của union Các bộ truy nhập cho các giá trị của union. Ví dụ: // IDL union OrderItem switch (long) { case 1: itemStruct itemInfo; case 2: orderStruct orderInfo; default: ID idInfo; }; // C++ class OrderItem { public: OrderItem(); OrderItem(const OrderItem &); ~OrderItem(); OrderItem &operator=(const OrderItem&); void _d (CORBA::Long); CORBA::Long _d () const; void itemInfo (const itemStruct &); const itemStruct & itemInfo () const; itemStruct & itemInfo (); void orderInfo (const orderStruct &); const orderStruct & orderInfo () const; orderStruct & orderInfo (); void idInfo (ID); ID idInfo () const; . . . }; Các định nghĩa kiểu Các định nghĩa kiểu trong IDL được ánh xạ trực tiếp sang các định nghĩa kiểu của C++. Nếu định nghĩa kiểu IDL gốc được ánh xạ sang một vài kiểu của C++ thì trình biên dịch của IDL sẽ sinh ra các bí danh tương ứng cho mỗi kiểu trong C++. // IDL typedef octet example_octet; typedef enum enum_values {           first,           second,           third } enum_example; // Kết quả trong C++ typedef octet example_octet; enum enum_values {           first,           second,           third }; typedef enum_values enum_example; // bí danh được tạo ra Modules Một module của IDL nên được ánh xạ sang một namespace của C++ với tên tương tự // IDL module ABC {           // Definitions           ... }; ... // Kết quả trong C++ class ABC {           // Definitions           ... }; Sequences Các sequences của IDL cả giưói hạn hay không giới hạn đều được ánh xạ sang class của C++. Chú ý: Khi chiều dài của sequence không giới hạn vượt quá chiều dài cực đại thì C++ sẽ cấp phát trong suốt một buffer lớn hơn, nó sẽ copy buffer cũ vào buffer mới và giải phong bộ nhớ khỏi buffer cũ. Tuy nhiên, nó sẽ không thực hiện giải phóng bất kỳ bộ nhớ nào chưa bao giờ được dùng đến nếu chiều dài cực đại giảm. Xét ví dụ sau: ánh xạ một sequence không giới hạn (unbounded)của IDL sang C++ // IDL typedef sequence LongSeq; ... // Results in the generation of this C++ code class LongSeq { public: LongSeq(CORBA::ULong max=0); LongSeq(CORBA::ULong max=0, CORBA::ULong length,                               CORBA::Long *data, CORBA::Boolean release = 0); LongSeq(const LongSeq&); ~LongSeq(); LongSeq&                  operator=(const LongSeq&); CORBA::ULong              maximum() const; void                      length(CORBA::ULong len); CORBA::ULong              length() const; const CORBA::ULong&       operator[](CORBA::ULong index) const; ... static LongSeq            *_duplicate(LongSeq* ptr); static void               _release(LongSeq *ptr); static CORBA::Long        *allocbuf(CORBA::ULong nelems); static void               freebuf(CORBA::Long *data); private: CORBA::Long         *_contents; CORBA::ULong        _count; CORBA::ULong        _num_allocated: CORBA::Boolean      _release_flag; CORBA::Long         _ref_count; }; Ý nghĩa của các hàm được môt tả ở bảng sau: Phương thức Mô tả LongSeq(CORBA::ULong max=0) bộ tạo lập cho một sequence không giới hạn chiếm một chiều dài cực đại như một tham số. Các sequence giới hạn thì có một chiều dài cực đại xác định. LongSeq(CORBA::ULong max=0,     CORBA::ULong length,     CORBA::Long *data,    CORBA::Boolean release=0) Constructor này cho phép bạn đặt một chiều dài cực đại, chiều dài hiện tại, một con trỏ tới bộ đệm dữ liệu kết hợp và một cờ giải phóng.Nếu cờ giải phóng khác 0, ISB về C++ sẽ giải bộ nhớ kết hợp với bộ đẹm dữ liệu khi tăng kích thước của sequence. Nếu cờ giải phóng bằng 0 thì bộ nhớ của bộ dệm dữ liệu cũ không được giải phóng. Sequence giới hạn có tất cả các thông số này trừ max. LongSeq(const LongSeq&) Bộ tạo lập sao chép thực hiện sao chép sâu đối tượng nguồn. ~LongSeq(); Destructor giải phóng tất cả bộ nhớ của chính sequence nếu cờ giải phóng (release flag) có giá trị khác không khi được tạo lập. Operator=(const LongSeq&j) Toán tử gán thực hiện một sự ao chép sâu, giải phóng việc lưu trữ cũ nếu cần thiết.. Maximum() Trả lại kích thước của sequence. length() Hai phương thức được định nghĩa cho việc đặt và trả lại chiều dài của sequence. Operator[]() Hai toán tử chỉ mục được cung cấp cho việc truy nhập một phần tử trong sequence. Một toán tử cho phép phần tử được thay đổi còn một toán tử chỉ cho phép truy nhập đọc phần tử. _release() Giải phóng sequence. Nếu cờ giải phóng của bộ tạo lập là khác 0 khi đối tượng được khởi tạo và kiểu phần tử của sequence là một chuỗi hoặc tham chiếu đối tượng thì mỗi phần tử sẽ được giải phóng trước khi buffer được giải phóng. allocbuf() freebuf() Bạn nên dùng hai phương thức tĩnh này để cấp phát hay huỷ bất kỳ bộ nhớ nào sử dụng bởi một sequence Quản lý bộ nhớ về các sequence Bạn nên cân nhắc cẩn thận các vấn đề quản lý bộ nhớ được chỉ ra dưới đây: Nếu cờ giải phống được đặt giá trị khác 0 khi sequence được khởi tạo, thì sequence sẽ giả định quản lý bộ nhớ của người dùng. Khi một phần tử được gán, bộ nhớ cũ được giải phóng trước khi quyền sở hữu của bộ nhớ của biểu thức bên tay phải được thừa nhận. Nếu cờ giải phóng được đặt giá trị khác 0 khi sequence được khởi tạo và các phần tử của sequence là các chuỗi hay các tham chiếu đối tượng, mỗi phần tử sẽ được giải phóng trước khi buffer chứa nội dung của sequence được giải phóng và đối tượng bị huỷ. Tránh việc gán một phần tử của sequence sử dụng toán tử [] trừ khi cờ giải phóng được đặt là 1, hoặc lỗi quản lý bộ nhớ xuất hiện. Các sequence được khởi tạo với cờ huỷ đặt bằng 0 không nên được sử dụng như các tham biến đầu vào/ đầu ra bởi vì các lỗi quản lý bộ nhớ trong bộ dịch vụ đối tượng có thể đưa đến kết quả. Luôn luôn sử dụng allocbuf và freebuf để khởi tạo và giải phóng kho lưu trữ được sử dụng với các sequence. Array Các array của IDL được ánh xạ sang các array của C++, cái mà có thể được khởi tạo tĩnh. Nếu các phần tử của array là các chuỗi hoặc các tham chiếu đối tượng, thì các phần tử của mảng trong C++ có kiểu _var. Ví dụ đoạn chương trình sau chỉ ra ba mảng với các kiểu phần tử khác nhau. // IDL interface Intf { // definitions... }; typedef long L[10]; typedef string S[10]; typedef Intf A[10]; // kiểu tham chiếu đối tượng ... // Kết quả trong C++ typedef CORBA::Long L[10]; typedef CORBA::String_var S[10]; typedef Intf_var A[10]; Cách sử dụng kiểu được quản lý kiểu _var cho các chuỗi và các tham chiếu đối tượng cho phép bộ nhớ được quản lý trong suốt khi các phần tử của mảng được gán. Các slice của mảng Kiểu _slice của mảng được sử dụng khi truyền tham số cho các mảng nhiều chiều. Một slice của một mảng với tất cả các chiều của mảng gốc trừ chiều đầu tiên. Kiểu mảng _slice cung cấp một cách thuận lợi cho việc truyền và trả lại các tham số. Một định ngh ĩa ki ểu cho m ỗi slice được phát sinh. // IDL typedef long L[10]; typedef string str[1][2][3]; ... // Results in the generation of these slices typedef CORBA::Long L_slice[10]; typedef CORBA::String_var str_slice[2][3]; typedef str_slice *str_slice_ptr; Nếu bạn chỉ có mảng một chiều, một mảng slice chỉ là một kiểu. Như bạn thấy ở ví dụ trên, ta có mảng long L[10] thì một mảng slice sẽ trả lại kết quả trong kiểu dữ liệu là CORBA::Long Quản lý bộ nhớ cho các mảng Trình biên dịch IDL của C++ sinh ra hai hàm phục vụ cho việc cấp phát và giải phóng bộ nhớ kết hợp với các mảng. Các hàm này cho phép ORB quản lý bộ nhớ mà không ghi đè các toán tử new và delete. // IDL typedef long L[10]; ... // Kết quả trong C++ inline L_slice *L_alloc();           // Cấp phát động một mảng. Trả lại giá trị NULL nếu lỗi. inline void L_free(L_slice *data);   // Giải phóng bộ nhớ mảng được cấp phát bởi L_loc. * Quản lý các ngoại lệ (Exception) Một exception trong Idl được ánh xạ sang một lớp của C++. Lớp này chứa các thành phần sau: Các bộ tạo lập (constructor) Destructors Một hàm _narrow static để xác định kiểu của exception. // OMG IDL module INVENT { exception NonExist { ID BadId; }; }; // C++ class INVENT { . . . class NonExist : public CORBA::UserException { public: static NonExist * _narrow(CORBA::Exception_ptr); NonExist (ID _BadId); NonExist (); NonExist (const NonExist &); ~NonExist (); NonExist & operator=(const NonExist &); void _raise (); ID BadId; }; }; Các thuộc tính của lớp Exception là public vì vậy bạn có thể truy nhập trực tiếp. Ánh xạ các các bộ phận Các bộ phận của lớp ngoại lệ được ánh xạ theo cách tương tự như các cấu trúc. Tất cả các bộ phận của ngoại lệ là dữ liệu công cộng trong lớp của C++, và được truy nhập trực tiếp. Var Một lớp _var được sinh ra cho một ngoại lệ. Out Một lớp Out được sinh ra cho một ngoại lệ. Các hàm bộ phận Với ngoại lệ của IDL là TYPE có các hàm bộ phận sau: static TYPE * _narrow(CORBA::Exception_ptr Except); TYPE(); Đây là constructor mặc định cho ngoại lệ TYPE(các tham chiếu bộ phận); TYPE (const TYPE & From); ~TYPE (); TYPE & operator=(const TYPE & From); void _raise (); * Quản lý các giao diện (interface) Một giao diện trong IDL được ánh xạ sang một lớp của C++. Lớp này chứa các định nghĩa của các thao tác, các thuộc tính, các hằng, và các kiểu người dùng định nghĩa (UDTs). Với một giao diện INTF, đoạn mã giao diện được sinh ra chứa các phần sau: Kiểu tham chiếu đối tượng (INTF_ptr) Kiểu biến tham chiếu đối tượng (INTF_var) Hàm bộ phận tĩnh _duplicate Hàm bộ phận tĩnh _narrow Hàm bộ phận tĩnh _nil UDTs Các hàm bộ phận về các thuộc tính và các thao tác Xét ví dụ sau: // OMG IDL module INVENT { interface Order { void cancelOrder (); }; }; Ánh xạ sang C++ như sau: // C++ class INVENT { . . . class Order; typedef Order * Order_ptr; class Order : public virtual CORBA::Object { . . . static Order_ptr _duplicate(Order_ptr obj); static Order_ptr _narrow(CORBA::Object_ptr obj); static Order_ptr _nil(); virtual void cancelOrder () = 0; . . . }; }; Các kiểu tham chiếu đối tượng và các hàm bộ phận được mô tả như sau: static INTF_ptr _duplicate (INTF_ptr Obj) Hàm bộ phận tĩnh này sao chép một tham chiếu đối tượng INTF đang tồn tại và trả lại một tham chiếu đối tượng INTF mới. Tham chiếu đối tượng INTF mới phải được giải phóng bằng việc gọi hamf bộ phận CORBA::realease. Nếu một lỗi xuất hiện thì một tham chiếu tới đối tượng INTF nil được trả lại. Đối số Obj xác định tham chiếu đối tượng được sao chép. static INTF_ptr _narrow (CORBA::Object_ptr Obj) Hàm bộ phận tĩnh này trả lại một tham chiếu đối tượng INTF mới dựa vào một tham chiếu đối tượng CORBA::Object_ptr đang tồn tại. Tham chiếu đối tượng Obiect_ptr có thể được khởi tạo bằng việc gọi hàm bộ phận CORBA::ORB::string_to_object hoặc có thể được trả lại như một tham chiếu từ một thao tác. Tham chiếu đối tượng INTF_ptr phải tương ứng với một đối tượng INTF hoặc tương ứng với một đối tượng mà kế thừa từ đối tượng INTF. Tham chiếu đối tượng INTF mới phải được giải phóng bằng việc gọi hàm bộ phận CORBA::release. Đối số Obj xác định tham chiếu đối tượng để thu hẹp tới một tham chiếu đối tượng INTF. Tham biến Obj không bị thay đổi bởi các hàm bộ phận này và nên đựoc giải phóng bởi người sử dụng khi nó không được sử dụng nữa. Nếu Obj không được thu hẹp tới một tham chiếu đối tượng INTF thì một tham chiếu đối tượng INTF nil được trả lại. static INTF_ptr _nil ( ) Hàm bộ phận static này trả lại một tham chiếu đối tượng nil mới cho giao diện INTF. Tham chiếu mới không phải được giải phóng bằng cách gọi hàm bộ phận CORBA::release. Các kiểu tham chiếu đối tượng Một lớp giao diện (INTF) là một lớp ảo; CORBA chuẩn không cho phép bạn: Khởi tạo hay hold một instance của lớp giao diện. Sử dụng một con trỏ hay một tham chiếu tới một lớp giao diện. Thay vì đó bạn có thể sử dụng một kiểu tham chiếu đối tượng: lớp INTF_ptr hay INTF_var. Bạn có thể giành được tham chiếu đối tượng bằng việc sử dụng hàm bộ phận static _nrrow. Các thao tác truy nhập trên các lớp này thì sử dụng toán tử -> Lớp _var của INTF đơn giản hoá việc quản lý bộ nhớ bằng việc huỷ tự động tham chiếu đối tượng khi lớp _var của INTF nằm ngoài phạm vi được cấp phát lại. Các thuộc tính Một thuộc tính chỉ đọc trong OMG IDL được ánh xạ sang một hàm C++ mà hàm đó trả lại giá trị thuộc tính. Một thuộc tính đọc-ghi ánh xạ sang hai hàm C++ được chòng hàm, một hàm trả lại giá trị thuộc tính và một hàm trả lại tập giá trị thuộc tính. Tên của hàm bộ phận được chồng hàm là tên của thuộc tính. Các thuộc tính được tạo ra theo cách tương tự mà các hàm được tạo ra. II. ¸nh x¹ phÝa server Trong phÇn nµy chóng ta sÏ xem c¸ch mµ c¸c giao tiÕp IDL ¸nh x¹ sang c¸c líp C++ cïng víi sù hç trî viÖc t¹o vµ gäi ®èi t­îng CORBA ë bªn phÝa server vµ mét sè vÊn ®Ò liªn quan kh¸c . 1 . Më ®Çu : Trong m« h×nh CORBA c¸c ®èi t­îng server thùc hiÖn bëi øng dông server.T¹i server, ®èi t­îng CORBA ®­îc thùc thi vµ thÓ hÞªn bëi c¸c hµm ng«n ng÷ lËp tr×nh vµ d÷ liÖu. C¸c thùc thÓ ng«n ng÷ lËp tr×nh thùc thi vµ thÓ hiÖn c¸c ®èi t­îng CORBA ®­îc gäi lµ c¸c servant. C¸c servant cung cÊp c¸c phÇn th©n cña ®èi t­îng CORBA, hay nãi c¸ch kh¸c chóng lµ thÓ hiÖn cña c¸c ®èi t­îng CORBA. Trong CORBA c¸c bé ®iÒu hîp ®èi t­îng(object adapter ) liªn kÕt c¸c ®èi t­îng CORBA víi c¸c servant cña ng«n ng÷ lËp tr×nh. VÒ kh¸i niÖm th× bé ®iÒu hîp ®èi t­îng lµm trung gian gi÷a ORB vµ c¸c servant cña ng«n ng÷ lËp tr×nh. Chóng cung cÊp c¸c dÞch vô ®Ó t¹o c¸c ®èi t­îng CORBA, tham chiÕu lªn c¸c ®èi t­îng ®ã vµ göi yªu cÇu tõ c¸c servant t­¬ng øng. Bé ®iÒu hîp ®èi t­îng chuÈn ®Þnh nghÜa trong CORBA lµ POA (Portable Object Adapter ) nã cung cÊp c¸c ®Æc tr­ng cÇn thiÕt ®Ó kÝch ho¹t c¸c servant, ®Ó cã thÓ thÝch øng víi c¸c lo¹i ORB ®­îc cung cÊp bëi nhiÒu h·ng kh¸c nhau. Trong khi BOA ( Basic Object Adapter) còng lµ mét bé ®iÒu hîp ®èi t­îng nh­ng nã g¾n víi tõng lo¹i ORB cña h·ng cung cÊp nã. D­íi ®©y ta chØ xÐt POA . POA Manager ORB POA Servants Yªu cÇu øng dông Server Mèi quan hÖ gi÷a ORB, POA vµ c¸c servant Mét øng dông server cã thÓ chøa nhiÒu thÓ hiÖn POA ®Ó hç trî c¸c ®èi t­îng CORBA víi c¸c ®Æc tÝnh kh¸c nhau ,hoÆc hç trî nhiÒu d¹ng thùc thi servant . Tuy nhiªn tÊt c¶ c¸c øng dông server ®Òu cã Ýt nhÊt mét POA gäi lµ Root POA . D­íi ®©y ta chØ giíi thiÖu c¸ch sö dông c¬ b¶n cña Root POA cÇn thiÕt cho viÖc gi¶i thÝch ¸nh x¹ C++ phÝa server : C¸c yªu cÇu ®èi t­îng CORBA ®­îc c­ tró trong mét øng dông server ®­îc göi ®i tõ mét Client vµ chuyÓn ®Õn mét server ORB . Server ORB nµy sÏ gøi c¸c yªu cÇu tíi mét POA mµ t¹i ®ã ®èi t­îng ®­îc t¹o . POA lóc ®ã göi yªu cÇu tíi servant vµ t¹o ra ®èi t­îng ®Ých . Servant thùc hiÖn c¸c yªu cÇu vµ tr¶ vÒ kÕt qu¶ qua POA vµ ORB tíi client . Server kh«ng thÓ chÊp nhËn bÊt k× yªu cÇu nµo cho ®Õn khi nã yªu cÇu ORB cña nã b¾t ®Çu l¾ng nghe c¸c yªu cÇu ®­îc göi tíi . Mét øng dông server cã thÓ cã nhiÒu POA , dßng yªu cÇu ®i vµo mçi POA ®­îc ®iÒu khiÓn bëi mét ®èi t­îng POA Manager g¾n víi POA ®ã . §Ó yªu cÇu tíi ®­îc POA POA Mangager cã thÓ xÕp hµng c¸c yªu cÇu vµ göi sau hoÆc cã thÓ huû bá c¸c yªu cÇu. Cuèi cïng mçi yªu cÇu CORBA nhËn bëi øng dông server ph¶i ®­îc xö lý bëi mét servant. Chøc n¨ng chÝnh cña ¸nh x¹ C++ phÝa server lµ ®Ó cho phÐp c¸c øng dông thi hµnh c¸c ®èi t­îng CORBA sö dông ®èi t­îng C++ trong vai trß cña c¸c servant . C¸c líp C++ phÝa server t­¬ng øng víi c¸c giao tiÕp IDL ®­îc gäi lµ líp Skeleton . Chóng t­¬ng øng víi c¸c líp proxy phÝa client vµ ®­îc sinh bëi bé dÞch IDL sang file nguån C++ , råi ®­îc dÞch trong øng dông server . Kh«ng nh­ c¸c líp proxy phÝa client c¸c líp skeleton ®­îc më réng ®Ó phôc vô d­íi vai trß lµ líp c¬ së cho c¸c líp cô thÓ cña øng dông server . Tõ viÖc dÉn xuÊt c¸c líp servant tõ c¸c líp skeleton ®ã , øng dông server ®­îc më réng vµ hoµn tÊt khung skeleton , cho phÐp thiÕt lËp vµ h×nh thµnh c¸c ®èi t­îng CORBA. ¸nh x¹ c¸c giao tiÕp ¸nh x¹ C++ phÝa server sinh ra mét líp skeleton riªng cho tõng giao tiÕp IDL . T­¬ng tù nh­ c¸ch mµ tr×nh dÞch IDL sinh ra c¸c file header ®Ó include vµo phÝa client . Tr×nh dÞch IDL th­êng sinh c¸c file header chøa c¸c ®Þnh nghÜa líp skeleton . Tªn vµ néi dung cña nh÷ng file sinh ra lµ kh¸c nhau tuú thuéc vµo c¸c nhµ triÓn khai ORB nh­ng nãi chung mét tr×nh dÞch IDL sinh ra c¶ file header vµ file thùc thi . Nghiªn cøu mét giao tiÕp ®¬n gi¶n d­íi ®©y: interface MyObject { long get_value(); }; File header ph¸t sinh chøa ®Þnh nghÜa líp skeleton nh­ sau : Class POA_MyObject public : public virtual PortableServer :: ServantBase { public : virtual CORBA::Long get_value() throw (CORBA::SystemException ) = 0 // . . . } ; Mét sè ®iÓm cÇn ph¶i chó ý: Tªn cña líp skeleton ®­îc sinh POA_MyObject phï hîp víi tªn MyObject trong giao tiÕp IDL ngo¹i trõ tiÒn tè POA_ . TiÒn tè POA_ ®­îc dïng ®Ó ph©n biÖt c¸c tªn cña c¸c líp C++ ®­îc sinh phÝa server víi c¸c tªn phÝa client . Sù ph©n biÖt namespace nµy lµ quan träng v× hÇu hÕt c¸c øng dông CORBA ch¹y kh«ng b×nh th­êng ®Òu lµ do c¶ phÝa server víi c¸c ®èi t­îng cña nã vµ client víi c¸c ®èi t­îng kh¸c . Ngoµi sù kh¸c biÖt trong tªn viÖc cè g¾ng link c¸c líp C++ phÝa client vµ phÝa server trong cïng mét øng dông dÉn ®Õn lçi thêi gian kÕt nèi ( link time-error ) bëi viÖc ®Þnh nghÜa l¹i c¸c tªn . Chó ý lµ tiÒn tè POA_ n»m ë ngoµi cïng . VÝ dô nÕu MyObject ®­îc ®Þnh nghÜa trong modul Mod th× tªn ®Çy ®ñ cña nã ®­îc sinh trong líp skeleton lµ: POA_Mod :: MyObject. Líp skeleton kÕ thõa tõ Portable :: ServantBase lµ líp c¬ së chung cho tÊt c¶ c¸c líp skeleton Líp skeleton cung cÊp ph­¬ng thøc get_value t­¬ng øng víi ph­¬ng thøc ®­îc ®Þnh nghÜa trong IDL . get_value ®­îc khai b¸o thuÇn ¶o (pure virtual) v× vËy líp skeleton POA_MyObject lµ mét líp c¬ së trõu t­îng kh«ng thÓ ®­îc thùc hiÖn . get_value bao gåm viÖc chØ ®Þnh mét ngo¹i lÖ mµ nã giíi h¹n kiÓu ngo¹i lÖ C++ ®­îc nÐm hîp lÖ. ViÖc chØ râ ngo¹i lÖ ®­îc sinh cho ph­¬ng thøc phÝa server chèng l¹i ph­¬ng thøc ®­îc khai b¸o trong c¸c l¬p proxy phÝa client mµ ë ®ã viÖc chØ ®Þnh ngo¹i lÖ lµ tïy chän TÊt c¶ c¸c ph­¬ng thøc cµi ®Æt ph­¬ng thøc IDL cã thÓ nÐm c¸c ngo¹i lÖ hÖ thèng CORBA ( CORBA system exception ) , ®iÒu nµy cã nghÜa líp c¬ së CORBA :: SystemException ®­îc include trong tÊt c¶ c¸c chØ ®Þnh ngo¹i lÖ cña líp skeleton . 3. C¸c líp servant §Ó t¹o ra mét ®èi t­îng CORBA kiÓu MyObject, b¹n ph¶i dÉn xuÊt mét líp servant tõ líp POA_MyObject vµ cµi ®Æt tÊt c¶ c¸c ph­¬ng thøc thuÇn ¶o. Xem vÝ dô cña líp servant d­íi ®©y. #include “my_object.hh” class MyObject_impl:public virtual POA_MyObject{ public: MyObject_impl(CORBA::long init_var):m_value(init_var){} Virtual CORBA::long get_value () throw (CORBA:System Exception); Private: CORBA::long m_value; MyObject_impl(const MyObject_impl &); Void operator=(const MyObject_imple &); }; Cã vµi ®IÓm quan träng cÇn l­u ý vÒ líp servant trªn: Gi¶ sö ch­¬ng tr×nh dïng tr×nh dÞch IDL ®Ó dÞch file My_object.idl trong ®ã cã chøa ®Þnh nghÜa IDL cña giao tiÕp MyObject. §Ó s¶n sinh ra file header phÝa server: My_object.hh (tªn cña file header kh«ng ®­îc tiªu chuÈn ho¸, v× vËy tªn chÝnh x¸c sÏ thay ®æi theo tr×nh dÞch IDL b¹n dïng). Ch­¬ng tr×nh include file header nµy ®Ó thu ®­îc khai b¸o cho líp c¬ së POA_Object. Tªn ®­îc chän cho líp servant MyObject_impl phô thuéc hoµn toµn vµo øng dông. Nã cã thÓ lµ bÊt cø tªn g×, miÔn lµ nã kh«ng xung ®ét víi bÊt cø tªn nµo ®­îc khai b¸o tr­íc bëi ¸nh x¹ C++, nh­ nh÷ng tªn ®­îc b¾t ®Çu víi POA_. Theo quy ­íc ®Æt tªn cho c¸c líp servant víi c¸c hËu tè _impl sao cho chóng ta cã thÓ biÕt ®­îc ®ã lµ c¸c líp servant khi nh×n vµo tªn cña líp. Líp MyObject_Impl thõa kÕ tù líp skeleton POA_myObject vµ n¹p chång hµm thuÇn ¶o get_value lµm cho MyObject mét líp cô thÓ cã thÓ thùc hiÖn. B¹n b¾t buéc ph¶i cÇn tÊt c¶ c¸c hµm thuÇn ¶o ®­îc thõa kÕ trong líp servant bëi v× tr×nh dÞch C++ sÏ kh«ng cho phÐp t¹o c¸c thÓ hiÖn cña nã. Trõ ra r»ng b¹n cã thÓ thªm bÊt cø g× kh¸c b¹n thÊy h÷u Ých ®Ó hç trî viÖc thi hµnh líp servant cña b¹n. VD: b¹n muèn thªm constuctor vµ destructor , thªm hµm thµnh phÇn hoÆc d÷ liÖu thµnh phÇn. B¹n còng cã thÓ thªm phÇn protected hoÆc private. §èi víi vÝ dô trªn chóng ta ®· thªm mét thµnh phÇn d÷ liÖu private lµ m_value cã kiÓu lµ CORBA:: long vµ mét constructor khëi t¹o thµnh phÇn ®ã. Ch­¬ng tr×nh còng ®· t¹o c¸c constructor sao chÐp vµ to¸n tö g¸n mÆc ®Þnh private. B»ng c¸ch Êy kh«ng cho phÐp sao chÐp servant cña chóng ta. Thùc tÕ hiÕm khi cÇn cã constructor sao chÐp hoÆc g¸n servant, v× vËy nªn Èn c¸c constructor sao chÐp vµ c¸c khai b¸o mÆc ®Þnh cho c¸c líp servant. ViÖc thùc thi ph­¬ng thøc get_value ®¬n gi¶n lµ tr¶ vÒ gi¸ trÞ m_value. ViÖc thùc thi hµm get_value qu¸ ®¬n gi¶n ®Õn nçi kh«ng cã ®iÒu khiÓn lçi cã thÓ x¶y ra,v× vËy kh«ng ph¶i nÐn bÊt k× ngo¹i lÖ nµo. Bëi v× c¸c servant cña ch­¬ng tr×nh thõa kÕ c¸c hµm ¶o, nã ph¶i ®­îc khai b¸o l¹i c¸c hµm chÝnh x¸c nh­ chóng ®­îc khai b¸o trong líp c¬ së skeleton ph¸t sinh, bao gåm tÊt c¶ c¸c chØ ®Þnh ngo¹i lÖ. H¬n thÕ n÷a c¸c tªn hµm, c¸c ký hiÖu vµ chØ ®Þnh ngo¹i lÖ cho viÖc ®Þnh nghÜa thùc thi servant ph¶I phï hîp chÝnh x¸c víi khai b¸o t­¬ng øng. Nõu cã sù kh«ng phï hîp chóng hÇu nh­ cã thÓ Èn, h¬n thÕ n÷a lµ ®Þnh nghÜa chång, thao t¸c skeleton thõa kÕ. §iÒu nµy cã nghÜa líp servant thõa kÕ c¸c hµm thuÇn ¶o vµ bëi vËy sÏ kh«ng cô thÓ. Cã ®­îc nh÷ng khai b¸o vµ ®Þnh nghÜa nµy chÝnh x¸c cã thÓ lµ ®èi t­îng sai, v× vËy nhiÒu ch×nh dÞch IDL include c¸c option. Nõu tr×nh dÞch IDL cña b¹n hç trî ®Æc tÝnh ®ã, th× b¹n nªn sö dông nã khi viÕt c¸c líp servant cña b¹n. nÕu thiÕu ®Æc tÝnh nµy b¹n nªn cut vµ Paste khai b¸o ph­¬ng thøc víi viÖc thùc thi tõ c¸c file ®­îc sinh phÝa server ®Ó tr¸nh lçi. Líp myObject kh¸ ®¬n gi¶n vµ ch­a ®Çy ®ñ. ThÓ hiÖn cña nã lµ ®Çy ®ñ kh¶ n¨ng cña viÖc h×nh thµnh ®èi t­îng CORBA kiÓu MyObject. 4. H×nh thành ®èi t­îng §Ó sö dông thÓ hiÖn cña líp servant MyObject_Impl ®Ó t¹o mét ®èi t­îng CORBA, b¹n ph¶I t¹o mét servant MyObject_Impl trong khi h×nh thµnh ®èi t­îng CORBA. Chó ý r»ng viÖc t¹o mét servant C++ kh«ng hµm ý viÖc t¹o mét ®èi t­îng CORBA, mçi thùc thÓ cña chóng cã nh÷ng ®Ióm riªng vµ vßng ®êi riªng biÖt. §Ó ®¬n gi¶n vÝ dô sau sÏ chØ râ c¸ch dÔ nhÊt ®Ó t¹o mét servant C++ vµ t¹o lËp mét ®èi t­îng CORBA míi b»ng servant ®ã. // ®Çu tiªn t¹o mét thÓ hiÖn servant MyObject_impl servant(42); // tiÕp theo t¹o ®èi t­îng CORBA vµ sö dông servant míi t¹o MyObject_var object= servant_this(); Dßng ®Çu cña ®o¹n code t¹o mét thÓ hiÖn servant vµ thiÕt lËp gi¸ trÞ cña nã lµ 42. ë ®iÓm nµy tÊt c¶ nh÷ng g× ch­¬ng tr×nh cÇn cã lµ mét ®èi t­îng C++ kh«ng kÕt nèi gi÷a servant vµ bÊt k× mét ®èi t­îng CORBA ®· ®­îc t¹o. Dßng hai ®o¹n m· lµ lêi gäi hµm _this cña servant,nã thøc hiÖn c¸c b­íc sau: T¹o mét ®èi t­îng CORBA d­íi root POA. §¨ng kÝ servant cïng víi root POA khi thùc thi cho ®èi t­îng míi. T¹o mét tham chiÕu ®èi t­îng cho ®èi t­îng míi. Tr¶ vÒ tham chiÕu ®èi t­îng. Hµm _this ®­îc cung cÊp bëi líp skeleton ®o¹n m· d­íi sÏ cho biÕt líp POA_MyObject ®­îc sinh. Cho bÊt k× líp skeleton POA_A miªu t¶ giao tiÕp IDL. Vµ gi¸ trÞ tr¶ vÒ cña hµm POA_A::_this lµ A_ptr, kiÓu tham chiÕu ®èi t­îng C++ cho giao tiÕp A. theo vÝ dô tr­íc kiÓu tr¶ vÒ cña hµm this lµ MyObject_ptr. Bëi v× lêi gäi hµm _this chÞu tr¸ch nhiÖm ®¶m b¶o CORBA::release cuèi cïng ®­îc gäi kiÓu tham chiÕu ®èi t­îng ®­îc tr¶ vÒ chóng ta ®· g¸n gi¸ trÞ tr¶ vÒ cho biÕn MyObject_var. Trong vÝ dô trªn ®èi t­îng CORBA ®­îc t¹o bëi hµm _this lµ mét ®èi t­îng tån t¹i ng¾n ngñi. §èi t­îng CORBA tån t¹i ng¾n ngñi bëi v× nã rµng buéc víi thêi gian tån t¹i cña POA mµ trong ®ã nã ®­îc t¹o ra. Tuy nhiªn hµm _this cã thÓ cung cÊp c¸ch thøc t¹o khu«n d¹ng nµy cña viÖc dÞch vô ®¨ng kÝ nÕu POA cña servant ®­îc t¹o víi c¸ch thøc hîp lý. TËp chuÈn cña c¸ch thøc ®­îc hç trî bëi root POA ®­îc thiÕt kÕ râ rµng ®Ó cho phÐp hµm _this ®­îc sö dông theo kiÓu nµy. 5. Server main §Ó hoµn tÊt øng dông server ®¬n gi¶n cña ch­¬ng tr×nh, ch­¬ng tr×nh ph¶i cung cÊp mét hµm main nh­ sau: #include “my_objects.hh” #include “iostream.h” int main(int argc, char *args[]) { // khëi t¹o ORB CORBA::ORB_var orb=CORBA::ORB_init(argc, argv); // LÊy tham chiÕu ®Õn Root POA CORBA::Object_var obj = orb->resolve_inittial_references(“Root POA”); Portable Server::POA_var poa=PortableServer::POA::_narrow(obj); // KÝch ho¹t manager cña POA Portable Server::Manager_var mgr=poa->the_POAmanager(); Mrg=activeti(); // T¹o servant MyObject vµ sau ®ã t¹o ngÇm mét ®èi t­îng CORBA vµ khëi // t¹o nã víi servant MyObject_impl servant(42); MyObject_var object = servant_this(); // ChuyÓn ®æi tham chiÕu ®èi t­îng sang d¹ng x©u vµ ®­a ra thiÕt bÞ chuÈn CORBA::String_var str = orb->object_tc_string(object); Cout<<str<<edl; // Cho phÐp ORB b¾t ®Çu xö lý yªu cÇu. Orb->run(); Return 0 } Hµm Main Server ho¹t ®éng nh­ sau: Khëi t¹o ORB qua lêi gäi hµm chuÈn CORBA::ORB_init. Sö dông tham chiÕu ORB tr¶ vÒ qua lêi gäi ORB_init ®Ó gäi resolve_initial_references cho phÐp thu ®­îc ®­îc tham chiÕu tõ c¸c giao tiÕp. Ch­¬ng tr×nh sÏ sö dông nã ®Ó nhËn ®­îc tham chiÕu tíi root POA cho ORB, ®ång thêi còng ®Ó nhËn tham chiÕu ®Õn POA Manager cho Root POA. KÝch ho¹t POA Manager cho phÐp Root POA b¾t ®Çu xö lý yªu cÇu miÔn lµ ORB b¾t ®Çu l¾ng nghe yªu cÇu. T¹o mét servant cña MyObject_impl. Ch­¬ng tr×nh gäi hµm _this cña servant ®Ó t¹o mét ®èi t­îng CORBA míi, cã thêi gian tån t¹i ng¾n vµ t¹o lËp nã víi servant. Sau ®ã ch­¬ng tr×nh l­u tr÷ tham chiÕu ®èi t­îng tr¶ vÒ trong mét biÕn MyObject_var vµ biÕn nµy sÏ tù ®éng ®­îc release khi mµ MyObject_var hÕt ph¹m vi ho¹t ®éng. §Ó t¹o tham chiÕu ®èi t­îng cho ®èi t­îng CORBA míi tíi c¸c Client, ch­¬ng tr×nh chuyÓn ®æi no sang d¹ng string b»ng viÖc sö dông hµm object_to_string cña ORB. Sau ®ã g¸n x©u tr¶ vÒ cho biÕn String_var råi ®­a ra thiÕt bÞ chuÈn. Ch­¬ng tr×nh gäi thñ tôc ORB::run ®Ó b¾t ®Çu l¾ng nghe c¸c yªu cÇu. ViÖc chuyÓn ®èi tham chiÕu sang d¹ng String (cô thÓ ë phÇn 7.10) cho phÐp client nhËn ®­îc tham chiÕu ®èi t­îng mét c¸ch chÝnh x¸c ®Ó cã thÓ gäi yªu cÇu trªn ®èi t­îng. DÜ nhiªn nh÷ng øng dông s¶n phÈm sÏ kh«ng bao giê dïng c¸ch tham chiÕu ®èi t­îng nh­ vËy mµ dïng dÞch vô tham chiÕu ®èi t­îng nh­ Naming (c.18) hoÆc trading (c19). 6. Quy t¾c chuyÒn tham sè Qu¶n lý bé nhí lµ cèt lâi cña viÖc ¸nh x¹ c++ phÝa server. VÝ dô trªn ®· tr¸nh ®Ò cËp tíi vÊn ®Ò qu¶n lý bé nhí ®Ó tËp trung vµo c¸c ®Þnh nghÜa líp servant. Cïng víi qui t¾c phÝa Client . Qui t¾c truyÒn tham sè phÝa server ®­îc thùc hiÖn víi 2 yªu cÇu. Trong suèt vÒ vÞ trÝ Qu¶n lý bé nhí cho Server còng nh­ Client, c¸c ®èi t­îng cã thÓ ®­îc ®Æt cïng nhau hoÆc kh«ng ®Æt cïng nhau. HiÖu qu¶ Sao chÐp tham sè cã thÓ bá qua bÊt cø khi nµo cã thÓ ®Æc biÖt khi Client vµ ®èi t­îng ®Ých ®­îc ®Æt gÇn nhau. Ta nhËn thÊy r»ng qui t¾c truyÒn tham sè phÝa server t­¬ng tù nh­ qui t¾c phÝa Cilent v× vËy cho phÐp g¸n hiÖu qu¶ c¸c ®èi t­îng ®­îc ®Æt gÇn nhau. Qui t¾c truyÒn tham sè tr×nh bµy ë phÇn nµy tu©n theo cïng quy t¾c víi phÇn 7.14 ®· tr×nh bµy ë phÝa Cilent. NÕu b¹n ch­a ch¾c ch¾n vÒ sù kh¸c nhau gi÷a c¸c kiÓu d÷ liÖu cã ®é dµi thay ®æi vµ d÷ liÖu cã ®é dµi cè ®Þnh vµ c¸c kiÓu d÷ liÖu IDL. H·y xem l¹i 7.14.1 (trang 275). 6.1. TruyÒn tham sè kiÓu ®¬n gi¶n. KiÓu ®¬n gi¶n hoÆc kiÓu liÖt kª ®­îc truyÒn theo trÞ hoÆc theo tham chiÕu phô thuéc vµo tham sè cã bÞ thay ®æi hay kh«ng. D­íi ®©y lµ 1 thao t¸c IDL sö dông tham sè kiÓu long interface Foo{ long long_op(in long l_in, inout long l_inout, out long l_out); }; ph­¬ng thøc t­¬ng øng trong líp skeleton cã d¹ng nh­ sau. Class POA_Foo:public vituar(PortableServer::ServantBase){ Public Virtual CORBA::long long_op( CORBA::long l_in, CORBA::long l_inout, CORBA::long l_out, ) throw (CORBA::SystemException)=0; //... }; ViÖc ¸p dông long_op trong líp servant ®­îc dÉn xuÊt cã thÓ ®­îc viÕt nh­ sau: CORBA::long Foo_ipml::long_op( CORBA::long l_in, CORBA::long & l_inout, CORBA::long long_out l_out, ) throw(CORBA::system exception) { l_inout =l_in*2; l_out=l-in/2; return 99; } Gi¸ trÞ cho c¶ l_in vµ l_inout ®­îc truyÒn trong hµm nµy b»ng lêi gäi. ViÖc thay ®æi gi¸ trÞ cña l_inout ®­îc truyÒn cho Orb servers vµo thêi gian ch¹y ®Ó tr¶ l¹i clien . Tham sè l_out kh«ng ®­îc khëi t¹o trong hµm nµy v× vËy ch­¬ng tr×nh cÇn thiÕt lËp gi¶ trÞ cña nã. Cuèi cïng göi l¹i gi¸ trÞ tr¶ vÒ qua c©u lÖnh return th­êng lÖ cña C++. 6.2 TruyÒn tham sè ®èi víi kiÓu d÷ liÖu phøc t¹p cã ®é dµi cè ®Þnh. Quy t¾c viÖc truyÒn tham sè cho kiÓu d÷ liÖu phøc t¹p cã chiÒu dµi cè ®Þnh (struct vµ union) t­¬ng tù kiÓu d÷ liÖu ®¬n gi¶n ngo¹i trõ tham sè vµo ®­îc truyÒn kiÓu tham chiÕu tíi h»ng ®Ó tr¸nh sao chÐp. Sau ®©y lµ mét thñ tôc IDL truyÒn tham sè struct cã ®é dµi cè ®Þnh. Struct Fls{ // Fixed –length struct Long l_mem; Doubel d_mem; }; interface Foo{ Fls fls_op(in Fls fls_in, inout Fls fls_inout, out Fls fls_out); }; Ph­¬ng thøc t­¬ng øng ë líp skeleton nh­ sau: Class POA_Foo: public virtual PortableServer:: ServantBase{ Public: Virtual Fls fls_op( Const Fls &fls_in; Fls & fls_inout; Fls _out fls_out; ) throw (CORBA::System Exception)=0; //... }; ViÖc cµi ®Æt fls_op trong líp servant ®­îc dÉn xuÊt cã thÓ ®Þnh nghÜa nh­ sau: Fls Foo_impl::fls_op( Const Fls &fls_in; Fls & fls_inout; Fls _out fls_out; ) throw (CORBA::System Exception); { // sö dông gi¸ trÞ biÕn fls_in vµ fls_inout // hiÖu chØnh fls_inout fls_inout.l_mem*=2; fls_inout.d_mem/=2; // khëi t¹o fls_out fls_out.l_mem=1234; fls_out.d_mem=5,678e8; // T¹o vµ khëi t¹o gi¸ trÞ tr¶ vÒ. Fls resutl={4321,-9,78e6); Return result; } Tham sè fls_in ®­îc tham chiÕu d¹ng h»ng, v× vËy chØ cho phÐp ®äc c¸c thµnh phÇn struct. Th­êng th× ph­¬ng thøc cña ta sÏ xö dông ph­¬ng thøc in, inout nh­ng ®Ó cho ®¬n gi¶n chóng ta sÏ kh«ng xÐt ë ®©y. Sau khi sö dông gi¸ trÞ cña ®Çu vµo cho fls_inout, ch­¬ng tr×nh thay ®æi gi¸ trÞ cña c¸c thµnh phÇn. Chó ý: ®©y chØ lµ vÝ dô ®¬n gi¶n, kiÓu phøc t¹p inout cã ®é dµi cè ®Þnh ®­îc truyÒn theo kiÓu tham chiÕu cho phÐp ph­¬ng thøc cã thÓ hiÖu chØnh nã. Tham sè fls_out ®­îc khëi t¹o qua ph­¬ng thøc nµy, v× vËy ch­¬ng tr×nh sÏ khëi t¹o c¸c thµnh phÇn ®Ó vµo thêi gian ch¹y ch­¬ng tr×nh ORB server cã thÓ göi c¸c thµnh phÇn ®ã vÒ cho Client. Cuèi cïng, ch­¬ng tr×nh khai b¸o Fls côc bé, khëi t¹o vµ tr¶ vÒ gi¸ trÞ cña nã qua c©u lÖnh return. 6.3>TruyÒn tham sè m¶ng víi sè phÇn tö cè ®Þnh ¸nh x¹ m¶ng IDL trùc tiÕp sang m¶ng C++ .Tr«ng C++ c¸c m¶ng lu«n ®­îc truyÒn bëi con trá .D­íi ®©y lµ thao t¸c truyÒn tham sè m¶ng cã ®é dµi cè ®Þnh : typedef foo { Darr darr_op(in darr darr_in, Inout darr darr_inout Out darr darr_out ) ; } ; ph­¬ng thøc t­¬ng øng trong líp skeleton cã d¹ng : class poa_foo:: public virtual portableserver :: servantbase{ public virtual darr slice * darr_op ( const darr darr_in, darr darr_inout, darr_out darr_out, ) throw (CORBA::systemexception )=0 … }; viÖc cµi ®Æt Darr_op trong líp servant nh­ sau; darr_slice *foo_impl::darr_op ( const darr darr_in , darr darr_inout, darr_out darr_out, ) throw (CORBA::systemexception ) const int array_length =sizeof (darr_in)/ sizeof (*darr_out) ; int i; //sö dông gi¸ trÞ truyÒn vµo cña darr_in and darr_inout //thay ®æi darr_inout for (i=0; i< array_length; i++) { darr_inout[i]* =i; } // khëi t¹o darr_out for (i=0; i< array_length; i++) { darr_out[i]* =i; } // t¹o vµ khëi t¹o gi¸ trÞ tr¶ vÒ darr_slice *result =darr_alloc(); for (i=0; i< array_length; i++) { result[i]* =i*i; } return result; } Tr¸ch nhiÖm qu¶n lý bé nhí cña ph­¬ng thøc servant nh­ sau : + tham sè vµo darr_in ®­îc truyÒn theo kiÓu h»ng (const Darr) gièng nh­ con trá h»ng CORBA::double ,v× vËy ch­¬ng tr×nh ®­îc phÐp truy cËp gi¸ trÞ ®­îc l­u tr÷ trong m¶ng nh­ng kh«ng ®­îc phÐp thay ®æi. M¶ng ®­îc x¸c ®Þnh bëi lêi gäi, ph­¬ng thøc servant kh«ng cã tr¸ch nhiÖm qu¶n lý bé nhí cho nã. + Tham sè vµo/ra darr_inout ®­îc truyÒn nh­ mét biÕn darr_out. Nã hiÖu qu¶ nh­ con trá CORBA::double, cho phÐp ch­¬ng tr×nh truy cËp vµ hiÖu chØnh gi¸ trÞ cña m¶ng , nh­ víi tham sè vµo, ph­¬ng thøc servant kh«ng cã tr¸ch nhiÖm qu¶n lý bé nhí cho m¶ng. Lêi gäi x¸c ®Þnh nã vµ truyÒn nã vµo, ®äc vµ ghi gi¸ trÞ cña nã. + tham sè ra darr_out ®­îc truyÒn nh­ kiÓu darr-out kiÓu nµy lµ mét typedef cho darr vµ ®­îc sö dông cho sù nhÊt qu¸n víi c¸c kiÓu ra kh¸c. Mét tham sè ra ch­a ®­îc khëi t¹o khi truyÒn tíi ph­¬ng thøc servant bëi v× nã truyÒn tõ server sang client. Do ®ã ®o¹n m· vÝ dô ®· thiÕt lËp tÊt c¶ c¸c gi¸ trÞ trong m¶ng sao cho khi ch¹y ORBServer cã thÓ göi nã trë l¹i Client. Chó ý r»ng víi m¶ng vµo vµ vµo/ra cña c¸c phÇn tö cã ®é dµi cè ®Þnh, tr×nh gäi sÏ ph¶i cÊp ph¸t m¶ng vµ ph­¬ng thøc servant cña ta kh«ng cã tr¸ch nhiÖm qu¶n lý bé nhã cña nã. + Bëi v× C++ kh«ng cho phÐp tr¶ vÒ gi¸ trÞ cña m¶ng ,do ®ã kiÓu tr¶ vÒ cña ph­¬ng thøc servant lµ Darr.slice * . Ph­¬ng thøc servant cña chóng ta sÏ cÊp ph¸t ®éng mét thùc thÓ (thÓ hiÖn ) darr b»ng viÖc sö dông hµm darr_alloc ®­îc sinh ra bëi tr×nh dÞch IDL ®iÒn c¸c gi¸ trÞ vµ tr¶ nã vÒ lêi gäi cña ph­¬ng thøc servant ,cã thÓ lµ client trong cïng mét tiÕn tr×nh cho tr­êng hîp cÊp ph¸t hoÆc sÏ lµ b¶n th©n Orb nÕu client lµ mét m¸y tÝnh ë xa , cã tr¸ch nhiÖm cuèi cïng lµ gäi darr_fee trªn gi¸ trÞ tr¶ vÒ ®óng c¸nh ®Ó gi¶i phãng nã. cÊp ph¸t gi¸ trÞ tr¶ vÒ sö dông hµm darr_alloc ,nÕu ta sö dông to¸n tö New th× cã thÓ g©y ra lçi lóc ch¹y khi ta gi¶i phãng bé nhí. 6.4> TruyÒn tham sè string vµ wide string string trong idl ®uîc ¸nh x¹ sang char * trong C++ ®©y lµ thao t¸c truyÒn tham sè Ønterface Foo { String string_op( in string s_in, Inout string s_inout , Out string s_out); } ph­¬ng thøc t­¬ng øng trong líp skeleton : class POA_Foo::public virtual()portableserver::servantbase { public virtual char* string_op( const char * s_in , char* & s_inout, CORBA::string_out s_out, ) throw (CORBA::systemexception)=0; //… }; viÖc cµi ®Æt bªn trong líp servant cã thÓ viÕt nh­ sau : char * Foo_impl::string_op(const char * s_in , char* & s_inout, CORBA::string_out s_out, ) throw (CORBA::systemexception)=0; //sö dông gi¸ trÞ truyÒn vµo cña s_in vµ s_out // thay ®æi s_inout const char * inout_out_value=” out going inout value” if (strlen(s_inout) < strlen(inout_out_value) ) { s_inout=CORBA::string_dup(inout_out_value); } //khëi t¹o s_out s_out= CORBA::string_dup(“out put string”); //t¹o gi¸ trÞ tr¶ vÒ return CORBA::string_dup(“return string”); + +tham sè vµo s_in ®­îc truyÒn theo kiÓu char * & lµ mét tham chiÕu cña con trá kiÓu char . cã thÓ gi¶i phãng vïng nhí cò (string_free) vµ cÊp ph¸t vïng nhí míi (string_alloc()) . client lu«n ph¶i sö dông hµm string_alloc() vµ hµm string_dup() ®Ó cÊp ph¸t c¸c x©u ®éng. + tham sè s_out lµ mét líp kiÓu CORBA::string_out kiÓu nµy ®­îc sö dông nh­ kiÓu char * & . ta thÊy r»ng tham sè ®­îc chuyÒn tõ server tíi client ,ph­¬ng thøc servant cña ch­¬ng tr×nh ph¶i cÊp ph¸t ®éng x©u ra vµ g¸n gi¸ trÞ cho tham sè cña chóng ®èi víi c¸c client cïng mét m¸y ®Çu ra nµy chØ ®­îc göi l¹i mµ kh«ng cÇn qua b­íc qu¸ ®é lµ s¾p xÕp vµ dän dÑp . nÕu client ë xa : tr×nh orb ë m¸y chñ sÏ s¾p xÕp x©u ra sau khi ph­¬ng thøc servant kÕt thóc, x©u gi¶i phãng b»ng hµm string _free() +x©u tr¶ vÒ ®­îc sö lý gièng hÖt x©u ra . bëi v× ¸nh x¹ C++ ng¨n cÊm truyÒn gi¸ trÞ null cho cho tham sè x©u ,nªn ph­¬ng thøc servant kh«ng ph¶i kiÓm tra con trá null ®­îc truyÒn cho nã vµ kh«ng cho phÐp tr¶ vÒ con trá null víi tham sè ra hoÆc gi¸ trÞ tr¶ vÒ. *®èi víi widestring còng t­¬ng tù : c¸c hµm cÊp ph¸t vµ gi¶ phãng lµ : wstring_alloc();wstring_dup();wstring_free(); 6.5> TruyÒn tham sè kiÓu phøc t¹p cã ®é dµi thay ®æi vµ kiÓu any Nh÷ng kiÓu d÷ liÖu phøc t¹p cã ®é dµi biÕn ®æi bao gåm :sequence,struct,union mµ cã chøa c¸c thµnh phÇn cã ®é dµi biÕn ®æi vÝ dô: struct vls { long l_mem; string s_mem; } ; interface foo { vls vls_op ( in vls vls_in, out vls vls_inout, inout vls vls _out, ) } ; ph­¬ng thøc t­¬ng øng trong líp skeleton class poa::public virtual portable server :: servantbase{ public : virtual vls* vls_op( const vls & vls_in, vls & vls_inout, vls_out vls_out ) throw (CORBA::systemexception)=0; //… }; + tham sè truyÒn vµo lvs_in vµ tham sè vµo ra lvs_inout cã quy t¾c nh­ kiÓu phøc cã ®é dµi cè ®Þnh . + quy t¾c ®èi víi tham sè ra cã ®é dµi thay kh¸c biÖt víi kiÓu cã ®é dµi cè ®Þnh . §Æc biÖt ta ph¶i cÊp ph¸t ®éng cho tham sè ra cã ®é dµi thay ®æi vµ tr¶ vÒ gi¸ trÞ ,sö dông to¸n tö new vµ tr¶ chóng vÒ b»ng con trá cña client mµ nã tr¸ch nhiÖm gi¶i phãng chóng b»ng to¸n tö delete vls_out =new vls; //… vls *reusult =new vls; return result ; ph­¬ng thøc cña ch­¬ng tr×nh khëi t¹o vls_out b»ng viÖc gäi to¸n tö new 6.6> truyÒn tham sè m¶ng víi c¸c thµnh phÇn cã ®é dµi thay ®æi ViÖc qu¶n lý bé nhí cho m¶ng víi c¸c phÇn tö cã ®é dµi thay ®æi t­¬ng tù víi c¸c kiÓu d÷ liÖu cã ®é dµi thay ®æi Vd : Struct vls { Long nunber ; String name; }; typedef vls varr[3]; inteface Foo { Varr varr_op ( in Varr varr_in, inout Varr varr_inout , out Varr varr_out, ); }; líp skeleton class POA_Foo ::virtual PortableServer :: ServantBase { public : virtual Varr_slice * varr_op( const varr varr_in, vass slice * varr_inout, ) thow (CORBA::SystemException)=0; } cµi ®Æt varr_slice * Foo::varr_op( ) { const int array_length =sizeof(varr_in)/sizeof(*varr_in); int i; // thay doi varr_inout vass_inout[0]=varr_out[0]; //t¹o khëi t¹o varr_out varr_out=varr_alloc(); const char * brothes[]={“john”,”jin”,”rich”}; for (i=0;i< array_length;i++)] varr_out[i].number=i-1; varr_out[i].name=brothes[i] } //t¹o vµ khëi t¹o gi¸ trÞ tr¶ vÒ varr_slice * result =varr_alloc(); const char * sisters[]={“aa”,”jbbb”,”ccc”}; for (i=0;i< array_length;i++)] result[i].number=i-1; result[i].name=brothes[i] } return result; ] + viÖc qu¶n lý bé nhí nh­ sau : Tham sè vµo varr_in ®ùoc sö lý nh­ m¶ng c¸c hÇn tö cã ®é dµi cè ®Þnh , client cÊp ph¸t vµ khëi t¹o vµ ph­¬ng thøc cña ta chØ cã thÓ ®äc c¸c phÇn tö , do ®ã ta kh«ng cÇn cã tr¸ch nhiÖm qu¶n lý bé nhí T­¬ng tù tham sè vµo ra varr_inout ®Þnh cÊp ph¸t vµ khëi t¹o bëi client. Nh­ng tr­êng hîp nµy chóng ta ®­îc phÐp thay ®æi gi¸ trÞ cña chóng, tham sè ®­îc truyÒn kiÓu varr_slide* vµ nã cho phÐp chóng ta ®¸nh chØ sè m¶ng nh­ tr­êng hîp tù nhiªn. Ph­¬ng thøc cña chóng ta kh«ng cã tr¸ch nhiÖm ph¶i qu¶n lý bé nhí. Tham sè ra varr_out ®­îc truyÒn kiÓu varr_out t­¬ng víi varr_slide* vµ mét tham chiÕu tíi con trá cña varr_slide* sö dông hµm varr_alloc ®Ó cÊp ph¸t ®éng lêi gäi cña ph­¬ng thøc servant còng nh­ m¸y client (trªn 1 m¸y) hoÆc ORB côc bé cã tr¸ch nhiÖm gäi varr_free ®Ó gi¶i phãng vïng nhí cña m¶ng. Kh«ng nªn sö dông to¸n tö new v× kh«ng kh¶ chuyÓn vµ cã thÓ sinh lçi thêi gian ch¹y khi m¶ng ®­îc gi¶i phãng. Chóng ta cÊp ph¸t vµ khëi tao gi¸ trÞ tr¶ vÒ nh­ tham sè vµ lêi gäi cã tr¸ch nhiÖm ®¶m b¶o con trá tr¶ vÒ cuèi cïng ®­îc truyÒn tíi varr_free. 6.7 TruyÒn tham sè tham chiÕu ®èi t­îng Tham chiÕu ®èi t­îng lµ kiÓu cã ®é dµi thay ®æi bëi v× nã t­¬ng tù con trá. Quy t¾c truyÒn tham sè cña chóng t­¬ng tù ®èi víi kiÓu string. VD: Interface Foo{ Foo ref_op( In Foo ref_in; Inout Foo ref_inout; Out Foo ref_out; ); void say_hello(); }; Líp Skeleton: Class POA_Foo: public virtual Portable Server:: Servant Base { Public: Virtual Foo_ptr ref_op( Foo_ptr ref_in; Foo_ptr & ref_inout; Foo_out ref_out; )throw (CORBA::SystemException)=0; // }; Cµi ®Æt ref_op Foo_impl:: Say_hello() throw (CORBA: System Exeption) { cout<<”hello”<<endl; } foo_ptr Foo_impl::ref_op( Foo_ptr ref_in; Foo_ptr ref_inout; Foo_out ref_out;) Thow (CORBA: system Exception) // sö dông ref_in if (!CORBA::is_nil(ref_in)){ ref_in->say_hello(); } //sö dông ref_inout if (!CORBA::is_nil(ref_inout)){ ref_inout->say_hello(); } // thay ®æi ref_inout CORBA::release (ref_inout); Ref_inout=_this(); // khëi t¹o ref_out foo_imp* new_servant=new Foo_impl; ref_out=new=new_servant->_this(); // t¹o gi¸ trÞ trë vÒ return Foo::_nil(); Qu¶n lý bé nhí cña ph­¬ng thøc servant Tham sè vµo ref_in ®­îc truyÒn theo trÞ. Chó ý r»ng nã lµ 1 tham chiÕu ®èi t­îng vµ kh«ng ®èi t­îng mµ nã tham chiÕu tíi nã ®­îc truyÒn cho ph­¬ng thøc servant. NÕu nã b»ng nill ref_in cã thÓ sÏ ®­îc dïng ®Ó gäi thao t¸c trªn ®èi t­îng ®­îc tham chiÕu. Ch­¬ng tr×nh chØ sö dông tham chiÕu ®èi t­îng vµ kh«ng ph¶i cã tr¸ch nhiÖm qu¶n lÝ Thao sè vµo ra ref_inout ®­îc truyÒn theo kiÓu tham chiÕu cho phÐp ®èi t­îng truy nhËp gi¸ trÞ vµ thiÕt lËp gi¸ trÞ míi cho CRB vµ thêi gian ch¹y ®Ó göi l¹i client. Ch­¬ng tr×nh ph¶i release tham chiÕu ®èi t­îng vµo tr­íc khi thiÕt lËp nã gi¸ trÞ míi. Trong vÝ dô ®èi t­îng thiÕt lËp ref_inout tíi tham chiÕu ®èi t­îng ®Ých, thu ®­îc qua lêi gäi hµm _this. Gi¸ trÞ hµm this ph¶i ®­îc release bëi lêi gäi v× vËy b»ng viÖc g¸n nã cho ref_inout chóng ta truyÒn thùc sù tr¸ch nhiÖm tíi lêi gäi cña ch­¬ng tr×nh Tham sè ra ®­îc truyÒn nhê 1 for+out cho ®èi t­îng ®­îc for_ptr. Nã ®­îc khëi t¹o vµ truyÒn vµo ch­¬ng tr×nh ph¶i khëi t¹o nã víi mét tham chiÕu ®èi t­îng Foo nil hoÆc kh«ng nil. Tham chiÕu ®èi t­îng chóng ta g¸n cho tham sè ref _out trë thµnh ®¶m nhiÖm cu¶ lêi gäi. Khèi catch ng¨n chÆn viÖc toµn bé øng dông bÞ huû bá. Nã cßn ng¨n øng dông client kh«ng nhËn c¸c ngo¹i lÖ ng­êi dïng ®Þnh nghÜa mµ kh«ng ®­îc khai b¸o trong mËt ®é raises Trong vÝ dô ch­¬ng tr×nh khëi t¹o mét tham sè ra b»ng viÖc t¹o 1 servant Foo_impl vµ dïng hµm this cña nã ®Ó t¹o ®èi t­îng CORBA míi. Sau ®ã g¸n gi¸ trÞ tr¶ vÒ cña c¸c hµm this cho ref_out chuyÓn cho lêi gäi hµm cã tr¸ch nhiÖm cho viÖc release nã . Chó ý Servant kh«ng ®­îc t¹o trªn stack nÕu kh«ng nã cã thÓ bÞ ph¸ huû sau khi lÖnh cuèi cïng cña ph­¬ng thøc servant ®­îc thùc hiÖn bá l¹i con trá ®­îc ®¨ng kÝ bëi POA. Thay v× ®ã , chóng ta cÊp ph¸t trªn vïng nhí heap . Cho ®Õn mét thêi ®iÓm nµo ®ã chóng ta ph¶i xo¸ nã ®Ó gi¶i phãng bé nhí ViÖc xö lý tham chiÕu tr¶ vÒ còng nh­ xö lý tham chiÕu ra . Lêi gäi cã tr¸ch nhiÖm release tham chiÕu tr¶ vÒ trong vÝ dô lêi gäi Foo::_nil() tr¶ vÒ mét tham chiÕu nil . Tham chiÕu ®­îc chuyÒn vµo cã kiÓu Foo_ptr mµ kh«ng ph¶i kiÓu const Foo_ptr& v× IDL cung cÊp mét ho¹t ®éng khai b¸o kh«ng ®­îc hiÖu chØnh tr¹ng th¸i cña ®èi t­îng, nãi c¸ch kh¸c IDL lµ ng«n ng÷ khai b¸o nã kh«ng phô thuéc vµo ng«n ng÷ lËp tr×nh cô thÓ nµo, v× vËy tr¹ng th¸i cña ®èi t­îng kh«ng ®­îc chØ ®Þnh trong IDL. Bëi v× trong tham chiÕu ®èi t­îng ®­îc truyÒn bëi trÞ. 7. Ph¸t sinh ngo¹i lÖ 7.1 Ph¸t sinh c¸c ngo¹i lÖ. B¹n cÇn chó ý r»ng ph­¬ng thøc servant chØ ®­îc phÐp ®­a ra c¸c ngo¹i lÖ cã trong danh s¸ch c¸c ngo¹i lÖ ®· ®­îc chØ ®Þnh. §iÒu nµy bao gåm tÊt c¶ c¸c ngo¹i lÖ cña hÖ thèng CORBA bëi v× líp c¬ së CORBA::SystemException cã trong tÊt c¶ c¸c ngo¹i lÖ servant. Khi ®ang ®­îc thùc hiÖn C++ b¶o vÖ ph­¬ng thøc servant khái bÊt cø ngo¹i lÖ nµo kh«ng cã trong danh s¸ch chØ ®Þnh cho dï ngo¹i lÖ ®ã ®­îc ®­a ra trùc tiÕp hay gi¸n tiÕp tõ ph­¬ng thøc servant. §Ó ®¶m b¶o c¸c ngo¹i lÖ ®­îc ®­a ra tõ c¸c servant, ORB vµ skeleton ph¶i chøa tÊt c¶ c¸c lêi gîi servant trong khèi catch ®Ó bÉy c¸c ngo¹i lÖ CORBA hoÆc kh«ng ph¶i CORBA. TÊt c¶ c¸c ngo¹i lÖ ph¶i ®­îc ®­a ra b»ng ph­¬ng thøc servant bao gåm ngo¹i lÖ CORBA do ng­êi dïng ®Þnh nghÜa vµ ngo¹i lÖ chung cña C++ ®­îc b¾t bëi CORBA vµ bÞ chuyÓn thµnh ngo¹i lÖ. 7.2 C¸c ngo¹i lÖ hÖ thèng (System Exception) Ph­¬ng thøc servant cã thÓ nÐm ngo¹i lÖ CORBA: BAP_PARAM 1 trong c¸c tham sè cã gi¸ trÞ kh«ng mong ®îi hoÆc viÖc nÐm ngo¹i lÖ CORBA: NO_MEMORY ®Ó b¸o r»ng viÖc cÊp ph¸t cho tham sè cã ®é dµi thay ®æi kh«ng thµnh c«ng. Tuy nhiªn ORB còng sö dông nh÷ng ngo¹i lÖ nµy ®Ó b¸o lçi lµ nã xung ®ét trong khi cè g¾ng nhËn yªu cÇu hoÆc tr¶ lêi yªu cÇu. Khi client b¾t lçi hÖ thèng cña CORBA trong tr­êng hîp ®ã, nã kh«ng biÕt ®©u lµ nguyªn nh©n bëi CORBA thay viÖc thi hµnh servant. §Ó tr¸nh lén xén gi÷a ORB vµ servant. B¹n nªn tr¸nh trùc tiÕp nÐm ngo¹i lÖ ….CORB thay vµo ®ã nªn sö dông ngo¹i lÖ ng­êi dïng ®Þnh nghÜa ®Ó b¸o lçi . §iÒu nµy dÉn ®Õn b¹n ph¶i xem xÐt c¸c kh¶ n¨ng g©y lçi khi thiÕt kÕ giao tiÕp IDL vµ khai b¸o c¸c lçi ®ã trong mçi mÖnh ®Ò raise Trªn mét bé ®iÒu hîp ®èi t­îng yªu cÇu 1 ®èi t­îng mµ nã kh«ng tån t¹i th× øng dông sÏ chê ®îi mét ngo¹i lÖ …. 7.3 Qu¶n lÝ bé nhí vµ ngo¹i lÖ Khi ph­¬ng thøc servant lo¹i bá mét ngo¹i lÖ ORB sÏ gi¶i phãng bÊt cø vïng nhí nµo mµ nã cÊp ph¸t cho tham sè vµo vµ ra, …. Cã tham sè ra vµ gi¸ trÞ tr¶ vÒ vµ s¾p xÕp c¸c ngo¹i lÖ cho ®Ó tr¶ vÒ client. V× vËy ph­¬ng thøc servant ph¶i cÈn thËn gi¶i phãng vïng nhí mµ nã ®· cÊp ph¸t cho tham sè ra hoÆc gi¸ trÞ tr¶ vÒ mµ kh«ng bÞ ph©n kho¶ng bé nhí. Sö dông kiÓu _var trong c¸c ph­¬ng thøc servant ®Ó qu¶n lý cÊp ph¸t ®éng c¸c thÓ hiÖn cho ®Õn khi chóng tr¶ vÒ gi¸ trÞ cho ng­êi gäi kh«ng g©y rß rØ tµi nguyªn chóng nhËn ®­îc 8 Tie classes C¸c líp skeleton thõa kÕ tõ c¸c giao diÖn líp servant göi ®i c¸c yªu cÇu tíi ORB hoÆc POA. Sö dông sù thõa kÕ cña class form thuéc Adapter pattern. Trong phÇn nµy chóng ta chØ sö dông c¸c skeleton ®Ó nhËn biÕt class form cña Adapter pattern. §Ó hoµn thµnh chóng ta ph¶i chØ ra c¸c líp servan mµ cung cÊp c¸c form kh¸c cña Adapter pattern, b»ng viÖc gäi object form ®­îc t¹o ra tõ tr×nh dÞch IDL. ViÖc tù ®éng t¹o ra c¸c líp servant nµy gäi lµ tie classes Néi dung cña Tie classes: Mét tie class lµ mét líp mÉu cña C++ mµ b¹n ph¶i thùc hiÖn ®Ó t¹o ra mét servant cô thÓ. Mét tie-based servant cµi ®Æt tÊt c¶ c¸c ph­¬ng thøc b»ng viÖc uû quyÒn tíi ®èi t­îng kh¸c cña C++. §Ó sö dông mét tie class ta thùc hiÖn c¸c b­íc sau: Thi hµnh mét b¶n mÉu víi mét kiÓu líp mµ øng dông hµm thµnh viªn get_value T¹o mét thÓ hiÖn cña mÉu tÇng thi hµnh ®ã truyÒn cho hµm t¹o mét con trá hoÆc mét tham chiÕu tíi kiÓu líp tham chiÕu. ThÓ hiÖn cña líp tham chiÕu mÉu nµy ®­îc gäi lµ tie object. §¨ng ký tr­êng hîp nµy víi POA nh­ lµ mét servant cña ®èi t­îng CORBA. Khi POA gäi hµm get_value cña tie servant nã sÏ thiÕt lËp mét tie object vµ gióp viÖc qu¶n lý bé nhí cña nã. 9. Tæng kÕt Chóng ta ®· giíi thiÖu toµn bé vÒ viÖc thi hµnh CORBA server. MÆc dï c¸c vÝ dô tr×nh bµy trong phÇn nµy lµ c¸c ¸p dông thùc tÕ vµ chóng ta ®· thÓ hiÖn ®­îc quy t¾c sö dông POA vµ c¸ch cµi ®Æt CORBA object servant nh­ thÕ nµo trong C++. Tãm l¹i ta cÇn chó ý c¸c ®iÓm sau Server kh«ng bao giê yªu cÇu thi hµnh c¸c chi tiÕt cô thÓ d­íi c¸c giao thøc m¹ng ch¼ng h¹n chóng ta kh«ng ph¶i x¸c nhËn tªn m¸y hoÆc më mét TCP socket, l¾ng nghe c¸c th«ng ®iÖp vµo trªn cæng vµo cña m¹ng MÆc dï bªn ohÝa client sö dông m¸y kh¸c víi server c¸c ph­¬ng thøc cµi ®Æt trªn IDL kh«ng cÇn ph¶i thay ®æi. LuËt qu¶n lý bé nhí ®èi víi c¸c tham sè vµ gi¸ trÞ tr¶ vÒ ®­îc ®Þnh danh bªn phÝa client ®­îc gäi tõ xa hoÆc ®­îc tÝch hîp l¹i. B¹n kh«ng cÇn ph¶i lo l¾ng vÒ ng«n ng÷ lËp tr×nh cµi ®Æt trªn phÝa client hoÆc kiÕn tróc phÇn cøng hoÆc c¸c hÖ ®iÒu hµnh ch¹y trªn m¸y ®ã. Ng«n ng÷ ®Æc t¶ IDL ®· lµm nhiÖm vô chuyÓn ®æi mét c¸ch linh lo¹t gi÷a c¸c ng«n ng÷ ®ã miÔn lµ c¸c cµi ®Æt nµy tu©n theo ®Æc t¶ IDL MôC LôC Trang Lêi nãi ®Çu 1 I. ¸nh x¹ tõ IDL sang C++ 2 1. Giíi thiÖu 2 2. ¸nh x¹ cho tªn 2 3. Ánh x¹ c¸c kiÓu d÷ liÖu c¬ b¶n 3 4. Ánh x¹ c¸c kiÓu d÷ liÖu phøc 3 II. ¸nh x¹ phÝa server 16 1 . Më ®Çu 16 2 . ¸nh x¹ c¸c giao tiÕp 16 3. C¸c líp servant 17 4. H×nh thành ®èi t­îng 19 5. Server main 20 6. Quy t¾c chuyÒn tham sè 21 6.1. TruyÒn tham sè kiÓu ®¬n gi¶n. 22 6.2 TruyÒn tham sè ®èi víi kiÓu d÷ liÖu phøc t¹p cã ®é dµi cè ®Þnh. 23 6.3 TruyÒn tham sè m¶ng víi sè phÇn tö cè ®Þnh 24 6.4 TruyÒn tham sè string vµ wide string 26 6.5 TruyÒn tham sè kiÓu phøc t¹p cã ®é dµi thay ®æi vµ kiÓu any 28 6.6 TruyÒn tham sè m¶ng víi c¸c thµnh phÇn cã ®é dµi thay ®æi 29 6.7 TruyÒn tham sè tham chiÕu ®èi t­îng 31 7. Ph¸t sinh ngo¹i lÖ 34 7.1 Ph¸t sinh c¸c ngo¹i lÖ. 34 7.2 C¸c ngo¹i lÖ hÖ thèng 35 7.3 Qu¶n lÝ bé nhí vµ ngo¹i lÖ 35 8. Tie classes 35 9 . Tæng kÕt 36 Môc lôc 37

Các file đính kèm theo tài liệu này:

  • doc77351.DOC
Tài liệu liên quan