quá trình ánh xạ (mapping) từ ngôn ngữ đặc tả sang ngôn ngữ cài đặt.doc.DOC

36 1.1K 0
quá trình ánh xạ (mapping) từ ngôn ngữ đặc tả sang ngôn ngữ cài đặt.doc.DOC

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

quá trình ánh xạ (mapping) từ ngôn ngữ đặc tả sang ngôn ngữ cài đặt.

Trang 1

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 nhng đó 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

Trang 2

I ánh xạ từ IDL sang C++ 1 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 nhng 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ễ

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 };

Trang 3

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:

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

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

Trang 4

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:

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:

Trang 5

Đố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

d> Union

Trang 6

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;

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; .

};

Trang 7

e> 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 {

Trang 8

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

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);

Trang 9

Phương thứcMô 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

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ả.

Trang 10

• 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.

h> 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 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

Trang 11

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

static NonExist * _narrow(CORBA::Exception_ptr); NonExist (ID _BadId);

NonExist ();

NonExist (const NonExist &); ~NonExist ();

Trang 12

NonExist & operator=(const NonExist &);

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.

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

Kiểu tham chiếu đối tượng (INTF_ptr)

Kiểu biến tham chiếu đối tượng (INTF_var)

Trang 13

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.

Trang 14

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

Trang 15

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 trng 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 nhng 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

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.

Trang 16

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.

2 á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 nhng 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 {

- 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

Trang 17

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.

MyObject_impl(const MyObject_impl &); Void operator=(const MyObject_imple &); };

Có vài đIểm quan trọng cần lu ý 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.

Trang 18

- 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à cha đầ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

Ngày đăng: 10/09/2012, 09:25

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan