我有一些先前作为DLL发布/编译的第三方开源代码,我想将其重新编译为静态库以包含在我的项目中。
当将第三方代码编译为静态库时,.lib文件会在没有错误的情况下构建,但是当它包含在我的项目中时,我会得到"未解析的外部"几乎每个对静态库中的函数的引用的错误。将库编译为DLL时,不会发生这些错误。
这些错误似乎与我在项目构建阶段得到的LNK4217和LNK4049警告有关,这似乎与第3部分库的标题中的大多数函数都标有__declspec的事实有关( DLLEXPORT)。
我的猜测是' dllexport'将这些函数标记为特定于DLL,因此在静态构建库时它们会被跳过。如何将这些函数包含在库的静态版本中?
答案 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 Console
或Win32 Projet
作为选项。一旦你创建了项目,那么你可以在新项目中包含来自第三方的代码并进行编译。
如果任何类定义使用了__declspec(dllexport)
,则应将其替换为API
,或者不使用任何宏。这是必需的,因为函数不是static library
的导出函数,而是嵌入到应用程序中的函数,添加对static library
的引用。然后,您可以尝试构建static library
。
在应用程序项目中添加对此新构建静态库的引用并构建它。