关于 Linux 与 Windows 上的 g++、动态和静态链接的误解
我对今天学到的东西有点困惑。我希望有人能帮助我。
我理解动态和静态链接的概念,但问题如下。在 Windows 上,或者至少在 Windows 上的范例上,您可以拥有 .lib(类似于 .a)和 .dll(类似于 .so,除了...不同),并且必须静态链接到 .lib包含在运行时从 dll 调用函数的代码。这是正确的吗?换句话说,gcc 或 g++ 必须在编译/链接时具有可用的 .lib 文件,并且能够在运行时找到 .dll 文件。请纠正此处任何错误的假设。
但是,我将小型应用程序中的一些源文件分开,因为我想让它们成为一个库。当我使用 -shared 选项在目标文件上运行 g++ 时,这基本上会创建一个共享库 (.so)?这就是混乱产生的地方。链接时和运行时都需要相同 so 文件吗?我无法理解在链接时如何在 -L/-l 选项中需要它,但它在运行时仍然需要该文件。这实际上是常态吗? dll 有本质上的不同吗?
最后,最后一个问题。以 Windows 上的 boost 这样的库为例。我按照说明构建了 boost。最后,stage/lib 目录包含重复序列 name.a、name.dll.a、name.dll 的库。这个计划的目的是什么?我知道我在运行时需要 dll 文件,但是当我在链接时使用 -L/-l 选项时,它使用什么文件?
抱歉,如果这真的很分散,但我希望有人可以帮助解决这个问题。多谢!
I'm a little confused by what I've learned today. I hope somebody can help me out.
I understand the concept of dynamic and static linking, but the problem is as follows. On windows, or at least the paradigm on windows, you can have a .lib (which is like .a) and .dll (which is like .so, except... different) and you must statically link in the .lib which contains code that calls functions from the dll at runtime. Is this correct? In other words, gcc or g++ must have .lib files available at compile/link time, and be able to find .dll files at runtime. Please correct any wrong assumptions here.
However, I'm splitting a few of my source files in my small application away because I want to make them a library. When I run g++ on my object files, with the -shared option, this basically creates a shared library (.so)? This is where the confusion arises. The same so file is needed both at link time and runtime? I have trouble understanding how I need it in the -L/-l option at link time but it still needs the file at runtime. Is this actually the norm? Is a dll fundamentally different?
Finally, a final question. Take a library like boost on Windows. I built boost according to the instructions. In the end, the stage/lib directory contains libraries in a repeating sequence of name.a, name.dll.a, name.dll. What is the purpose of this scheme? I know I need the dll files at runtime, but when I use the -L/-l option at link time, what files is it using THEN?
Sorry if this is really scattered, but I hope someone can help clear this up. Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,也不是。这是 DLL 在 Windows 上工作的一种方式,但不是唯一的方式。
您可以使用 Win32 API 调用手动加载 DLL。但如果这样做,则必须手动获取函数指针才能实际访问 DLL。导入库(您正在谈论的静态库)的目的是自动执行此操作。
手动执行此操作的好处是您可以选择所需的 DLL。这就是某些应用程序提供插件支持的方式。用户编写一个 DLL,导出一组定义良好的 API 函数。您的程序从目录加载它们,并将每个 DLL 的函数指针捆绑到其自己的对象中,该对象代表该插件的接口。
GCC 在 Windows 上的工作方式相同。。构建 DLL 会生成 DLL 和导入库。由于编译器的原因,它是一个“.a”文件而不是“.lib”,但它仍然做同样的事情。
在 Linux 上,.so 文件是 .dll 和导入库的组合。因此,在编译相关程序时链接到 .so,它的作用与链接到导入库相同。
Yes and no. That is one way that DLLs work on Windows, but it is not the only way.
You can load a DLL manually, using Win32 API calls. But if you do, you have to get function pointers manually to actually access the DLL. The purpose of the import library (that static library you're talking about) is to do this automatically.
The nice thing about doing it manually is that you can pick and choose what DLLs you want. This is how some applications provide plugin support. Users write a DLL that exports a well-defined set of API functions. Your program loads them from a directory, and they bundle the function pointers for each DLL into its own object, which represents the interface to that plugin.
GCC works the same way, on Windows. Building a DLL produces a DLL and an import library. It's a ".a" file instead of ".lib" because of the compiler, but it still does the same thing.
On Linux, .so files are a combination of the .dll and the import library. So you link to the .so when compiling the program in question, and it does the same job as linking to the import library.
这只是在编译时提供有关共享库的信息的两种方法。也许比较会更好地解释它?
在 Windows 中,它是:“您将使用共享库 (.dll),这里(.a 或 .dll.a)是有关如何使用它的手册。”
在 Linux 中,它是:“您将使用共享库 (.so),因此请事先查看它 (.so),这样您就会知道如何使用它。”
It's just two ways of giving infos at compile time about the shared library. Maybe a comparison would explain it better ?
In Windows, it's : "You will use a shared library (.dll) and here (.a or .dll.a) is the manual on how to use it."
In Linux, it's :" You will use a shared library (.so) so look at it beforehand (.so) so you'll know how to use it."