如何导入java库_导入库如何工作?细节?

链接到DLL文件可以在编译链接时隐式发生,也可以在运行时显式发生 . 无论哪种方式,DLL最终都会加载到进程内存空间中,并且其所有导出的入口点都可供应用程序使用 .

如果在运行时显式使用,则使用 LoadLibrary() 和 GetProcAddress() 手动加载DLL并获取指向需要调用的函数的指针 .

如果在构建程序时隐式链接,则程序使用的每个DLL导出的存根将从导入库链接到程序,并且这些存根在进程启动时加载EXE和DLL时会更新 . (是的,我在这里简化了一点......)

这些存根需要来自某个地方,而在Microsoft工具链中,它们来自一种称为导入库的特殊形式的.LIB文件 . 所需的.LIB通常与DLL同时构建,并包含从DLL导出的每个函数的存根 .

令人困惑的是,同一个库的静态版本也将作为.LIB文件提供 . 除了作为DLL的导入库的LIB通常比匹配的静态LIB更小(通常小得多)之外,没有简单的方法可以区分它们 .

如果您使用GCC工具链,顺便说一句,您实际上并不需要导入库来匹配您的DLL . 移植到Windows的Gnu链接器版本直接理解DLL,并且可以动态地合成大多数任何所需的存根 .

更新

如果您能够't resist knowing where all the nuts and bolts really are and what is really going on, there is always something at MSDN to help. Matt Pietrek'文章An In-Depth Look into the Win32 Portable Executable File Format是对EXE文件格式及其加载和运行方式的完整概述 . 它甚至已经更新,以涵盖.NET和更多,因为它最初出现在MSDN杂志ca. 2002年 .

此外,知道如何准确了解程序使用的DLL是有帮助的 . 其工具是Dependency Walker,又名depends.exe . 它的一个版本包含在Visual Studio中,但最新版本可从其作者http://www.dependencywalker.com/获得 . 它可以识别在链接时指定的所有DLL(早期加载和延迟加载),它还可以运行程序并监视它在运行时加载的任何其他DLL .

更新2

我已经重新编写了一些早期的文本,以便在重新阅读时澄清它,并使用术语隐式和显式链接来与MSDN保持一致 .

因此,我们有三种方法可供程序使用库函数 . 显而易见的后续问题是:“如何选择哪种方式?”

静态链接是程序本身的大部分链接 . 列出了所有目标文件,并由链接器一起收集到EXE文件中 . 在此过程中,链接器负责处理一些小事,例如修复对全局符号的引用,以便您的模块可以打电话给对方的功能 . 库也可以静态链接 . 组成库的目标文件由.LIB文件中的库管理器收集在一起,链接器搜索包含所需符号的模块 . 静态链接的一个影响是只有程序使用的库中的那些模块才链接到它;其他模块被忽略 . 例如,传统的C数学库包括许多三角函数 . 但是如果你链接它并使用 cos() ,你不会得到 sin() 或 tan() 代码的副本,除非你也调用了这些函数 . 对于具有丰富功能的大型库,选择性地包含模块非常重要 . 在诸如嵌入式系统的许多平台上,与可用于在设备中存储可执行文件的空间相比,可用于库中的代码的总大小可能很大 . 如果没有选择性包含,那么管理这些平台的构建程序的细节将更加困难 .

但是,在每个运行的程序中都拥有相同库的副本会给通常运行大量进程的系统带来负担 . 使用正确类型的虚拟内存系统,具有相同内容的内存页只需要在系统中存在一次,但可以被许多进程使用 . 这样可以增加包含代码的页面可能与尽可能多的其他运行进程中的某个页面相同的机会 . 但是,如果程序静态链接到运行时库,那么每个程序都有不同的功能组合,每个功能都在不同位置的进程内存映射中布局,并且没有很多可共享的代码页,除非它本身就是一个程序 . 在多个过程中运行 . 因此,DLL的想法获得了另一个主要优势 .

库的DLL包含其所有功能,可供任何客户端程序使用 . 如果许多程序加载该DLL,它们都可以共享其代码页 . 每个人都赢了 . (好吧,直到你用新版本更新DLL,但这不是这个故事的一部分 . 谷歌DLL地狱的故事的那一面 . )

因此,在规划新项目时做出的第一个重大选择是在动态和静态链接之间 . 使用静态链接,您可以安装较少的文件,并且您可以免受第三方更新您使用的DLL的影响 . 但是,您的程序更大,并且它不是Windows生态系统的良好公民 . 使用动态链接,您需要安装更多文件,第三方更新您使用的DLL时可能会遇到问题,但您通常对系统上的其他进程更友好 .

DLL的一大优点是可以加载和使用它而无需重新编译甚至重新链接主程序 . 这可以允许第三方库提供程序(例如Microsoft和C运行时)修复其库中的错误并进行分发 . 一旦最终用户安装了更新的DLL,他们就会立即从使用该DLL的所有程序中获得该错误修复的好处 . (除非它破坏了东西 . 请参阅DLL Hell . )

另一个优点来自隐式加载和显式加载之间的区别 . 如果你需要额外的显式加载工作,那么在编写和发布程序时,DLL可能甚至不存在 . 例如,这允许可以发现和加载插件的扩展机制 .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值