2012-07-09 56 views
2

是否可以在加載(或卸載)庫時在共享庫(在Windows上爲.dll,在Linux上爲.so)中創建函數?加載/卸載共享庫時執行的代碼

就像main()函數是可執行文件的入口點一樣,我可以定義一個函數在加載或卸載DLL時執行嗎?

例如爲:

void _atstart() 
{ 
    // Initialize some stuff needed by the library 
} 

void _atexit() 
{ 
    // Release some allocated resources 
} 

我想我已經看到了這樣的例子地方,但我找不到它的任何更多的,並不能找到有關這個互聯網上的任何東西。

如果它有任何用處,我使用MinGW編譯代碼。

回答

3

Windows系統可以使用DllMain

BOOL WINAPI DllMain(
    __in HINSTANCE hinstDLL, 
    __in DWORD fdwReason, 
    __in LPVOID lpvReserved 
); 

第二個參數fdwReason如果庫加載或卸載指定。全參考:http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) 
{ 
    switch (fdwReason) 
    { 
    case DLL_PROCESS_ATTACH: 
     // code for library load 
     break; 
    case DLL_PROCESS_DETACH: 
     // code for library unload 
     break; 
    } 
    return (TRUE); 
} 

對於Linux,你也許可以使用:

__attribute__ ((constructor)) 
__attribute__ ((destructor)) 

但這只是谷歌搜索後,來到了,所以你必須自行調查 - http://tdistler.com/2007/10/05/implementing-dllmain-in-a-linux-shared-library

+0

因此,這意味着卸載時加載時的DllMain執行兩次,一次,一次? – Tibi 2012-07-09 11:34:27

+0

@Tibi是的。用不同的參數, – 2012-07-09 11:35:49

+0

好的,謝謝:) – Tibi 2012-07-09 11:36:02

0

在Windows下,您可以編寫自己的DllMain()版本。

4

在C++中,你至少可以創造一些類

class ResourceHolder { 
public: 
    ResourceHolder() { 
     // at start 
    } 

    ~ResourceHolder() { 
     // at exit 
    } 
}; 

ResourceHolder theHolder; 

但如果你在圖書館使用另一個全局變量的一些認識,需要的全局實例。

1

正如前面所說,在Window下你可以從DllMain開始工作。但要小心你會做什麼,因爲有很多限制(例如,禁止使用COM CoInitialize函數)。有一件事你不能依賴的是,dll的加載/卸載順序沒有保證,所以你不能調用DllMain中駐留在另一個dll中的函數:它可以在今天運行,但不能在明天運行:)

可以在線上MSDN: [http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx]

帕特里斯