我的项目通过几个静态库构建而成,这些静态库应该链接到主dll库,从而获得一个单独的dll。
使用__declspec(dllexport)
属性不会导致将静态库的指定功能显示为dll,而这些库完全未与dll链接。
然后,我尝试将每个库构建为共享库,以获取导出函数的正确名称,并基于它们创建了.def文件。使用.def文件导致结果。
__declspec(dllexport)
和.def-file
是否应表现相同? 更新资料
我想详细解释一下我的项目的结构。该解决方案由几个项目(模块)组成。
+
|
+-+ static_lib1
| +
| +--+ src
|
+-+ static_lib2
| +
| +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src
每个子项目几乎都依赖于其他子项目,为了清晰起见,我们假设它们未连接。每个模块都有自己的公共(public)接口(interface)。我希望将所有模块作为单个动态库,因此我的工件是
dynamic_lib.dll
,但实际上静态库未与其链接。 最佳答案
静态库不应包含任何__declspec
或__attribute((dll...))
内容。它们不过是组成一个文件的多个目标文件(通常是*.obj
或*.o
)。
要使用此类库(在.exe
或.dll
中),您需要做的就是包括适当的头并将其链接-使用Visual Studio相当简单。
首先,您需要知道 1)静态存储库的位置和 2)的确切名称。转到项目属性,然后转到General
。 Target name
包含输出文件的名称,而Output directory
指示将.lib
放置在哪个文件夹中。
注意:对于每个项目,此路径可能有所不同!对于多项目解决方案,我总是将其设置为通用路径以避免配置问题。
现在,转到项目的属性,该属性将使用此库(与其链接)。转到Linker
-> Input
,然后将.lib
的名称添加到Additional dependencies
(条目以分号分隔):
您需要添加要链接的所有库。此外,必须将放置这些库的文件夹添加到Linker
-> General
-> Additional library directories
中。如果所有.lib
都放置在同一位置-很好,否则将它们复制到共享位置或将多个条目添加到Additional library directories
列表中。
最后一件事-请记住,您还需要包含要使用的带有函数和对象声明的 header 。我知道基本的事情,但必须提及。
更新
您的问题是而不是与链接完全无关。事实是,您误解了什么,链接静态库确实可以实现。
我猜想,您的DLL
未使用报告为 Unresolved 功能,对吧?但是您希望它们位于其中,对吗?
当DLL
引用外部内容(如函数或变量)时,它将在链接时连同所有依赖项一起解析。 但这就是。如果您的静态库具有一个名为print_sample_string()
,的函数,但您的DLL
不使用它,则它将不会附加到DLL
图像上。仔细考虑一下-为什么会这样?
甚至更多-未经过dllexport
明确定义的函数也将始终不可见。函数默认具有外部存储-因此,基本上,它们是私有(private)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
并直接使用它。关于c++ - 用DLL链接静态库的正确方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31446363/