Bài giảng Hệ thống điều khiển phân tán - Hoàng Minh Sơn
Tóm tắt Bài giảng Hệ thống điều khiển phân tán - Hoàng Minh Sơn: ...Các loại bus trường được hỗ trợ mạnh nhất là Profibus-DP, Foundation Fieldbus, DeviceNet và AS-I. Trong môi trường đòi hỏi an toàn cháy nổ thì Profibus-PA và Foundation Fieldbus H1 là hai hệ được sử dụng phổ biến nhất. Một trạm vào/ra từ xa thực chất có cấu trúc không khác lắm so với một t...ược đặt trong phòng điều khiển trung tâm với điều kiện môi trường làm việc tốt. Mặt khác, trên thị trường cũng đã có rất nhiều loại máy tính cá nhân công nghiệp, đảm bảo độ tin cậy cao không kém một PLC. Một khi máy tính chỉ được cài đặt hệ điều hành và phần mềm điều khiển thì khả năng gây l...tích, giải thuật được phân chia thành các giải thuật con đơn giản hơn, cấu trúc dữ liệu lớn được chia thành những cấu trúc nhỏ hơn. Quá trình tương tự cũng được tiến hành trong quá trình thiết kế. Phương pháp phân tích, thiết kế hướng thủ tục hoặc hướng dữ liệu có ưu điểm đơn giản, nhanh c...
ể vẫn đòi hỏi phải lập trình phía client (một đối tượng phân tán hoặc một chương trình ứng dụng thông thường). Ngày nay, đối tượng phân tán và phần mềm thành phần đã gặp nhau ở nhiều điểm, ví dụ trong công nghệ COM/DCOM/ActiveX. Nói tóm lại, một đối tượng phân tán là một đối tượng phần mềm trong một hệ thống phân tán, có thể được sử dụng bởi các chương trình ứng dụng hoặc các đối tượng khác thuộc cùng một quá trình tính toán, thuộc một quá trình tính toán khác hoặc thuộc một trạm khác trong mạng theo một phương thức thống nhất thông qua giao tiếp ngầm (không để ý tới giao thức truyền thông cụ thể, trong suốt với hệ điều hành, kiến trúc phần cứng và hệ thống mạng). Một đối tượng phân tán có các thuộc tính có thể truy cập được từ xa, có các phép toán có thể gọi được từ xa. Mỗi đối tượng phân tán (distributed object) - bất kể dạng thực hiện, nền triển khai và vị trí cài đặt - đều có căn cước phân biệt và có thể được sử dụng như các đối tượng nội trình (in-process object). Lợi thế quyết định ở đây là việc tạo dựng một ứng dụng phân tán được thực hiện ở mức trừu tượng cao hơn so với kiểu lập trình mạng cổ điển, nhờ vậy trên nguyên tắc không khác biệt so với tạo dựng một ứng dụng đơn độc (stand-alone application). Để đạt được điều đó, ta cần sự hỗ trợ hữu hiệu của một phần mềm khung (framework). Hiện nay có hai mô hình chuẩn cho những công trình khung đó là DCOM và CORBA. CORBA cho phép sử dụng một cách rộng rãi và linh hoạt hơn, trong khi DCOM hiện nay hầu như chỉ sử dụng được trên các hệ Microsoft Windows (95, 98, NT, 2000). © 2005, Hoàng Minh Sơn 38 6 KIẾN TRÚC ĐỐI TƯỢNG PHÂN TÁN Một kiến trúc đối tượng phân tán định nghĩa mô hình các đối tượng phân tán, mô hình giao tiếp và chuẩn giao tiếp giữa các đối tượng phân tán. 6.1 Yêu cầu chung Một kiến trúc đối tượng phân tán tạo điều kiện cho việc lập trình ở một mức trừu tượng cao hơn so với phương pháp hướng đối tượng cổ điển. Cụ thể, điểm khác biệt so với lập trình hướng đối tượng cổ điển nằm ở “tính trong suốt phân tán” (distribution transparency), thể hiện qua các đặc tính sau: • Trong suốt vị trí: Một client không cần biết rằng đối tượng server nằm trong cùng một quá trình tính toán, thuộc một quá trình tính toán khác trên cùng một trạm hoặc trên một trạm khác, cách sử dụng đối tượng server là thống nhất. Ngược lại cũng vậy. • Trong suốt thể hiện: Client không cần quan tâm tới việc đối tượng server được thể hiện bằng ngôn ngữ lập trình nào và bằng phương pháp nào, mà chỉ cần quan tâm tới giao diện để có thể sử dụng. • Trong suốt nền: Một client không cần biết rằng đối tượng server nằm trên hệ điều hành nào, trên nền máy tính kiến trúc ra sao. • Trong suốt truyền thông: Mã thực hiện client và các đối tượng server không liên quan tới mạng truyền thông và giao thức truyền thông cụ thể· 6.2 Các mẫu thiết kế Để đáp ứng các yêu cầu trên, người ta thường áp dụng các mẫu thiết kế sau đây: • Proxy: Một đối tượng đại diện cho server bên phía client, để client có thể sử dụng đối tượng server đơn giản như với một đối tượng nội trình (ví dụ thông qua con trỏ). • Broker: Bộ phận che dấu chi tiết về cơ chế truyền thông cụ thể, tạo điều kiện cho client/proxy và server giao tiếp với nhau mà không phụ thuộc vào nền và hệ thống truyền thông bên dưới. Broker có mặt cả bên client và server. • Adapter: Đối tượng trung gian, có vai trò thích ứng giao diện giữa broker và server, tạo điều kiện cho việc phát triển server một cách độc lập, cũng như sử dụng các server có sẵn (chưa tuân theo kiến trúc đối tượng phân tán). • Marshaling/Unmarshaling: Cơ chế thực hiện mã hóa và đóng gói các lời gọi hàm bên client thành các bức điện tương ứng với cơ chế truyền thông cấp thấp, cũng mở gói và giải mã các bức điện thành lời gọi hàm chi tiết bên đối tượng server. Các phương thức tương tự cũng được thực hiện để © 2005, Hoàng Minh Sơn 39 chuyển kết quả từ server trở lại client. Các nhiệm vụ này do proxy, server hoặc/và adapter đảm nhiệm. • Interface Mapping: Giải quyết vấn đề trong suốt thể hiện bằng cách mô tả các giao diện bằng một ngôn ngữ độc lập IDL (Interface Description Language) và cho phép ánh xạ sang thực hiện bằng một ngôn ngữ cụ thể. Hình 6-1: Các mẫu thiết kế giao tiếp giữa client và ₫ối tượng server 6.3 Giới thiệu chuẩn CORBA Chuẩn CORBA [4] do tổ chức OMG (Object Management Group) quản lý và phát triển. Đây là hiệp hội lớn nhất của các nhà phát triển, sản xuất và ứng dụng phần mềm trên thế giới, hiện nay có gần 1.000 thành viên. Chuẩn CORBA đưa ra một kiến trúc đối tượng phân tán cùng với các đặc tả ứng dụng cho nhiều lĩnh vực khác nhau, nhiều nền khác nhau và nhiều ngôn ngữ lập trình khác nhau. Vì tính trung lập của nó, CORBA được hỗ trợ rất rộng rãi, đặc biệt trong các hệ thống thông tin thương mại, phần mềm giao dịch kinh doanh và dịch vụ viễn thông. Tuy nhiên, cũng do tính độc lập của nó dẫn đến nhiều lý do mà CORBA không thực sự mạnh ở các hệ thống ứng qui mô vừa và nhỏ. Hình 6-2 minh họa cấu trúc mô hình CORBA, trong đó bộ phận trừu tượng trung gian mang tên Object Request Broker (ORB) giữ vai trò quan trọng nhất (broker). ORB cho phép khách hàng (client) sử dụng dịch vụ của đối tượng phục vụ (server) mà không cần biết cụ thể dạng thực hiện, nền triển khai và vị trí cài đặt của đối tượng phục vụ. Kiến trúc ở đây được thực hiện theo các mẫu thiết kế đã trình bày trong phần trước. Process B Process A client proxy adapter 1: op ( ) broker_A broker_B 2: marshal ( ) 3: dispatch( ) IPC server 4: upcall( ) 5: op( ) © 2005, Hoàng Minh Sơn 40 Hình 6-2: Cấu trúc mô hình CORBA 6.4 Giới thiệu chuẩn COM/DCOM COM (Component Object Model) là một mô hình đối tượng thành phần, một mô hình cơ sở cho nhiều công nghệ phần mềm quan trọng của hãng Microsoft. COM định nghĩa chuẩn nhị phân và đặc tả kết nối cho việc tương tác giữa các thành phần của một phần mềm với một thành phần khác trên cùng một quá trình tính toán, trên nhiều quá trình khác nhau hay trên các máy tính riêng biệt. Hãng Microsoft cũng hy vọng một ngày không xa COM cũng được sử dụng phổ biến trên các nền phần cứng và hệ điều hành khác nhau. COM là một mô hình lập trình cơ sở ₫ối tượng thiết kế để nâng cao sự tương tác giữa các thành phần phần mềm, nghĩa là, cho phép hai hoặc nhiều ứng dụng hay các thành phần dễ dàng giao tiếp với nhau cho dù chúng được viết bởi nhiều người khác nhau trong những khoảng thời gian khác nhau, bằng nhiều ngôn ngữ lập trình khác nhau thậm chí chạy trên các máy tính khác nhau, không hay cài đặt cùng một hệ điều hành. Để thực hiện điều này, COM định nghĩa và thực thi các kỹ thuật cho phép các ứng dụng kết nối với nhau như các ₫ối tượng phần mềm. Nói cách khác, COM đưa ra một mô hình tương tác mà qua đó một khách hàng (client) có thể kết nối với các nhà cung cấp dịch vụ (object) đó một cách thuận tiện. Với COM, các ứng dụng kết nối với nhau và với hệ thống qua các tập hợp của các lời gọi hàm - xem như là các phương thức hay những hàm thành viên, còn gọi là giao diện. Theo cách tư duy COM, một giao diện là một “quy ước” kiểu mạnh giữa các thành phần phần mềm nhằm cung cấp những liên quan dù nhỏ nhưng hữu dụng tập các thao tác liên quan danh nghĩa. Một đối tượng được định nghĩa phù hợp với COM là một sự thể hiện đặc biệt của đối tượng. Một đối tượng COM giống như một đối tượng C++ nhưng khác ở chỗ một client không truy nhập trực tiếp vào đối tượng COM mà sẽ qua các giao diện mà đối tượng cung cấp. Object Request Broker Core Dynamic Invocation IDL Stubs ORB Interface Static IDL Skeleton Dynamic Skeleton Object Adapter Client Object Implementation © 2005, Hoàng Minh Sơn 41 6.4.1 Giao diện Cách duy nhất để truy cập dữ liệu hoặc tác động lên một đối tượng COM là thông qua giao diện của nó. Một giao diện thực chất là một nhóm các hàm có sẵn liên quan với nhau. Có thể so sánh một giao diện với một lớp cơ sở trừu tượng chỉ gồm các hàm thuần ảo trong ngôn ngữ C++. Giao diện định nghĩa cú pháp các hàm thành viên, gọi là các phương thức (methods), kiểu trả về, số lượng và các kiểu tham số. Một giao diện không qui định cụ thể các phương thức đó được thực hiện như thế nào. Thực chất việc thể hiện giao diện là sử dụng con trỏ truy nhập vào một mảng các con trỏ khác và các con trỏ này trỏ tới các hàm của giao diện. Thông thường, tên của giao diện được bắt đầu bằng chữ cái I, ví dụ như IUnknown, IData... Định danh thật của giao diện thể hiện ở chỉ danh GUID của nó, còn tên chỉ để thuận tiện cho việc lập trình và hệ thống COM sẽ sử dụng các chỉ danh này khi thao tác trên giao diện. Thêm vào đó, khi giao diện có tên hoặc kiểu cụ thể và tên của các hàm thành viên, nó chỉ định nghĩa làm thế nào một client có thể sử dụng giao diện đó và những đáp ứng mong đợi từ đối tượng qua giao diện đó. Ví dụ, giao diện IStack với hai hàm thành viên PUSH và POP chỉ định nghĩa những thông số và kiểu trả về của hai hàm này và những gì chúng được mong đợi thực hiện từ client. Có thể nói, giao diện là phương tiện để đối tượng đưa ra những dịch vụ của nó. Có bốn điểm quan trọng về giao diện mà ta cần biết: • Một giao diện không phải là một lớp theo định nghĩa lớp thông thường bởi một lớp có thể được thể hiện qua một đối tượng còn một giao diện thì không bởi nó không kèm theo sự thực thi. • Một giao diện không phải là một ₫ối tượng bởi một giao diện chỉ đơn thuần là một nhóm các hàm liên quan và là chuẩn nhị phân mà qua đó client và object có thể giao tiếp với nhau. Còn đối tượng thì có thể thực thi trên nhiều ngôn ngữ với nhiều thể hiện của trạng thái bên trong, và do đó nó có thể cung cấp con trỏ đến các hàm thành viên của giao diện. • Giao diện có kiểu mạnh: Mỗi một giao diện đều có một định danh riêng nên ngăn chặn được khả năng xung đột có thể xảy ra đối với các tên ta đặt cho giao diện. Điều này tăng thêm tính bền vững cho chương trình. • Các giao diện ₫ược phân biệt rõ ràng: Mọi sự thay đổi như thêm hoặc xoá hàm thành viên, thay đổi ngữ nghĩa đều dẫn tới hình thành một giao diện mới và được gán một định danh mới. Do đó giao diện mới và cũ không thể xung đột với nhau cho dù mọi sự thay đổi chỉ đơn thuần là về ngữ nghĩa. 6.4.2 Đối tượng COM Một đối tượng COM có thể được lập trình bằng một ngôn ngữ thông dụng như C, C++ hoặc VB. Một đối tượng có thể cung cấp nhiều giao diện. Tất cả © 2005, Hoàng Minh Sơn 42 các đối tượng COM đều có một giao diện cơ bản là IUnknown. Đây là giao diện cơ sở cho tất cả các giao diện khác trong COM mà mọi đối tượng phải hỗ trợ. Bên cạnh đó, đối tượng cũng có khả năng thực thi nhiều giao diện khác. Các đối tượng với nhiều giao diện có thể cung cấp các con trỏ truy nhập vào nhiều bảng chứa các hàm. Các con trỏ này có thể gọi được con trỏ giao diện. Trong COM, giao diện là một bảng các con trỏ ( giống như vtable trong C++) vào các hàm được thực hiện bởi đối tượng. Hình 6-3: Mô hình một ₫ối tượng COM Trong thực tế, một con trỏ trỏ đến một giao diện là một con trỏ tới một con trỏ trỏ tới bảng các con trỏ vào các hàm thành viên. Tuy nhiên, để tránh cách diễn đạt quanh co này khi nói về giao diện người ta thường sử dụng thuật ngữ con trỏ giao diện để thay thế. Khi đó sự thực thi giao diện đơn giản là dùng con trỏ trỏ tới mảng các con trỏ tới các hàm. Hình 6-4 sau minh họa cho điều này. Giao diện IUnknown Như đã trình bày ở trên, mọi đối tượng COM, không có sự loại trừ, đều hỗ trợ giao diện IUnknown. Giao diện này có ba phương thức AddRef(), Release() và QueryInterface(). Tất cả các giao diện khác đều dẫn xuất từ giao diện IUnknown và đều có các con trỏ đến các phương thức này. Hai phương thức đầu tính toán số đếm tham chiếu để điều khiển thời gian sống của đối tượng. Khi đối tượng được tạo lần đầu, ta cần gọi phương thức AddRef() của đối tượng để tăng số đếm. Khi không còn cần tới đối tượng, ta gọi phương thức Release() để giảm số đếm tham chiếu. Khi người dùng cuối cùng gọi phương thức Release(), số đếm giảm về 0 thì đối tượng sẽ tự huỷ. Đối tượng IUnknown Các giao diện khác B A © 2005, Hoàng Minh Sơn 43 Hình 6-4: Sự thực thi con trỏ giao diện Ta có thể thấy rõ vấn đề hơn qua sự thực thi đơn giản hai phương thức IUnknown::AddRef() và IUnknown::Release() dưới đây: //tăng biến thành viên chứa số đếm tham chiếu ULONG IUnknown::AddRef() { return ++m_RefCount; } //giảm biến chứa số đếm tham chiếu, nếu bằng 0 thì huỷ đối tượng ULONG IUnknown::Release() { --m_RefCout; if (m_RefCount == 0) { delete this; return 0; } return m_RefCount; } Khi ta có một con trỏ đến đối tượng thì thực chất, những gì ta có chỉ là một con trỏ đến một trong số các giao diện của nó, còn đó là giao diện nào thì lại phụ thuộc vào cách mà ta có con trỏ đó. Từ con trỏ vào một giao diện, ta có thể truy cập được con trỏ vào các giao diện khác mà đối tượng hỗ trợ. Đối tượng có thể hoặc không hỗ trợ giao diện mà ta quan tâm, nhưng mọi đối tượng đều được đảm bảo hỗ trợ giao diện Iunknown nên ta có thể yêu cầu các giao diện khác qua phương thức IUnknow::QueryInterface(). Các giao diện được định danh bởi các IIDs (Interface IDs) ví dụ như IID_IUnknown của giao diện IUnknown. Khi ta gọi phương thức QueryInterface(), ta gửi IID của giao diện mà ta cần cho nó và một con trỏ đến tham số đầu ra. Nếu đối tượng hỗ trợ giao diện yêu cầu, nó sẽ trả lại đoạn mã báo thành công S_OK (định nghĩa là 0) và đặt vào tham số đầu ra mà ta cung cấp con trỏ đến giao diện yêu cầu. Nếu đối tượng không hỗ trợ giao diện này nó báo lỗi và đặt tham số đầu ra là NULL. Ta xét một sự thực thi đơn giản sau: HRESULT IUnknown::QueryInterface (REFIID riid , LPVOID * ppv) { //kiểm tra IID xem đối tượng có hỗ trợ giao diện yêu cầu không, pointer Interface Function Table Interface Pointer Pointer to Function1 Function1(...) { ... } Pointer to Function2 Pointer to Function3 ... Function2(...) { ... } Function3(...) { ... } ... © 2005, Hoàng Minh Sơn 44 //nếu hỗ trợ ta tăng số đếm tham chiếu, đưa vào biến đầu ra cung cấp // một con trỏ đến giao diện, và báo rằng đã thành công if (riid == IDD_IUnknow) { AddRef(); *ppv = (LPVOID) this; return S_OK; } //nếu không hỗ trợ giao diện ta đặt biến đầu ra cung cấp là NULL và // trả về một mã thông báo lỗi else { *ppv = NULL; return E_NOINTERFACE; } } Quan hệ giữa ₫ối tượng và các giao diện • Các client chỉ kết nối qua con trỏ tới các giao diện. Khi một client truy nhập vào một đối tượng, client chỉ đơn thuần thông qua con trỏ giao diện. Con trỏ giấu đi nội dung của thao tác bên trong, ta không thể thấy chi tiết về đối tượng mà chỉ có thể thấy thông tin về trạng thái của chúng. • Đối tượng có thể thực thi nhiều giao diện. Một lớp thực thi đối tượng có thể thực thi nhiều giao diện, ví dụ qua phương pháp đa thừa kế. 6.4.3 Giao tiếp giữa client và object Cách thức của sự giao tiếp Trước khi sử dụng một đối tượng COM trong một ứng dụng, ta cần khởi tạo cơ chế COM trong ứng dụng bằng lời gọi CoInitialize(...) và sau đó tạo đối tượng COM mong muốn. Client kết nối với object thông qua con trỏ giao diện và không bao giờ truy nhập trực tiếp vào object. Khi cần sử dụng dịch vụ nào đó của đối tượng, client hiểu rằng nó cần có con trỏ đến một hay nhiều giao diện của đối tượng. Để tạo một đối tượng COM và nhận một con trỏ vào giao diện, ta có thể gọi một trong hai hàm CoCreateInstance() hoặc CoCreateInstanceEx() với các tham số xác định đối tượng. Hình 6-5: Giao tiếp giữa ₫ối tượng và khách hàng Trong một số trường hợp, bản thân client sẽ đóng vai trò một object và cung cấp cho các đối tượng khác những chức năng gọi các sự kiện hoặc đưa ra các dịch vụ của nó. Lúc này client là một đối tượng thực thi còn object là một khách hàng. Client Application Object Interface Pointer © 2005, Hoàng Minh Sơn 45 Hình 6-6: Giao tiếp giữa hai ₫ối tượng Giao tiếp trên cùng một quá trình tính toán Khi client và đối tượng COM cùng nằm trên một quá trình tính toán thì client sẽ kết nối trực tiếp với object qua con trỏ giao diện. Hình 6-7: Giao tiếp giữa ₫ối tượng và khách hàng trên cùng quá trình Giao tiếp liên quá trình Nếu client và object không cùng nằm trên một không gian địa chỉ hay nằm trên các máy tính khác nhau thì COM sẽ thiết lập một đối tượng đại diện (proxy) bên phía client và một đối tượng gốc (stub) bên phía object. Proxy và stub sẽ kết nối với nhau qua kênh giao tiếp (channel). Khi đó, client sẽ thực hiện lời gọi dịch vụ trong không gian địa chỉ của nó tức là giao tiếp trực tiếp với proxy. Proxy sẽ thu thập (marshal) các thông số, gửi chúng đến stub qua kênh giao tiếp. Stub thực hiện lời gọi đến đối tượng dịch vụ, đóng gói kết quả và đưa về cho proxy. Hình 6-8: Giao tiếp giữa ₫ối tượng và khách hàng trên hai quá trình khác nhau Quá trình client client object server Quá trình client client proxy Proxy server COM Engine object Quá trình dịch vụ cục bộ hay từ xa Stub server Object Application Object Application © 2005, Hoàng Minh Sơn 46 6.4.4 Ngôn ngữ mô tả giao diện IDL (Interface Description Language) là một ngôn ngữ kiểu mạnh dùng để mô tả giao diện của đối tượng COM, độc lập với ngôn ngữ lập trình. Cú pháp của ngôn ngữ này không phức tạp so với một ngồn ngữ lập trình. Khi xây dựng một đối tượng COM, ta cần mô tả các phương thức của giao diện bằng cách sử dụng ngôn ngữ này. Sau khi tạp xong file mô tả giao diện này, ta cần lưu nó ở dạng *.idl để chương trình dịch có thể hiểu được. Chương trình dịch (IDL-Compiler) sẽ dịch sang một ngôn ngữ lập trình, ví dụ C++. Khi đó một giao diện sẽ được chuyển sang thực hiện bằng một cấu trúc thích hợp trong ngôn ngữ lập trình, ví dụ một lớp thuần ảo trong C++. 6.4.5 Mô hình đối tượng thành phần phân tán DCOM DCOM (Distributed COM) mở rộng COM cho việc giao tiếp giữa các đối tượng phân tán, thuộc các chương trình chạy trên nhiều máy tính khác nhau trên mạng LAN, WAN hay Internet. Với DCOM, các ứng dụng có thể phân tán trên nhiều vị trí đem lại sự thuận lợi cho chính ứng dụng. Ngày nay khi người ta nói tới COM là cũng thường bao hàm DCOM trong đó. DCOM là một công nghệ lý tưởng cho những ứng dụng nhiều tầng lớp bởi vì nó cho phép những thành phần ActiveX làm việc ngang qua mạng. Nhiều người có thể phát triển thêm cùng một thành phần mà không cần phải lo lắng về lập trình mạng, tính tương thích hệ thống hoặc sự hợp nhất của những thành phần xây dựng từ những ngôn ngữ khác nhau. Nó dẫn tới hạ thấp giá thành và làm giảm sự phức tạp của việc phân tán các ứng dụng thành phần. Hình 6-9: Giao tiếp giữa ₫ối tượng và khách hàng trên hai máy khác nhau với DCOM Client ComponentProxy DCE RPC Protocol Stack Stub DCOM network- protocol Security Provider DCE RPC Protocol Stack Security Provider SCM SCM COM Runtime CoCreateInstance() (Remote) Activation CoCreateInstance() © 2005, Hoàng Minh Sơn 47 Khi các đối tượng ở trên các máy tính khác nhau, DCOM đơn giản thực hiện sự thay thế truyền thông liên quá trình cục bộ bởi giao thức mạng. Hình dưới đây minh họa rõ nét cách thức giao tiếp giữa các đối tượng nằm trên hai máy tính khác nhau. Thư viện COM Run-Time cung cấp những dịch vụ hướng đối tượng tới khách hàng và thành phần muốn giao tiếp với nhau đồng thời sử dụng RPC và nhà cung cấp an toàn để tạo chuẩn nối mạng đóng gói tuân theo giao thức truyền thông cho DCOM. Một ứng dụng client có thể tạo một đối tượng trên một máy tính khác qua hàm API CoCreateInstance(). Ta xét một ví dụ đơn giản sau: HRESUL hr = CoCreateInstance( CLSID_CData, // định danh lớp của đối tượng yêu cầu NULL, CLSCTX_REMOTE_SERVER, // dịch vụ từ xa được yêu cầu &si); // tham số đầu ra để chứa con trỏ giao diện
File đính kèm:
- bai_giang_he_thong_dieu_khien_phan_tan_hoang_minh_son.pdf