加载/卸载共享库时执行的代码

问题描述:

是否可以在加载(或卸载)库时在共享库(在Windows上为.dll,在Linux上为.so)中创建函数?加载/卸载共享库时执行的代码

就像main()函数是可执行文件的入口点一样,我可以定义一个函数在加载或卸载DLL时执行吗?

例如为:

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

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

我想我已经看到了这样的例子地方,但我找不到它的任何更多的,并不能找到有关这个互联网上的任何东西。

如果它有任何用处,我使用MinGW编译代码。

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

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

在C++中,你至少可以创造一些类

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

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

ResourceHolder theHolder; 

但如果你在图书馆使用另一个全局变量的一些认识,需要的全局实例。

正如前面所说,在Window下你可以从DllMain开始工作。但要小心你会做什么,因为有很多限制(例如,禁止使用COM CoInitialize函数)。有一件事你不能依赖的是,dll的加载/卸载顺序没有保证,所以你不能调用DllMain中驻留在另一个dll中的函数:它可以在今天运行,但不能在明天运行:)

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

帕特里斯