C++ 用dll链接静态库的正确方法
我的项目通过几个静态库构建,这些库应该链接到主dll库,从而获得一个dll 使用C++ 用dll链接静态库的正确方法,c++,visual-c++,dll,visual-studio-2013,declspec,C++,Visual C++,Dll,Visual Studio 2013,Declspec,我的项目通过几个静态库构建,这些库应该链接到主dll库,从而获得一个dll 使用\uuuu declspec(dllexport)属性不会导致静态库的指定函数出现在dll中,库根本不与dll链接 然后,我尝试将每个库构建为共享库,以获取导出函数的正确名称,并基于它们创建.def文件。使用导致结果的.def文件 \uuu declspec(dllexport)和.def文件在我的情况下是否应该同样起作用 是否可以从源代码生成.def文件?因为我有C++代码,我自己不能编写.DEF文件,因为API中
\uuuu declspec(dllexport)
属性不会导致静态库的指定函数出现在dll中,库根本不与dll链接
然后,我尝试将每个库构建为共享库,以获取导出函数的正确名称,并基于它们创建.def文件。使用导致结果的.def文件
\uuu declspec(dllexport)
和.def文件
在我的情况下是否应该同样起作用每个子项目都弱地依赖于其他子项目,让我们假设它们之间没有清晰的联系。每个模块都有自己的公共接口。我希望将所有模块都作为单个动态库,因此我的工件是
动态库.dll
,但实际上静态库不与之链接。静态库不应包含任何\u declspec
或\u属性((dll…)
内容。它们不过是多个对象文件(通常是*.obj
或*.o
),组成一个单独的文件
要使用这样的库(无论是在.exe
还是.dll
中),您所需要做的就是包含适当的头并将它们链接起来—使用Visual Studio,这非常简单
首先,您需要知道1)静态库的位置和2)它们的确切名称。转到“项目属性”,然后单击“常规”Target name
包含输出文件的名称,而output directory
指示将把.lib
放在哪个文件夹中
注意:每个项目的路径可能不同!对于多项目解决方案,我总是将其设置为公共路径以避免配置问题
现在,转到将使用此库的项目的属性(与之链接)。转到链接器
->输入
,然后将.lib
的名称添加到其他依赖项
(条目用分号分隔):
您需要添加要链接的所有库。此外,放置这些库的文件夹必须添加到链接器->常规->其他库目录中。如果所有.lib
都放在同一个位置-好,否则将它们复制到共享位置或将多个条目添加到其他库目录
列表中
最后一件事——记住,您还需要包含带有您想要使用的函数和对象声明的头。基本的事情,我知道,但必须提到
更新
尝试在外部产品中使用dll库时未解析的外部
你的问题根本与链接无关。问题是,您误解了链接静态库的作用
我猜,报告为未解析的函数不会被您的DLL
使用,对吗?但你希望他们在里面,对吗
当您的DLL
引用外部内容(如函数或变量)时,将在链接时解析该内容以及所有依赖项但仅此而已。如果您的静态库有一个名为print\u sample\u string()
,的函数,但您的DLL
没有使用它,则它不会附加到DLL
图像。仔细想想,为什么会这样
更重要的是,没有显式地dllexport
ed的函数无论如何都不会可见。默认情况下,函数具有外部存储—因此基本上,它们是私有的DLL
内容
因此,为了直接回答您的问题,如果您需要使用静态库1.lib
中的函数/变量,请将其附加到客户端应用程序,就像您现在将其附加到动态库一样。没有别的办法(*)
(*)确切地说,是有的。您可以在DLL
中创建中间函数,将其导出并在内部调用所需函数:
在动态库中的某个地方
:
DLL_EXP_IMP long CallFunctionFromA_Lib()
{
return some_function(); //this function is from static_lib1.lib
}
long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib
在.exe
中的某处:
DLL_EXP_IMP long CallFunctionFromA_Lib()
{
return some_function(); //this function is from static_lib1.lib
}
long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib
然而,我无法想象,为什么您要这样做,而不是简单地链接A.lib
并直接使用它。Raymond Chan解释了这种行为,最好的解决方案就是使用def文件。至于如何为静态库自动生成它,讨论看起来是一个很好的起点。谢谢!但我有相同的配置。我的问题是库之间没有相互使用代码,每个库都是单独的模块,使用自己的公共接口,因此链接器忽略了其他静态库,除了主要的oneUpdate问题,其中包含关于您有哪些库、您希望使用哪些库(以及哪些库)以及您得到的错误的确切信息。我不明白除了主库之外,链接器忽略其他静态库是什么意思。问题:你说的[…]库根本没有与dll链接。您是否在dynamic_-lib
或另一个使用dynamic_-lib的项目中遇到错误?尝试在外部prodjectsLink中使用dll库时,此错误是否为未解析的外部[…]
?未解析的外部
。