程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> COM編程—EXE中的服務器

COM編程—EXE中的服務器

編輯:關於C語言
 

我們之前總結的很多東西,甚至是提供的DEMO程序都是基於進程中服務器的,也就是生成的COM組件的形式為DLL。但是,有的時候,我們可能需要使組件是以EXE的形式發布。這樣就會出現另一個問題,不同EXE中的組件和客戶將在不同的進程中運行,這是因為每一個EXE都有其自己的進程空間。這樣一來客戶和組件之間的交互就會跨越進程邊界了。

不同的進程

由於每一個EXE文件都將在不同的進程中運行,而每一個進程都有其自己的進程空間。一個進程空間中的邏輯地址0x00002525所對應的物理地址將不同於另外一個進程中同一邏輯地址所對應的物理地址。因此若一個進程將地址0x00002525傳給另外一個進程,後者用此地址所訪問到的內存單元將不是前一進程所希望的。

同每一個EXE都有其自己的進程不同,DLL將被映射到鏈接它們的EXE文件的進程空間中。由於這個原因,DLL也被稱作是進程中服務器,而EXE則被稱作是進程外服務器。在某些情況下,EXE也被稱作是本地服務器以同另外一種類型的進程外服務器“遠程服務器”相區別。遠程服務器指的是運行於另外一個不同的機器上的進程外服務器。

對於進程外服務器,跨越進程邊界的接口,我們需要考慮如下一些條件:
1.一個進程需要能夠調用另外一個進程中的函數;
2.一個進程需要能夠將數據傳遞給另外一個進程;
3.客戶無需關心它所訪問的服務器是進程內服務器還是進程外服務器。

本地過程調用

對於進程間的通信有幾種不同的方法,如動態數據交換,命名管道以及共享內存等。COM所用的方法則為本地過程調用(LPC)。LPC是同一機器上不同進程間通信的一種方法,它是基於遠程過程調用(RPC)的用於單機上進程間通信的專利技術。LPC是由操作系統實現的,由於操作系統知道同一個進程邏輯地址空間相對應的物理地址,因此操作系統可以調用任意進程中的任意函數。

調整

調用EXE中的函數只是第一步。另外我們還需要一種方法將函數調用的參數從一個進程的地址空間中傳到另外一個進程的地址空間中。這種方法被稱為“調整”。

若兩個進程都在同一台機器上,則調整過程將是相當直接的:只需要將參數數據從一個進程的地址空間復制到另外一個進程的地址空間就可以了。若參與參數傳遞的兩個進程在不同的地址空間中,那麼考慮到不同機器在數據表示方面的不同,如整數的字節順序可能會不同,必須將參數數據轉換成標准的格式。

為對組件進行調整,可以實現一個名為IMarshal的接口。在COM創建組件的過程中,它將查詢組件的IMarshal接口。然後它將調用IMarshal的成員函數以在調用函數的前後調整或反調整有關的參數。COM庫中實現了一個可以供大多數接口使用的IMarshal的標准版本。在需要對性能進程優化時,可以對IMarshal進行定制。

代理/殘根DLL

上面也說了,客戶不會去關心的組件是進程中的還是進程外的;最終實現時,客戶應該可以按照相同的方式與進程中、本地及遠程組件進行通信。顯然,若客戶必須自己處理LPC的問題,這一目標將無法實現。為達到這一目的,COM使用了一個非常簡單的方法。

在實際編程時,我們在使用Win32函數時,它們都用到了LPC。當調用Win32函數時,系統實現上將調用一個DLL中的函數,而此函數將通過LPC調用Windows中的實際代碼。這種結構可以將用戶進程同Windows代碼隔離開。由於不同的進程具有不同的地址空間,因此用戶程序不可能對操作系統造成破壞。

COM使用的結構與這個類似。客戶將同一個模仿組件的DLL進行通信。這個DLL可以為客戶完成參數的調整及LPC調用。在COM中,此DLL(也是一個組件)被稱作是一個代理。

用COM的術語來說,一個代理就是同另外一個組件行為相同的組件。代理必須是DLL形式的,因為它們需要訪問客戶進程的地址空間以便對傳給接口函數的數據進行調整。對數據的調整只完成了任務的一半,組件還需要一個被稱作是殘根的DLL,以對從客戶傳來的數據進行反調整。殘根也將對傳回給客戶的數據進行調整。

說了這麼多,感覺很復雜,我們要去實現代理DLL,殘根DLL;但是在實際編程中,這一切都不用我們去實現的。之後的文章會告訴你是誰幫助了我們去完成了這些復雜的動作。

總結

這裡說了這麼多理論的東西,我一直都認為,理論是實踐的基礎;任何實踐都實踐都是建立在理論之上的。理解這裡的理論,對後面的學習將會有很大的幫助的。

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved