c ++:declspec,静态库和DLL

时间:2017-07-22 20:31:51

标签: c++ dll static

我有一些先前作为DLL发布/编译的第三方开源代码,我想将其重新编译为静态库以包含在我的项目中。

当将第三方代码编译为静态库时,.lib文件会在没有错误的情况下构建,但是当它包含在我的项目中时,我会得到"未解析的外部"几乎每个对静态库中的函数的引用的错误。将库编译为DLL时,不会发生这些错误。

这些错误似乎与我在项目构建阶段得到的LNK4217和LNK4049警告有关,这似乎与第3部分库的标题中的大多数函数都标有__declspec的事实有关( DLLEXPORT)。

我的猜测是' dllexport'将这些函数标记为特定于DLL,因此在静态构建库时它们会被跳过。如何将这些函数包含在库的静态版本中?

3 个答案:

答案 0 :(得分:2)

通常会出现类似API宏的内容。它出现在API标题中,看起来像这样......

// If we are Microsoft C/C++ Compiler
#if defined(_MSC_VER)
    #if defined(DLL_EXPORT)
        #define API __declspec(dllexport)
    #else
        #define API __declspec(dllimport)
    #endif

// If we are non Windows (Export by default) or compiling to a StaticLibrary
#else
    #define API 
#endif

然后,所有API函数都会在声明中使用API宏,而不是原始__declspec(dllexport)

下一步是在Visual Studio中的各种构建配置中,如果配置针对DLL_EXPORT中的DynamicLibrary(DLL),则可以将Project->Properties->Configuration Properties->C/C++->Preprocessor->Preprocessor Definitions定义为预处理器指令。

一个例子......

DLL_EXPORT;%(PreprocessorDefinitions)

您还可以通过运行

来检查公共符号
dumpbin /LINKERMEMBER thing.lib
来自开发人员命令提示符

答案 1 :(得分:0)

你应该把它保存为dll。你正在等待你的时间,并没有任何意义。

那说有一个第二层次的陌生感,因为你可以像使用静态库一样使用dll中的函数。因此,他们会在构建时被引入您的源代码,并且他们不会要求您将整个dll附加到已完成的构建以便执行。就像静态库一样,您使用的部件也会链接在一起,也可以带来轻微的性能提升,因为它不必在程序启动期间在运行时加载它们。它与使用静态库(实际上就是这样,那就是MyDll.dll存在MyDll.lib的原因)完全相同。所以你甚至没有减少最终的二进制文件大小或任何东西。现在考虑一下dll的好处。更新funtionslity很简单,只需将新的dll(如果对你正在使用的开源api进行改进)复制到目录中或者你的代码所期望的地方和那就是它。您甚至可以在运行时加载dll并检查版本控制等,并优雅地处理版本不匹配和其他问题。

答案 2 :(得分:0)

如果您使用VS将第三方代码重新编译为静态库,那么最好创建一个新项目。请注意,static library需要不同的设置。

static library模板下提供了创建Win 32应用程序类型的选项。您可以选择Win32 ConsoleWin32 Projet作为选项。一旦你创建了项目,那么你可以在新项目中包含来自第三方的代码并进行编译。

如果任何类定义使用了__declspec(dllexport),则应将其替换为API,或者不使用任何宏。这是必需的,因为函数不是static library的导出函数,而是嵌入到应用程序中的函数,添加对static library的引用。然后,您可以尝试构建static library

在应用程序项目中添加对此新构建静态库的引用并构建它。