ATL中關於程序內伺服器註冊機制的改變

2021-03-31 08:56:59 字數 3465 閱讀 6123

一、

在atl3.0

中,是通過物件對映表來註冊伺服器。

begin_object_map(objectmap)

object_entry(clsid_mycirclecollectioncreator, cmycirclecollectioncreator)

end_object_map( )

atl註冊伺服器時,最終呼叫到

atlmoduleregisterserver

函式進行伺服器註冊。對於元件支援的所有物件,它建立乙個登錄檔項進行註冊,註冊過程結束。

但是,在

atl7

中,以上三個巨集都已經過時,取而代之的是巨集

object_entry_auto

。下面我們就來分析巨集

object_entry_auto

的實現。

二、巨集

object_entry_auto

的定義。 1.

我們首先看看

_atl_objmap_entry

的定義:

struct _atl_objmap_entry30

typedef _atl_objmap_entry30 _atl_objmap_entry;

2.

巨集object_entry_auto

的定義如下:

#define object_entry_auto(clsid, class)

__declspec(selectany) atl::_atl_objmap_entry __objmap_##class = /

;/ /

extern "c" __declspec(allocate("atl$__m")) /

__declspec(selectany) atl::_atl_objmap_entry * const __pobjmap_##class /

= &__objmap_##class; /

object_entry_pragma(class)

3.接下來我們看乙個輔助的巨集

object_entry_pragma

,它的定義如下:

#define object_entry_pragma(class) /

__pragma(***ment(linker, "/include:___pobjmap_" #class));

三、

巨集object_entry_auto

的功能

1.結構體

_atl_objmap_entry

就不用多說了,和

atl3

是完全一樣的。 2.

巨集object_entry_auto

的功能: 1)

使用clsid, class

的資訊,生成

_atl_objmap_entry

的乙個例項,變數名為

__objmap_

加上class

的實際值。 2)

宣告1)

所生成例項的乙個指標,並賦值為

1)生成的例項的位址。但是指標被放在

atl$_m

段中。 3.巨集

object_entry_pragma

的功能是

告訴聯結器向符號表中新增符號

___objmap_

加上class

的實際值

。注:在

x86平台下

,符號名為宣告的名字前加下劃線。所以在

object_entry_pragma

巨集中,pobjmap

之前有三個下劃線。 四、

在哪部分**中使用

object_entry_auto

建立atl7.0

工程時: 1.

如果使用的是非屬性化程式設計,那麼它在

***類的標頭檔案中,它由嚮導自動生成,千萬不要刪除該巨集,否則將不能夠建立該類的例項。 而這樣的錯誤又是非常難發現的。 2.

如果使用的是屬性化程式設計,那麼在

***類的前面有

coclass

屬性,編譯器將向**中插入一些**完成以下功能: l

新增***

類的基類 l

產生註冊** l

產生介面對映表 l

產生物件對映項,即巨集

object_entry_auto

所以在**中,你實際看不到

object_entry_auto。

五、object_entry_auto

和系統其他部分的協作,這裡分析物件對映表的建立及使用。

如果使用非屬性化程式設計,那麼使用者可以生成任意合法

***類名稱;如果使用屬性化程式設計,我們根本不知道

_atl_objmap_entry

指標變數的名字,這些對於

atl庫來講,它不可能預先知道使用者定義的

***類的名字。那麼它是如何遍歷物件對映表,來進行更新登錄檔呢?

答案在於物件對映表的建立,我們先來看對映表的開始項、結束項。他們的定義如下:

__declspec(selectany) __declspec(allocate("atl$__a")) _atl_objmap_entry* __pobjmapentryfirst = null;

__declspec(selectany) __declspec(allocate("atl$__z")) _atl_objmap_entry* __pobjmapentrylast = null;

分析如下: l

需要注意的是,

__pobjmapentryfirst

、__pobjmapentrylast

分別被放置在段

atl$_a

和atl$_z中。

l再次需要注意的是,通過巨集

object_entry_auto

放置的變數在

atl$_m中。

l當聯結器布局**時,它按根據的名稱,按照字母排序的規則,排列所有段。這樣在段

atl$_a

中的變數出現在段

atl$_z

所有變數之前。 l

最後使用

#pragma ***ment(linker, "/merge:atl=.rdata")

,將三個段中的所有資料合併到段

.rdata

唯讀資料段中。 l

最後形成的布局可能如下:

__pobjmapentryfirst …

userdefinedptr1

userdefinedptr2 …

__pobjmapentrylast

通過這種方式,就形成了物件對映表。而在

atl庫中,可以根據

__pobjmapentryfirst

、__pobjmapentrylast

來定位物件對映表,對其中的所有物件進行註冊。

關於專用和共享伺服器程序

oracle資料庫建立伺服器程序來處理連線到例項的使用者程序的請求。伺服器程序可以是以下任一種 您的資料庫始終啟用以允許專用的伺服器程序,但您必須通過設定乙個或多個初始化引數來專門配置和啟用共享伺服器。專用伺服器程序 圖5 1 oracle資料庫專用伺服器程序 說明了專用伺服器程序如何工作。在該圖中...

Sipdroid中像伺服器註冊是如何實現的 一

關於 sipdroid是如何實現像伺服器註冊的 首先告訴大家 塊在 註冊的核心在registeragent類中的函式register int time 中,註冊的核心是 create message re modified by mandrajg message req messagefactory...

一種併發伺服器關於程序的問題

在學習 的時候曾經發生過這種問題 一台 機,執行虛擬機器,一台 嵌入式裝置 掛在 在 上面。在 執行伺服器程式 在 執行客戶端程式 與伺服器連線。伺服器是併發的,連線以後它產生 個子程序如下 root localhost echo ps a pid tty time cmd 1514 pts 0 0...