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

Code executed by shared library when loaded/unloaded

本文关键字:执行 代码 共享 卸载 加载      更新时间:2023-10-16

是否可以在共享库(Windows上为.dll,linux上为.so)中创建一个函数,该函数在加载(或卸载)库时立即执行?

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

例如:

void _atstart()
{
    // Initialize some stuff needed by the library
}
void _atexit()
{
    // Release some allocated resources
}

我想我在某个地方见过这样的例子,但我再也找不到了,也在互联网上找不到任何关于这个的东西。

如果它有用的话,我正在用MinGW编译代码。

在C++中,您至少可以创建某个类的全局实例

class ResourceHolder {
public:
    ResourceHolder() {
        // at start
    }
    ~ResourceHolder() {
        // at exit
    }
};
ResourceHolder theHolder;

不过,如果您在库中使用其他全局变量,则需要一些意识。

对于窗口,您可以使用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

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

MSDN上的更多联机信息:[http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx]

Patrice

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