DCOM(Distributed COM)
Presenter:
資管研一 R89725009 呂江麟 資管研一 R89725037 劉英和大綱
Component Object Model
Distributed COM
DCOM Example With MFC
SAP:
Component Object Model
COM – 軟體之間提供服務的一種標準方式
COM 是一組規格:
描述 COM 元件建立時所必須遵守的準則
COM 是一組服務:
COM 函式庫提供支援此規格的服務或 API
物件導向:識別碼、狀態、行為
位置通透性
相同行程 (in-process server)COM 的基本理念
組裝軟體 : Componentware
COM 的承諾
以機器碼而非原始碼的重複使用方式
語言獨立性
位置通透性
COM 介面
定義了其他軟體或元件可以使用的公用功能
一個 COM 介面必須滿足下列要求
唯一的識別碼: IID ( Interface ID)
衍生自 IUnknown 介面
一旦出版之後,便不允許更改
介面並不是一個類別
IUnknown 介面
QueryInterface :
查詢物件是否有支援特定的介面
AddRef 與 Release
進行物件生命週期的管理,當參考計
數( Reference Count) 的值為 0 時,物
件就知道沒有任何一個客戶端使用到自
己,便能夠將自己毀滅,
COM 元件的型態
視程式碼模組的結構以及元件與使用元件的
用戶端處理程序之間的關係而定,元件可
分
為以下三種型態:
- 行程內 (In Process)
- 本機 (Local)
- 遠端 (Remote)
行程內( In-Process )
行程內( In-Process )
In-Process Server : DLL 型式
執行時,將
DLL 載入記憶體區塊
容錯能力較差
執行於同一個
Process ,沒有安
全機制
本機(
Local )
本機(
Local )
通常實作成
EXE 型式
不同行程,彼此不會互相干擾
Proxy-> Marshaling->IPC (inter-process
communication)->Un-marshaling->Stub
遠端(
Remote )
遠端(
Remote )
Client 端與 Server 端必須包含相對應
的
proxy/stub 進行 marshaling
RPC ( Remote Procedure Call) 溝通
Server 端可為 DLL 型式或 EXE 型式
(若為
DLL ,則需要 Server 的代理
行程,
COM 系統函式庫( COM Librar
y )
COM 系統層級的程式碼 :COM 的建置是包
含在 COM 系統函式庫中的。這項建置透
過一個 DLL 提供,這個 DLL 包含下列 COM
的規格中所提到的要件:
- 基本的 API 函數
- 建置找尋服務
- 透明化的遠端程序呼叫
- 控制記憶體的配置
介面定義語言( Interface Definition Lan
guage )
不需要任何的物件實作碼
MIDL ( Microsoft IDL 編譯器)
Proxy/Stub
DLL :
Proxy 和 stub 會被包在一個 proxy/stub D
LL 中,這個 DLL 包含客戶端 proxy 與伺服
器 stub 的程式碼 。當在不同的電腦上執
行客戶端與伺服器時,必須保證 proxy/st
ub DLL 同時安裝及登錄在這兩台電腦 。
COM 物件的重複使用機制
COM 物件的重複使用機制
使用
使用
Visual Basic
Visual Basic
呼叫
呼叫
Exce
Exce
l
l
Dim objDim objSet obj = CreateObject(
Set obj = CreateObject(““Excel.ApplicationExcel.Application””)) obj.visible = true obj.visible = true obj.Workbooks.Add obj.Workbooks.Add obj.Range("B3").Select obj.Range("B3").Select obj.ActiveCell.FormulaR1C1 = "12" obj.ActiveCell.FormulaR1C1 = "12" obj.Range("B4").Select obj.Range("B4").Select obj.ActiveCell.FormulaR1C1 = "34“
COM 如何找出 Excel 的位置?
使用 RegEdit.exe 登錄編輯器
HKEY_CLASSES_ROOT CLSID {00024500-0000-000…} LocalServer32 = excel.exe Excel.Application CLSID = {00024500-0000-000…} Excel.Application : ProgIDCOM Runtime
COM Runtime [D]COM Registry Pluggable Security (SSPI) NTLM DCE MS-RPC 核心服務(Monikers, Storage, Data Transfer,...)
元件和應用程式
Core COM Services
Security
Lifecycle
Management
Type Information
(Interface
Repository)
Monikers (Naming)
Automation (Dynamic
Invocation)
Data Transfer
Component
Categories
Registry
COM Runtime Architecture
Flexible and extensible
Pluggable Transports
COM COM Client Client Component C O M R un ti m e Server Machine Client Machine TCP, UDP SPX,IPX Net BUI HTTP “Falcon” C O M R un ti m e ProxyCOM Runtime Architecture
Flexible and extensible
Pluggable Security Providers
COM COM Client Client Component C O M R un ti m e Server Machine Client Machine DCE NT Kerberos SSL, Certs. NTLM C O M R un ti m e Proxy
COM
COM
程式設計模型
程式設計模型
用戶端行程 用戶端行程用戶端程式
OLE32.DLL OLE32.DLLCOM
COM
程式設計模型
程式設計模型
用戶端行程 用戶端行程用戶端程式
元件行程 元件行程 Object Object OLE32.DLL OLE32.DLL OLE32.DLL OLE32.DLL元件行程 元件行程
COM
COM
程式設計模型
程式設計模型
Object Object 用戶端行程 用戶端行程 stub proxy用戶端程式
OLE32.DLL OLE32.DLL OLE32.DLL OLE32.DLL元件行程 元件行程
COM
COM
程式設計模型
程式設計模型
Object Object 用戶端行程 用戶端行程 stub proxy用戶端程式
OLE32.DLL OLE32.DLL OLE32.DLL OLE32.DLL元件行程 元件行程
COM
COM
程式設計模型
程式設計模型
Object Object 用戶端行程 用戶端行程 stub proxy用戶端程式
OLE32.DLL OLE32.DLL OLE32.DLL OLE32.DLLCOM 的
攔截機制
Distributed COM
Just COM “with a longer wire”
All COM components communicate in the
same way
on the same machine
In-process, Out-of-process
across a Local Area Network across a Wide Area Network across the Internet
Distributed COM
Wire Protocol
Based on DCE RPC Specification
Interoperable with OSF DCE RPC implementatio
ns
We call it “ORPC”
指定元件的伺服器的位置
COM 如何找到啟動遠端伺服器的資訊?
又是 RegEdit.exe !
HKEY_CLASSES_ROOT
AppID {00024500-0000-000…} RemoteServerName = jackyDCOM 的物件啟動
元件行程 元件行程 Object Object 用戶端行程 用戶端行程 stub proxy用戶端程式
OLE32.DLL OLE32.DLL OLE32.DLL OLE32.DLL SCM SCM SCM SCMCOM 物件的安全模型
設定方式:
宣告式安全設定:於元件外部的登錄
(
registry )中設定
程式控制安全設定:由程式設計者加進元件
宣告式安全設定:
預設安全(
default security ) : 指定所有在本
機上執行的元件之安全設定值
元件安全( component security ):提供特
別的安全性給一個特定的元件
To implement a class using MFC’s interface maps follows these steps :
1.Use Derive a class either directly or indirectly from CCmdTarget.
2.Use the DECLARE_INTERFACE_MAP function in the derived class definition.
3.For each interface you wish to support, use the BEGIN_INTERFACE_PART 、
END_INTERFACE_PART
4.In the implementation file, use the BEGIN_INTERFACE_MAP
and END_INTERFACE_MAP macros to define the class's interface map.
5.For each IID supported, use the INTERFACE_PART macro between the BEGIN_INTERFACE_MAP and
END_INTERFACE_MAP macros to map that IID to a specific "part" of your class.
6.Implement each of the nested classes that represent the interfaces you support.
7.Use the METHOD_PROLOGUE macro to access the parent, CcmdTarget-derived object.
8.AddRef, Release, and QueryInterface can delegate to the CcmdTarget implementation of these functions :
ExternalAddRef, ExternalRelease, and ExternalQueryInterface.
Macro of MFC Implementation(1)
BEGIN_INTERFACE_PART(localClass, iface);END_INTERFACE_PART(localClass)
localClass :實作 interface 的 class
iface : class 實作的 interface
用來產生巢狀類別,它會把
X 加到第一個參數
Macro of MFC Implementation(2)
DECLARE_INTERFACE_MAP 產生一個表格的宣告,這個表格內含所有類別的介面 識別碼 BEGIN_INTERFACE_MAP(theClass, baseClass) END_INTERFACE_MAPtheClass :要建立 interface 的 class baseClass :該 class 所繼承的類別
Macro of MFC Implementation(3)
STDMETHOD_
在宣告敘述
(*.h file) 中,宣告 method 。
STDMETHODIMP_
在
implement 中 (*.cpp) ,定義 method 。
此兩巨集將傳回值指定為第一個參數。Macro of MFC Implementation(4)
STDMETHOD
在宣告敘述
(*.h file) 中,宣告 method 。
STDMETHODIMP
在
implement 中 (*.cpp) ,定義 method 。
此兩巨集採用型態為 HRESULT 的傳回值。METHOD_PROLOGUE
傳回父類別的指標,且存於 pThis 這個指標中。
CLASS FACTORY(1)
A COM object that implements the
IClassFactory interface and that creates
CLASS FACTORY(2)
IClassFactory 介面:
衍生自
IUnknow 介面,主要 member function
為:
virtual BOOL CreateInstance(int& nlid,
void** ppvObj)
= 0
CLASS FACTORY(3)
Why Class Factory ?
因為不能直接
call target class 的 constructor
,則
object 的設置和啟動是透過 Class Factory
來作。
介面宣告
Interface.h
struct Isum : public IUnknown
{
STDMETHOD_(void, Sum) (int x,int y,
int *revtal) = 0;
};
由
CcmdTarget 類別 derived 下來
的
元件類別
test.h
class CTest : public CCmdTarget
{
protected:
BEGIN_INTERFACE_PART(Sum, ISum)
STDMETHOD_(void, Sum) (int x,int y,int *revtal);
END_INTERFACE_PART(Sum)
DECLARE_INTERFACE_MAP() };
類別
implement test.cpp(1)
#include "Interface.h" #include "test.h“
static const IID IID_ISum =
{ 0x692d03a4, 0xc689, 0x11ce,
{ 0xb3, 0x37, 0x88, 0xea, 0x36, 0xde, 0x9e, 0x4e } };
BEGIN_INTERFACE_MAP(CTest, CCmdTarget) INTERFACE_PART(CTest, IID_ISum, Sum)
類別
implement test.cpp(2)
STDMETHODIMP_(ULONG) CTest::XSum::AddRef() { METHOD_PROLOGUE(CTest, Sum) return pThis->ExternalAddRef(); } STDMETHODIMP_(ULONG) CTest::XSum::Release() { METHOD_PROLOGUE(CTest, Sum) return pThis->ExternalRelease();類別
implement test.cpp(3)
STDMETHODIMP CTest::XSum::QueryInterface( REFIID iid, LPVOID* ppvObj){
METHOD_PROLOGUE(CTest, Sum)
return pThis->ExternalQueryInterface(&iid, ppvObj); }
STDMETHODIMP_(void) CTest::XSum::Sum(int x,int y,int *revtal)
{
用戶端程式
(1) :
LPCLASSFACTORY pClf; LPUNKNOWN pUnk; ISum* pSum; Imultilpy *pMul HRESULT hr; CLSID clsid; if ((hr = ::CLSIDFromProgID(L"Test", &clsid)) != NO ERROR) {用戶端程式
(2) :
if((hr=::CoGetClassObject(clsid,CLSCTX_REMOTE_SERV ER, NULL, IID_IClassFactory, (void **) &pClf)) != NO ERROR)
{;
return; }
pClf->CreateInstance(NULL, IID_IUnknown, (void**) & pUnk);
用戶端程式
(3) :
int sum;
pSum->Sum(4,5,&sum);
pClf->Release();
pUnk->Release();
pSum->Release();
DCOM Component Connector
DCOM Component Connector
由
SAP 與 Microsoft 共同利用 DCOM 研
發出來的架構,可以讓由
SAP 或其他公司所提供
的
components 完美、緊密地的結合;而且藉由先
前定義好的界面,可以輕易地昇級系統的某個元
件
(component) ,而不是一次就須換整個系統。
使用
使用 DCOM Component ConnectorDCOM Component Connector 的好處的好處 (1)(1)
A new dimension of openness
透過定義良好的 interface 可輕易地補強和擴充
Leverage existing programming skills
未來的補強工具可在 SAP tools 和 COM tools 之間作 選擇
使用
使用
DCOM Component Connector
DCOM Component Connector
的好處
的好處
(1)
(1)
Eased integration
因為使用了 DCOM ,與其他產品的整合變得容易 甚至可以使用多種不同的 DataBases
Evolutionary approach