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