Cha*_*lie 25 c c++ compilation loadlibrary dynamic-linking
动态链接如何工作?
在Windows(LoadLibrary)上,您需要在运行时调用.dll,但在链接时,您需要提供相应的.lib文件,否则程序将无法链接... .lib文件包含什么?.dll方法的描述?这不是标题包含的内容吗?
相关地,在*nix上,您不需要lib文件...编译器如何知道标头中描述的方法在运行时可用?
作为一个新手,当你想到两个方案中的任何一个,然后另一个,它们都没有意义......
Jam*_*nze 23
逐一回答您的问题:
动态链接将部分链接过程延迟到运行时.它可以以两种方式使用:隐式和显式.隐式地,静态链接器将信息插入到可执行文件中,这将导致库加载并解析必要的符号.显然,您必须调用LoadLibrary
或
dlopen
手动,然后GetProcAddress
/ dlsym
为您需要使用的每个符号.隐式加载用于系统库之类的东西,其实现将取决于系统的版本,但保证接口.显式加载用于插件之类的东西,其中要加载的库将在运行时确定.
该.lib
文件仅用于隐式加载.它包含库实际提供此符号的信息,因此链接器不会抱怨该符号未定义,并且它告诉链接器符号所在的库,因此它可以插入必要的信息以使该库自动加载.所有头文件告诉编译器符号将存在于某处; 链接器需要.lib
知道在哪里.
在Unix下,所有信息都是从中提取的
.so
.为什么Windows需要两个单独的文件,而不是将所有信息放在一个文件中,我不知道; 它实际上是复制了大部分信息,因为需要的信息.lib
也需要.dll
.(也许许可问题.你可以用你的程序分发你的程序.dll
,但没有人可以链接到库,除非他们有.lib
.)
要保留的主要内容是,如果要进行隐式加载,则必须为链接器提供相应的信息,或者使用文件.lib
或.so
文件,以便它可以将该信息插入到可执行文件中.如果你想要显式加载,你不能直接引用库中的任何符号; 你必须自己打电话GetProcAddress
/ dlsym
获取他们的地址(并做一些有趣的演员来使用它们).
Com*_*sMS 13
.lib
加载动态库不需要Windows上的文件,它只是提供了一种方便的方法.
原则上,您可以使用LoadLibrary
加载DLL,然后GetProcAddress
用于访问该DLL提供的功能.在这种情况下,封闭程序的编译不需要访问dll,只需要在运行时(即LoadLibrary
实际执行时).MSDN有一个代码示例.
这里的缺点是你需要手动编写代码来从dll加载函数.如果你自己编译了dll,这段代码只是复制了编译器可以自动从dll源代码中提取的知识(比如导出函数的名称和签名).
这就是.lib
文件的作用:它包含GetProcAddress
由编译器生成的Dlls导出函数的调用,因此您不必担心它.在Windows术语中,这称为加载时动态链接,因为当加载封闭程序时,由.lib文件中的代码自动加载Dll(与手动方法相反,称为运行时动态链接) .
动态链接如何工作?
动态链接库(也称为共享对象)文件包含机器代码指令和数据,以及元数据表,说明该代码/数据中的哪些偏移与哪些"符号",符号的类型(例如,功能与数据)相关,数据中的字节数或字数,以及其他一些东西.不同的操作系统往往会有不同的共享对象文件格式,实际上相同的操作系统可能会支持几种,但这就是它的要点.
所以,想象共享库是一大块字节,其索引如下:
SYMBOL ADDRESS TYPE SIZE
my_function 1000 function 2893
my_number 4800 variable 4
Run Code Online (Sandbox Code Playgroud)
通常,不需要在元数据表中捕获符号的确切类型 - 期望库的头文件中的声明包含所有缺少的信息.C++有点特殊 - 与C相比 - 因为重载可能意味着有几个具有相同名称的函数,并且命名空间允许进一步的符号,否则将被模糊地命名 - 因此名称修改通常用于连接一些表示函数名称的名称空间和函数参数,形成了库对象文件中唯一的东西.
想要使用共享对象的程序通常可以执行以下两种操作之一:
让操作系统同时加载自身和共享对象(执行前main()
),OS Loader负责查找符号并检查程序文件映像中有关这些符号使用的元数据,然后在符号地址中修补程序使用的内存,这样程序就可以运行并在功能上运行,就像它在第一次编译时知道符号地址一样(但可能稍慢)
或者,dlopen
在main
运行后的某个时间显式地在其自己的源代码中调用,然后使用dlsym
或类似地获取符号地址,根据程序员对预期数据类型的了解将它们保存到(函数/数据)指针中,然后使用指针显式调用它们.
在Windows(LoadLibrary)上,您需要在运行时调用.dll,但在链接时,您需要提供相应的.lib文件,否则程序将无法链接...
这听起来不对.应该是我认为的一个或另一个.
Wtf .lib文件包含?.dll方法的描述?这不是标题包含的内容吗?
lib文件 - 在这个描述级别 - 与共享对象文件几乎相同......主要区别在于编译器在程序发布和运行之前找到符号地址.