【问题标题】:Proper way to link static libraries with dll将静态库与 dll 链接的正确方法
【发布时间】:2015-10-05 10:27:39
【问题描述】:

我的项目是通过几个静态库构建的,这些静态库应该链接到主 dll 库,因此获得了一个 dll。

使用__declspec(dllexport)属性不会导致静态库的指定功能出现在dll中,库根本没有与dll链接。

然后我尝试将每个库构建为共享库,以获取导出函数的正确名称并基于它们创建 .def 文件。使用 .def 文件会导致结果。

  1. 在我的情况下,__declspec(dllexport).def-file 是否应该同等对待?

  2. 是否可以从源代码生成 .def 文件?由于我有 C++ 代码,由于 API 中的修饰和存在类,我无法自己编写 .def 文件,因此上述使用临时生成的 dll 的方法与生产不一致。

更新

我想详细解释一下我的项目的结构。该解决方案由几个项目(模块)组成。

+ 
|    
+-+ static_lib1                                          
|       +                                                
|       +--+ src                                         
|                                                        
+-+ static_lib2                                          
|       +                                                
|       +--+ src                                         
|                                                        
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
        +                                                
        +--+ src

每个子项目都弱依赖于其他子项目,为了清楚起见,我们假设它们没有连接。每个模块都有自己的公共接口。我想将所有模块作为单个动态库,所以我的工件是dynamic_lib.dll,但实际上静态库并没有与之链接。

【问题讨论】:

  • 问题:你说[...] libraries not linked with dll at all。您是否在dynamic_lib另一个项目 中遇到错误,即使用 dynamic_lib?这个错误是unresolved external [...]吗?
  • unresolved external 在外部项目中尝试使用 dll 库时

标签: c++ visual-c++ dll visual-studio-2013 declspec


【解决方案1】:

HereRaymond Chan 解释了这种行为,最好的解决方案实际上就是使用 def 文件。至于如何为静态库自动生成它 - this 讨论看起来是一个很好的起点。

【讨论】:

  • 链接已过时。
【解决方案2】:

静态库不应包含任何__declspec__attribute((dll...)) 的东西。它们只不过是多个目标文件(通常是 *.obj*.o),组合成一个单独的文件。

要使用此类库(.exe.dll),您需要做的就是包含正确的标头并链接它们 - 使用 Visual Studio 非常简单。

首先,您需要知道1)静态库的放置位置以及2)它们的确切名称。转到项目属性,然后转到GeneralTarget name 包含输出文件的名称,而Output directory 表示您的.lib 将放置在哪个文件夹中。

注意:每个项目的路径可能不同!对于多项目解决方案,我总是将其设置为公共路径以避免配置问题。

现在,转到项目的属性,它将使用这个库(链接到它)。转到Linker -> Input,然后将.lib 的名称添加到Additional dependencies(条目以分号分隔):

您需要添加所有要链接的库。此外,放置这些库的文件夹必须添加到Linker -> General -> Additional library directories。如果所有 .libs 都放在同一个地方 - 很好,否则将它们复制到共享位置或将多个条目添加到 Additional library directories 列表中。

最后一件事 - 请记住,您还需要包含要使用的函数和对象声明的标题。基本的东西,我知道,但必须提及。


更新

尝试在外部项目中使用 dll 库时无法解析外部

您的问题与链接完全无关。问题是,您误解了链接静态库的作用确实如此

我猜,你的DLL 没有使用报告为unresolved 的函数,对吧?但你希望他们在里面,对吧?

当您的DLL 引用外部内容(如函数或变量)时,它会在链接时解析 - 连同所有依赖项。 仅此而已。如果您的静态库有一个名为 print_sample_string() 的函数,但您的 DLL 不使用它,它将不会附加到 DLL 图像。仔细想想 - 为什么会这样?

甚至更多 - 不是dllexported 明确的函数无论如何都不会可见。函数默认具有外部存储 - 所以基本上,它们是私有 DLL 的内容。

所以要直接回答您的问题 - 如果您需要使用来自 static_lib1.lib 的函数/变量,请将其附加到客户端应用程序 - 就像您现在将其附加到 dynamic_lib 一样。没有其他办法。 (*)


(*) 说真的 - 有。您可以在DLL 中创建中间函数,将其导出并在其中调用所需的函数:

dynamic_lib的某个地方:

DLL_EXP_IMP long CallFunctionFromA_Lib()
{
     return some_function(); //this function is from static_lib1.lib
}

.exe的某个地方:

long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib

但是,我无法想象,您为什么要这样做而不是简单地链接 A.lib 并直接使用它。

【讨论】:

  • 谢谢!但我有相同的配置。我的问题是库不使用其他代码,每个库都是单独的模块,使用自己的公共接口,因此链接器忽略除主库之外的其他静态库
  • 更新问题,提供有关您拥有哪些库、您希望使用其他库(以及哪些库)以及您遇到的错误的确切信息。我不明白linker ignores others static libraries except main one 是什么意思。
猜你喜欢
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多