今天稍微實(shí)驗(yàn)了一下DLL的數(shù)據(jù)共享問題,做了兩種情況下的測試,第一種是兩個(gè)進(jìn)程同時(shí)調(diào)用一個(gè)DLL的實(shí)驗(yàn),另一種是一個(gè)進(jìn)程調(diào)用一個(gè)兩個(gè)DLL,然后這兩個(gè)DLL有依賴關(guān)系,記錄一下得到的測試結(jié)果。
當(dāng)一個(gè)進(jìn)程調(diào)用LoadLibrary、LoadLibraryEx以及FreeLibrary時(shí),DllMain會(huì)被調(diào)用,從DllMain的入口函數(shù)的第二個(gè)參數(shù)可以得知是加載還是釋放。LoadLibraryEx的flag參數(shù)傳入DONT_RESOLVE_DLL_REFERENCES可以跳過DllMain的調(diào)用,這在很多時(shí)候是有用的。
當(dāng)一個(gè)進(jìn)程在調(diào)用LoadLibrary后又啟動(dòng)了線程,則每啟動(dòng)一個(gè)線程,就會(huì)調(diào)用一次DllMain,同樣可以從DllMain的第二個(gè)參數(shù)的值來區(qū)分調(diào)用時(shí)由進(jìn)程引起的還是由線程引起的。第二個(gè)參數(shù)的值一般有4種,如下:
DLL_PROCESS_ATTACH
DLL_PROCESS_DETACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
不用解釋也能看得出來分別是表示什么意義了,通過這個(gè)可以選擇性的對(duì)DLL中的數(shù)據(jù)進(jìn)行初始化。
如果是兩個(gè)進(jìn)程同時(shí)調(diào)用一個(gè)DLL的話,數(shù)據(jù)是不會(huì)共享的,除非你設(shè)置了seg項(xiàng)為共享,具體不同的編譯器會(huì)有不同的設(shè)置方法。兩個(gè)進(jìn)程對(duì)同一個(gè)DLL的調(diào)用計(jì)數(shù)也是分開的,這讓我很放心了,之前一直害怕的沖突問題釋然。
當(dāng)一個(gè)進(jìn)程去調(diào)用一個(gè)DLL甲,而甲又在初始化的時(shí)候調(diào)用了DLL乙,進(jìn)程通過甲的函數(shù)來訪問了DLL乙,同時(shí)自己也親自調(diào)用了DLL乙并取出和更改了數(shù)據(jù)。這樣的情況下,DLL乙的引用計(jì)數(shù)是共享的,數(shù)據(jù)也是共享的,加載和釋放都很安全,之前擔(dān)心DLL乙中的單件會(huì)被重復(fù)調(diào)用的情況也不可能存在了。