3

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

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

例如:

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

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

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

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

4

4 回答 4

5

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

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

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

ResourceHolder theHolder;

但是,如果您在库中使用另一个全局变量,则需要一些意识。

于 2012-07-09T11:36:53.210 回答
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

于 2012-07-09T11:33:21.720 回答
1

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

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

帕特里斯

于 2015-01-15T16:30:38.683 回答
0

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

于 2012-07-09T11:33:30.367 回答