相关疑难解决方法(0)

共享对象(.so),静态库(.a)和DLL(.so)之间的区别?

我参与了关于Linux中的库的一些争论,并想确认一些事情.

这是我的理解(请纠正我,如果我错了,我将在稍后编辑我的帖子),在构建应用程序时有两种使用库的方法:

  1. 静态库(.a文件):在链接时,将整个库的副本放入最终应用程序中,以便库中的函数始终可用于调用应用程序
  2. 共享对象(.so文件):在链接时,仅通过相应的头(.h)文件针对其API验证对象.直到运行时才需要实际使用该库.

静态库的明显优势是他们让整个应用程序是自包含的,而动态库的好处是"所以"文件可以被替换(即:如果它需要更新由于安全bug),无需重新编译基本应用程序.

我听说有些人区分共享对象和动态链接库(DLL),即使它们都是".so"文件.在Linux或任何其他POSIX兼容操作系统(即:MINIX,UNIX,QNX等)上进行C/C++开发时,共享对象和DLL之间是否有任何区别?我被告知一个关键的区别(到目前为止)是共享对象只是在运行时使用,而DLL必须首先使用应用程序中的dlopen()调用打开.

最后,我还听到一些开发人员提到"共享存档",根据我的理解,这些存档也是静态库本身,但直接由应用程序使用.相反,其他静态库将链接到"共享存档",以将一些(但不是全部)功能/资源从共享存档中提取到正在构建的静态库中.

提前谢谢大家的帮助.

更新


在向我提供这些术语的上下文中,Windows开发人员必须学习Linux的实际上是错误的术语.我试图纠正它们,但是(不正确的)语言规范被卡住了.

  1. 共享对象:程序启动时自动链接到程序中的库,作为独立文件存在.该库在编译时包含在链接列表中(即:LDOPTS+=-lmylib对于名为的库文件mylib.so).库必须在编译时出现,并在应用程序启动时出现.
  2. 静态库:在构建时合并到实际程序本身的库,用于包含应用程序代码的单个(更大)应用程序和在构建程序时自动链接到程序的库代码,以及包含两者的最终二进制文件主程序和库本身作为单个独立的二进制文件存在.该库在编译时包含在链接列表中(即:LDOPTS+=-lmylib对于名为mylib.a的库文件).库必须在编译时出现.
  3. DLL:基本上相同的共享对象,但是,而不是被包括在编译时链接列表,该库是通过加载dlopen()/ dlsym()命令,以便库不需要存在在构建时对程序进行编译.此外,库不需要在应用程序启动或编译时存在(必要),因为只有在调用dlopen/ dlsym调用时才需要它.
  4. 共享存档:基本上与静态库相同,但使用"export-shared"和"-fPIC"标志进行编译.该库在编译时包含在链接列表中(即:LDOPTS + = - lmylib,LDOPTS+=-lmylibS用于名为mylib mylibS.a.a 的库文件).两者之间的区别在于,如果共享对象或DLL想要将共享存档静态链接到其自己的代码并且能够使共享对象中的函数可用于其他程序而不是仅使用它们,则需要此附加标志. DLL的内部.当有人为您提供静态库,并且您希望将其重新打包为SO时,这非常有用.库必须在编译时出现.

其他更新

" DLL"和" shared library" 之间的区别只是我当时工作的公司(懒惰,不准确)的口语主义(Windows开发人员被迫转向Linux开发,术语卡住),坚持上述说明.

另外,在S"共享档案"的情况下,库名后面的尾随" "字面只是该公司使用的惯例,而不是一般的行业.

c c++ linux dll linker

255
推荐指数
4
解决办法
15万
查看次数

有.dll文件和头文件时如何制作.lib文件

我正在尝试在visual studio中创建一个能够访问已存在的.dll文件的应用程序.我需要应用程序来调用例程.我还有一个已经存在的头文件.

我一直在研究互联网,发现我需要创建一个.lib文件.在这里查看类似的问题我找到了一个链接:http://support.microsoft.com/kb/131313 但是我不能按照指示操​​作.

链接中的信息表示要创建一个DEF文件(我在别处读到这需要编译为具有相同名称的DLL,但不确定该名称是什么,与.dll文件同名?).但我不明白第一个方向,即"使用DUMPBIN/EXPORTS".然后我需要"存根"函数,然后与.OBJ文件有关(我不知道这些文件是什么).

是否有任何分步指导,类似于上面的链接,很容易遵循?

c++ dll header function

43
推荐指数
2
解决办法
5万
查看次数

导入库如何工作以及为什么MinGW不需要它们?

我查看了这个页面:深入了解Win32可移植可执行文件格式

它解释了链接器需要一个导入库,因为编译器无法区分正常函数调用和API函数调用.但是他们也说__declspec(dllimport)将函数调用指定为API调用,以便链接器链接.但是使用此关键字,编译器应该知道这是对API函数的调用.__imp_[function-name]

为什么链接器仍然需要导入库?编译器可以通过预先添加__imp_到函数名称来标记此符号,并且可以调用函数指针(这是一个尚未解析的符号),并且链接器可以替换此符号(因为它看到这是一个API调用) IAT条目的地址.

为什么MinGW-linker直接使用"MinGW-DLLs",但Visual-Studio链接器需要导入库?

在我阅读帖子时,还提出了一些其他问题.在完成与最终可执行文件的链接之前,"dlltool(或链接器)"(无论哪个创建导入库)如何知道IAT条目的位置?我认为IAT条目将在链接时与最终可执行文件一起构建.帖子说,每个API-Call在IAT表中都有一个固定的位置,从不介意将链接多少个DLL.我无法想象如何实现这一目标.

c c++ windows dll linker

9
推荐指数
1
解决办法
959
查看次数

Windows和Linux上的C++ [[gnu :: visibility("default")]] vs __declspec(dllexport)

我需要在C++中创建一些共享库,并使用linux作为我的开发人员操作系统.我知道如果我想通过dlsym/ 加载它们,我需要使符号可见LoadLibrary.所以在linux中我的所有符号都遵循这种模式:

extern "C" [[gnu::visibility("default")]] void f();
Run Code Online (Sandbox Code Playgroud)

我使用了启用了C++ 11的clang,我能够加载f我的宿主程序.当我移动到Windows时,我使用GCC 4.8.2启用了C++ 11,并且该模式也适用于Windows机器LoadLibrary.(我需要使用C++ 11来获取新的属性语法).我知道在Windows上我需要用来__declspec(dllexport)从共享库中导出符号.所以现在怎么办?是__declspec(dllexport)不是不再需要?

编辑:

我发现在这里,那些是同义词(我认为),所以问题是,是否有一个[[gnu::attribute]]用于__declspec(dllimport)避免使用宏和ifdefS代表具体的目标?

c++ attributes visibility declspec

8
推荐指数
1
解决办法
2434
查看次数

标签 统计

c++ ×4

dll ×3

c ×2

linker ×2

attributes ×1

declspec ×1

function ×1

header ×1

linux ×1

visibility ×1

windows ×1