用DLL链接静态库的正确方法 [英] Proper way to link static libraries with dll
问题描述
我的项目通过几个静态库构建,这些静态库应该链接到主dll库,从而获得一个单独的dll。
My project builds through few static libraries which should linked to main dll library gain one single dll as a result.
使用 __ declspec(dllexport )
属性不会导致将静态库的指定功能显示为dll,而根本没有与dll链接的库。
Using __declspec(dllexport)
attribute does not lead to appearance of specified functions of static libraries to dll, libraries not linked with dll at all.
然后,我尝试构建每个共享库,以获取导出函数的正确名称,并基于它们创建.def文件。使用.def文件导致结果。
Then I tried to build each library as shared for getting proper names of exported functions and created .def file based on them. Using .def file leaded to result.
-
应该
__ declspec(dllexport)
和.def文件
在我的情况下是否同样起作用?
Should
__declspec(dllexport)
and.def-file
act equally in my case?
是否可以从源代码生成.def文件?由于我有C ++代码,由于API中的损坏和状态类,我无法自己编写.def文件,因此上述使用临时生成的dll的方法在生产中是不一致的。
Is it possible to generate a .def file from sources? Since I have C++ code I'm not able to write .def file by myself because of mangling and presence classes in API, the approach described above with temporary generated dlls is inconsistent for production.
更新
我想详细解释一下我的项目的结构。该解决方案由几个项目(模块)组成。
Update
I'd like to explain in detail about the structure of my project. The solution consists of a few projects (modules).
+
|
+-+ static_lib1
| +
| +--+ src
|
+-+ static_lib2
| +
| +--+ src
|
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
+
+--+ src
每个子项目几乎都依赖于其他项目,为了清楚起见,我们假设它们未连接。每个模块都有自己的公共接口。我想将所有模块都作为单个动态库,因此我的工件是 dynamic_lib.dll
,但实际上静态库未与其链接。
Each sub-project weakly depends on others, let's assume they are not connected for clearness. Each module has own public interface. I want to have all modules as single dynamic library so my artifact is dynamic_lib.dll
, but in fact static libraries are not linked with it.
推荐答案
静态库不应包含任何 __ declspec
或 __ attribute((dll .. 。)
东西。它们不过是多个目标文件(通常是 *。obj
或 *。o
),它们组成一个文件,一个文件文件。
Static libraries should not contain any __declspec
or __attribute((dll...))
things. They are nothing more than multiple object files (usually *.obj
or *.o
), composed into one, single file.
使用此类库所需要做的一切(在 .exe
或<$ c中$ c> .dll )是要包含适当的头并将其链接-使用Visual Studio相当容易。
All you need to do in order to use such library (either in .exe
or .dll
) is to include proper headers and link them - with Visual Studio it's pretty easy.
首先,您需要了解 1)静态库的位置以及 2)的确切名称。转到项目属性,然后选择常规
。 目标名称
包含输出文件的名称,而输出目录
表示在哪个文件夹中。 lib
将被放置。
First of all, you need to know 1) where your static libraries are placed and 2) their exact names. Go to project properties and then General
. Target name
contains name for the output file, while Output directory
indicates in which folder your .lib
will be placed.
注意: 项目!对于多项目解决方案,我总是将其设置为通用路径以避免配置问题。
Note: This path may be different for every project! For multi-project solution, I always set this to a common path to avoid configuration problems.
现在,转到项目的属性,这将消耗此库(链接为它)。转到链接器
-> 输入
,然后添加 .lib $ c的名称$ c>到
其他依赖项
(条目之间用分号分隔):
Now, go to properties of project, that will consume this library (link with it). Go to Linker
-> Input
and then add name of your .lib
to Additional dependencies
(entries are separated with semicolon):
您需要添加所有要链接的库。而且,文件夹这些库所在的位置,必须添加到链接器
-> 常规
-> 附加库目录
。如果所有 .lib
都放在同一位置-很好,否则将它们复制到共享位置或将多个条目添加到其他库目录
列表。
You need to add all libraries you want have linked in. Also, folder, in which these libraries are placed, must added to Linker
-> General
-> Additional library directories
. If all .lib
s are placed in the same place - good, otherwise copy them into shared location or add multiple entries to Additional library directories
list.
最后一件事-请记住,您还需要包括要使用的带有函数和对象声明的标头。我知道基本的东西,但必须提及。
And the last thing - remember, that you also need to include headers with declarations of functions and objects, that you want to use. Basic thing, I know, but has to be mentioned.
更新
在外部项目中尝试使用dll库时未解析的外部
unresolved external when trying to use dll library in an external prodjects
您的问题根本与链接无关。问题是,您误解了什么,链接静态库确实确实。
Your problem is not related to linking at all. The thing is, that you misunderstood what, linking a static library exactly does.
我猜,该函数报告为 unsolved 不是您的 DLL
使用的,对吗?但是,您希望它们位于其中,对吗?
I am guessing, that functions reported as unresolved are not used by your DLL
, right? But you expect them to be inside it, right?
当您的 DLL
引用外部内容(例如函数)时,或变量),它会在链接时连同所有依赖项一起解析。 但是就这些。如果您的静态库具有名为 print_sample_string()
的函数,则但您的 DLL
不使用它 strong>,它将不会附加到 DLL
图片。
When your DLL
refers to an external content (like function or variable), it is resolved at linking time - together with all dependencies. But that's all. If your static library has a function named print_sample_string()
, but your DLL
does not use it, it won't be attached to DLL
image. Think about this carefully - why should it be?
甚至更多-未明确赢得 dllexport
功能的函数?无论如何都不可见。函数默认具有外部存储-因此,基本上,它们是私有 DLL
的内容。
Even more - functions, that are not dllexport
ed explicitly won't be visible anyway. Functions have by default external storage - so basically, they are private DLL
's content.
所以要回答您的问题直接提问-如果您需要使用 static_lib1.lib
中的函数/变量,请将其附加到客户端应用程序-就像您现在将其附加到 dynamic_lib
。没有别的办法了。 (*)
So to answer your question directly - if you need to use functions/variables from static_lib1.lib
, attach it to client application - just like you are attaching it now to dynamic_lib
. There is no other way. (*)
(*)是。您可以在 DLL
中创建中间函数,然后将其导出并在其中调用所需的函数:
(*) Truly speaking - there is. You can create intermediate function in DLL
, that is exported and call desired function inside:
在 dynamic_lib
:
Somewhere in dynamic_lib
:
DLL_EXP_IMP long CallFunctionFromA_Lib()
{
return some_function(); //this function is from static_lib1.lib
}
<$>中的某个位置c $ c> .exe :
Somewhere in .exe
:
long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib
调用函数,但是我无法想象,为什么您想要执行此操作,而不仅仅是链接 A.lib
并直接使用它。
I can't imagine, however, why would you want to do this and not simply link A.lib
and use it directly.
这篇关于用DLL链接静态库的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!