防止过多的LoadLibrary / FreeLibrary

时间:2010-10-02 09:32:15

标签: c windows operating-system

我正在编写一个代理库(称为库A),它只是另一个DLL(称为库B)的接口,可能存在于系统中或不存在。 想法是程序将链接到此库A而不是原始库B;如果系统上没有安装库B,则库A将处理错误。

因此典型的代理函数如下所示:

int function(int arg1, int arg2)
{
    HINSTANCE hinstLib;
    UINT errormode = SetErrorMode(SEM_FAILCRITICALERRORS);
    SetErrorMode(errormode | SEM_FAILCRITICALERRORS);
    hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));
    SetErrorMode (errormode);
    if (hinstLib != NULL)
    {
        ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
        if (NULL != ProcAdd)
        {
            return (ProcAdd) (arg1, arg2);
        }
        FreeLibrary(hinstLib);
    }
    return ERROR;
}

现在,我会对图书馆B中的所有原始条目执行此操作。可能会有很多调用它。 因此,如此频繁地加载/卸载DLL肯定会对速度产生影响。

我想知道使用全局变量hinstLib是否可以接受;

之类的东西
HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));

int function(int arg1, int arg2)
{
    if (hinstLib != NULL)
    {
        ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
        if (NULL != ProcAdd)
        {
            return (ProcAdd) (arg1, arg2);
        }
    }
    return ERROR;
}

让Windows在程序退出时自动卸载DLL(假设它已卸载)。

提前感谢你的明智言论......

让伊夫

1 个答案:

答案 0 :(得分:2)

除非卸载是特定用例,否则这很好。但是我会实现一些线程安全性,以确保通过此代码使用Critical Section没有竞争条件。

这是维基百科文章中的一个例子

    /* Sample C/C++, Windows, link to kernel32.dll */
    #include <windows.h>

    static CRITICAL_SECTION cs;

    static HINSTANCE hinstLib = LoadLibrary(TEXT(ORIGINAL_DLL));

    /* Initialize the critical section before entering multi-threaded context. */
    InitializeCriticalSection(&cs);

    void f() {
        /* Enter the critical section -- other threads are locked out */
        __try {
           EnterCriticalSection(&cs);

           if (hinstLib != NULL)     {
           ProcAdd = (void *) GetProcAddress(hinstLib, TEXT("function"));
         } __finally { 
            LeaveCriticalSection(&cs);
         }
         if (NULL != ProcAdd) {
               return (ProcAdd) (arg1, arg2);
         }
    }

.
.
.

    /* Release system object when all finished -- usually at the end of the cleanup code */
    DeleteCriticalSection(&cs);