为什么我们已经有了实际的 .dll 实现,还需要一个 .lib 存根文件? [英] Why do we still need a .lib stub file when we've got the actual .dll implementation?

查看:21
本文介绍了为什么我们已经有了实际的 .dll 实现,还需要一个 .lib 存根文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道为什么链接器不能仅仅通过查阅获得实际实现代码的实际 .dll 文件中的信息来完成他们的工作?我的意思是为什么链接器仍然需要 .lib 文件来进行隐式链接?

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 still need .lib files to do implicit linking ?

导出和相对地址表还不足以进行这种链接吗?

are not the export and relative address tables enough for such linking ?

有没有一种方法可以只使用 .dll 而不使用 .lib 存根/代理文件来进行隐式链接?

is there anyway by which one can do implicit linking using only the .dll without the .lib stub/proxy files ?

我认为 Windows 可执行加载器只会代表程序执行 LoadLibrary/LoadLibraryEx 调用(因此称为隐式链接),这是与显式链接的主要区别.如果这是真的,那么在没有 .lib 的情况下显式执行它应该表明它在没有它的情况下是可行的,对吧?还是我只是在说无意义?

i thought the windows executable loader would simply do LoadLibrary/LoadLibraryEx calls on behalf of the program (hence the name implicit linking) which is the main difference to explicit linking. if that is true then doing it explicitly without .lib should indicate that it is doable without it implicitly, right ? or i'm just saying non sense?

推荐答案

我能想到几个原因.

  • 使用 .lib 文件意味着您可以构建与系统上不同版本的 DLL,前提是您安装了正确的 SDK.
  • 编译器和链接器需要支持跨平台编译 - 您可能在 32 位平台上为 64 位目标构建,反之亦然,并且没有正确的架构 DLL.
  • .lib 文件使您能够隐藏"您的实现的某些部分 - 您可以拥有不显示在 .lib 中但可以通过 GetProcAddress 发现的私有导出.您也可以进行序数导出,在这种情况下,它们没有导出的友好名称,但在 .lib 中会有一个友好名称.
  • 本机 DLL 没有强名称,因此可能会选择错误的 DLL 版本.
  • 最重要的是,这项技术是在 1980 年代设计的.如果它是今天设计的,它可能更接近您所描述的 - 例如,.NET 您只需要引用目标程序集并且您拥有使用它所需的一切.

我不知道有任何方法可以单独使用 DLL 进行隐式链接 - 快速搜索发现了几个工具,但我没有使用过其中任何一个.

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.

在这种情况下,我将创建一个包含您需要使用的函数的单独源文件,并根据需要动态加载 DLL 并绑定它们.例如:

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();
}

这篇关于为什么我们已经有了实际的 .dll 实现,还需要一个 .lib 存根文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆