Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
共享库:Windows vs Linux方法_Linux_Windows_Shared Libraries - Fatal编程技术网

共享库:Windows vs Linux方法

共享库:Windows vs Linux方法,linux,windows,shared-libraries,Linux,Windows,Shared Libraries,我有一个关于Windows共享库(DLL)和Linux共享库(SOs)的快速问题 为什么在创建Windows DLL时,客户端程序还需要与静态库(.lib文件)链接,而在Linux中创建的应用程序不需要与此类静态库链接 它是否与代码重新定位等有关?谢谢。事实上,代码重新定位不是这样,这是一个完全不同的问题。这是关于架构上的差异: 在Windows中,DLL就像可执行文件(EXE)。EXE和DLL之间的主要区别在于EXE有一个入口点(main/WinMain函数),因此它可以用来启动进程,而DL

我有一个关于Windows共享库(DLL)和Linux共享库(SOs)的快速问题

为什么在创建Windows DLL时,客户端程序还需要与静态库(.lib文件)链接,而在Linux中创建的应用程序不需要与此类静态库链接


它是否与代码重新定位等有关?谢谢。

事实上,代码重新定位不是这样,这是一个完全不同的问题。这是关于架构上的差异:

  • 在Windows中,DLL就像可执行文件(EXE)。EXE和DLL之间的主要区别在于EXE有一个入口点(main/WinMain函数),因此它可以用来启动进程,而DLL只能加载到预先存在的进程中。但见(1)

  • 在Linux中,a.so的工作方式类似于静态库(.a)。主要区别在于.so文件可以与正在运行的程序链接,而.a文件只能在编译程序时链接

这种方法的结果是,在linux中,可以使用相同的文件来构建和运行程序。但是在Windows中,您需要一个适当的库(LIB)来链接程序。实际上,与DLL相对应的lib通常只包含函数名,以满足链接器的需要,以及用于重新定位的存根。但见(2)

(1) 嗯,DLL也有入口点,但它并没有用作主函数,就像某种初始化/终结钩子一样


(2) 有些链接器足够聪明,在一些简单的情况下,可以使用DLL本身链接到DLL,而不需要额外的LIB文件。我认为至少MinGW链接器可以做到这一点。

在Windows中,客户端程序不需要链接到静态库来访问DLL中的函数。动态链接可以完全在运行时发生,而客户机程序甚至在编译DLL时都不知道DLL的存在

例如,如果要在名为“bar.DLL”的DLL中调用函数名“foo”,可以编写如下代码:

HINSTANCE hinst = LoadLibrary("bar.dll");
FARPROC foo = GetProcAddress(hinst, "foo");
foo();
“foo”和“bar.dll”很容易成为仅在运行时建立的值,比如通过配置文件或其他用户输入

静态库的目的是通过创建存根来自动化此动态加载过程,就客户端程序而言,存根看起来像是常规函数,但在运行时链接到DLL。通常,这种链接在加载客户端进程时发生,但也可以生成库,根据需要加载和链接,因此DLL在实际需要之前不会被带到内存中。静态库决定链接何时发生

在大多数情况下,编译器可以自动生成这些库,因此在技术上,仅链接到DLL函数时不需要这些库。但是,有一个例外(我知道)是链接到共享变量时

在Windows DLL中,您可以创建一个共享数据段,其中包含可由加载该DLL的任何进程访问的变量。有关这些变量的大小和类型的信息存储在关联的静态库中,不能仅从DLL确定。为了访问这些变量,客户端程序必须链接到该DLL的静态库

据我所知,Linux共享库不支持这样的概念

更新

我还应该提到,在Windows上,可以创建一个DLL,其中函数入口点仅按序号(数字)而不是名称导出。这可以被认为是数据隐藏的一种形式,通常在实现者希望某些函数保持私有时使用

有权访问静态库的人可以按名称调用这些函数,因为库中有将函数名链接到适当序号的详细信息。任何只拥有DLL的人都必须通过序号手动链接到函数,或者用虚构的名称生成自己的静态库

为什么在创建Windows DLL时,客户端程序还需要与静态库(.lib文件)链接,而在Linux中创建的应用程序不需要与此类静态库链接

这是微软做出的历史性设计决策,这样链接器就可以将DLL引用添加到可执行文件中,而无需在链接时提供特定版本的DLL。原因是,总是有不同版本的Windows,有不同版本的DLL。当时微软还在OS/2上与IBM合作,计划是Windows程序也可以在OS/2上执行。微软决定“backstab”OS/2,基于NT内核推出自己的专业级操作系统。但这意味着,对于开发,您希望开发人员能够链接到系统DLL,而无需使用DLL的所有不同变体。相反,动态链接“模板”将用于创建DLL和可执行文件(均为PE格式),它们是这些特定的
.lib
文件,它们根本不是库,而只是符号和顺序表(这是一个鲜为人知的事实,但PE二进制符号不仅可以通过字符串标识符加载,还可以通过整数(即所谓的序数)加载)

序数的一个副作用是,它们允许隐藏人类可读的符号,因此只有知道序数时才能使用DLL←→ 函数关系

在Unix中,传统是“您在将要运行它的系统上构建它”,或者“您已经准备好了所有目标系统文件”。因此,从技术上讲,从来没有一个激励因素会如此分离库和链接信息