dll #pragma data_seg注意事項#pragma data_seg("flag_data")
int count=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:flag_data,RWS")
這種方法只能在沒有def檔案時使用,如果通過def檔案進行匯出的話,那麼設定就要在def檔案內設定而不能
在代碼裡設定了。
SETCTIONS
flag_data READ WRITE SHARED
0 0
0
(請您對文章做出評價)發表於 2008-04-08 23:56 ahuo 閱讀(1554) 評論(2) 編輯 收藏 網摘 所屬分類: VC++, API
評論
1315155
在主檔案中,用#pragma data_seg建立一
個新的資料區段並定義共用資料,其具體格式為:
#pragma data_seg ("shareddata") //名稱可以
//自己定義,但必須與下面的一致。
HWND sharedwnd=NULL;//共用資料
#pragma data_seg()
僅定義一個資料區段還不能達到共用資料的目的,還要告訴編譯器該段的屬性,有兩種方法可以實現該目的 (其效果是相同的),一種方法是在.DEF檔案中加入如下語句: SETCTIONS shareddata READ WRITE SHARED 另一種方法是在項目設定連結選項(Project Setting --〉Link)中加入如下語句: /SECTION:shareddata,rws
第一點:什麼是共用資料區段?為什麼要用共用資料區段??它有什麼用途??
在Win16環境中,DLL的全域資料對每個載入它的進程來說都是相同的;而在Win32環境中,情況卻發生了變化,DLL函數中的代碼所建立的任何對象(包括變數)都歸調用它的線程或進程所有。當進程在載入DLL時,作業系統自動把DLL地址映射到該進程的私人空間,也就是進程的虛擬位址空間,而且也複製該DLL的全域資料的一份拷貝到該進程空間。也就是說每個進程所擁有的相同的DLL的全域資料,它們的名稱相同,但其值卻並不一定是相同的,而且是互不干涉的。
因此,在Win32環境下要想在多個進程中共用資料,就必須進行必要的設定。在訪問同一個Dll的各進程之間共用儲存空間是通過儲存空間對應檔技術實現的。也可以把這些需要共用的資料分離出來,放置在一個獨立的資料區段裡,並把該段的屬性設定為共用。必須給這些變數賦初值,否則編譯器會把沒有賦初始值的變數放在一個叫未被初始化的資料區段中。
#pragma data_seg預先處理指令用於設定共用資料區段。例如:
#pragma data_seg("SharedDataName") HHOOK hHook=NULL; //必須在定義的同時進行初始化!!!!#pragma data_seg()
在#pragma data_seg("SharedDataName")和#pragma data_seg()之間的所有變數將被訪問該Dll的所有進程看到和共用。再加上一條指令#pragma comment(linker,"/section:.SharedDataName,rws"),[注意:資料節的名稱is case sensitive]那麼這個資料節中的資料可以在所有DLL的執行個體之間共用。所有對這些資料的操作都針對同一個執行個體的,而不是在每個進程的地址空間中都有一份。
當進程隱式或顯式調用一個動態庫裡的函數時,系統都要把這個動態庫映射到這個進程的虛擬位址空間裡(以下簡稱"地址空間")。這使得DLL成為進程的一部分,以這個進程的身份執行,使用這個進程的堆棧。(這項技術又叫code Injection技術,被廣泛地應用在了病毒、駭客領域!呵呵^_^)
第二點:在具體使用共用資料區段時需要注意的一些問題!
Win32 DLLs are mapped into the address space of the calling process. By default, each process using a DLL has its own instance of all the DLLs global and static variables. (注意: 即使是全域變數和靜態變數也都不是共用的!) If your DLL needs to share data with other instances of it loaded by other applications, you can use either of the following approaches:
· Create named data sections using the data_seg pragma.
· Use memory mapped files. See the Win32 documentation about memory mapped files.
Here is an example of using the data_seg pragma:
#pragma data_seg (".myseg")
int i = 0;
char a[32] = "hello world";
#pragma data_seg()
data_seg can be used to create a new named section (.myseg in this example). The most typical usage is to call the data segment .shared for clarity. You then must specify the correct sharing attributes for this new named data section in your .def file or with the linker option /SECTION:.MYSEC,RWS. (這個編譯參數既可以使用pragma指令來指定,也可以在VC的IDE中指定!)
There are restrictions to consider before using a shared data segment:
· Any variables in a shared data segment must be statically initialized. In the above example, i is initialized to 0 and a is 32 characters initialized to hello world.
· All shared variables are placed in the compiled DLL in the specified data segment. Very large arrays can result in very large DLLs. This is true of all initialized global variables.
· Never store process-specific information in a shared data segment. Most Win32 data structures or values (such as HANDLEs) are really valid only within the context of a single process.
· Each process gets its own address space. It is very important that pointers are never stored in a variable contained in a shared data segment. A pointer might be perfectly valid in one application but not in another.
· It is possible that the DLL itself could get loaded at a different address in the virtual address spaces of each process. It is not safe to have pointers to functions in the DLL or to other shared variables.
#1樓[樓主] 回複 引用 查看