Why do we still need a .lib stub file when we've got the actual .dll implementation?

前端 未结 1 1902
野趣味
野趣味 2020-12-16 12:27

i\'m wondering why linkers can not do their job simply by consulting the information in the actual .dll files that got the actual implementation code ? i mean why linkers st

相关标签:
1条回答
  • 2020-12-16 12:53

    I can think of a a few reasons.

    • Using .lib files mean you can build for a different version of a DLL than you have on your system, provided you just have the correct SDK installed.
    • Compilers & linkers need to support cross-platform compilations - You might be building for a 64-bit target on a 32-bit platform and vice-versa and not have the correct architecture DLL present.
    • .lib files enable you to "hide" certain parts of your implementation - you could have private exports that do not show up in the .lib but are discoverable via GetProcAddress. You can also do ordinal exports in which case they don't have a friendly name exported, but would have a friendly name in the .lib.
    • Native DLL's do not have strong names, so it may be possible to pick up the wrong version of the DLL.
    • And most importantly, this technology was designed in the 1980's. If it were designed today, it'd probably be closer to what you describe - for instance, .NET you just need to reference the target assembly and you have everything you need to use it.

    I don't know of any way to do implicit linking solely with the DLL - A quick search revealed several tools, but I haven't used any of them.

    In this case, I would create a separate source file with the functions you need to use, and dynamically load the DLL and bind them as needed. For example:

    // using global variables and no-error handling for brevity.
    
    HINSTANCE theDll = NULL;
    typedef void (__stdcall * FooPtr)();
    FooPtr pfnFoo = NULL;
    INIT_ONCE initOnce;
    
    BOOL CALLBACK BindDLL(PINIT_ONCE initOnce, PVOID parameter, PVOID context)
    {
        theDll = LoadLibrary();
        pfnfoo = GetProcAddress(dll, "Foo");
    
        return TRUE;
    }
    
    // Export for foo
    void Foo()
    {
        // Use one-time init for thread-safe lazy initialization
        InitOnceExecuteOnce(initOnce, BinDll, NULL, NULL)
        pfnFoo();
    }
    
    0 讨论(0)
提交回复
热议问题