我的项目是通过几个静态库构建的,这些库应该链接到主dll库,从而获得一个单独的dll。
使用__declspec(dllexport)
属性不会导致静态库的指定函数出现在dll中,库根本没有与dll链接。
然后我尝试将每个库构建为共享,以获取导出函数的正确名称,并基于它们创建.def文件。使用.def文件导致结果。
__declspec(dllexport)
和.def-file
应该在我的案件中采取同等行动吗?
是否可以从源生成.def文件?由于我有C ++代码,因为API中的修改和存在类,我不能自己编写.def文件,上面描述的临时生成的dll方法与生产不一致。
我想详细解释一下我项目的结构。该解决方案包含一些项目(模块)。
+
|
+-+ static_lib1
| +
| +--+ src
|
+-+ static_lib2
| +
| +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src
每个子项目都依赖于其他子项目,让我们假设它们没有联系以保持清晰。每个模块都有自己的公共接口。我希望将所有模块作为单个动态库,因此我的工件是dynamic_lib.dll
,但实际上静态库没有与它链接。
答案 0 :(得分:13)
静态库不应包含任何__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
列表。
最后一件事 - 请记住,您还需要包含要使用的函数和对象声明的标题。基本的,我知道,但必须提到。
<强>更新强>
尝试在外部项目中使用dll库时未解析外部
您的问题 与链接完全无关。问题是,你误解了什么,链接静态库完全是。
我猜,您的DLL
不会使用报告为未解析的功能,对吧?但你希望它们在里面,对吗?
当您的DLL
引用外部内容(如函数或变量)时,它会在链接时解析 - 与所有依赖项一起解析。 但这都是。如果您的静态库具有名为print_sample_string()
,但DLL
未使用的函数,则它将不会附加到DLL
图像。仔细想想 - 为什么会这样?
更多 - 明确不是dllexport
ed的函数无论如何都不会显示。函数默认具有外部存储 - 基本上,它们是私有的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
并直接使用它。
答案 1 :(得分:3)