'LIBCMT'与其他库的使用冲突 + 未解决的外部符号问题

26

我有一个使用OpenGL 3.2(+库)和FreeType2的程序,还有另一个使用Boost和OpenSSL的程序。 OpenGL方面是为了确保文字可以呈现,而boost / openssl程序则是用于进行安全登录/游戏服务器。

这两个程序都单独运行良好。

但是,将Boost和OpenSSL添加到游戏(GL + freetype)项目中会导致连接失败。

我已经链接了以下库,并包含其包含文件夹。

glimg.lib glutil.lib glfw.lib opengl32.lib freetype.lib glew32.lib user32.lib libeay32.lib ssleay32.lib

链接错误如下。

1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>libeay32.lib(cryptlib.obj) : error LNK2001: unresolved external symbol __imp__DeregisterEventSource@4
1>libeay32.lib(cryptlib.obj) : error LNK2001: unresolved external symbol __imp__ReportEventA@36
1>libeay32.lib(cryptlib.obj) : error LNK2001: unresolved external symbol __imp__RegisterEventSourceA@8
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__DeleteDC@4
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__DeleteObject@4
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__GetBitmapBits@12
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__BitBlt@36
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__GetObjectA@12
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__SelectObject@8
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__CreateCompatibleBitmap@12
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__GetDeviceCaps@8
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__CreateCompatibleDC@4
1>libeay32.lib(rand_win.obj) : error LNK2001: unresolved external symbol __imp__CreateDCA@16
1>.\BasicTexture.exe : fatal error LNK1120: 13 unresolved externals

运行库设置为多线程 DLL (/MD)。

我不知道该怎么做,非常感谢任何帮助。


3
未解决的外部引用是由于未链接到所需的库(Advapi32.libGdi32.lib)。第一个警告表明,您的项目及其一些链接的库与CRT在链接器设置方面不兼容。除此之外,似乎您没有编译Unicode版本。是否有原因呢? - IInspectable
谢谢Tim。我不确定Unicode的问题,我只是使用premake4来创建VS solution并更改了所需的任何内容(我已选择了Unicode)。你想把它作为答案吗,因为你已经解决了它!生成成功。非常感谢你! :) - Andrew
2个回答

34

您试图使用/MD进行编译,这可能是正确的选择,但某些代码(可能是其中一个库)使用/MT构建,因此在同一程序中不能同时使用两种方法。 您需要找出哪个库是使用/MT构建的,并使用/MD重新构建它。


2
如果你没有源代码,链接你的项目时请使用/MT - AShelly
感谢您的回复,问题已经在大约一个小时前由Tim在评论中解决。我想给他答案接受。但是+1。因为在发布问题之前,我确实检查了所有内容是否都是MD线程的。 - Andrew

31

当编译器生成引用外部定义的对象或函数的代码而链接器无法找到它们时,会产生未解决的外部错误消息。为了生成调用函数的代码,编译器只需要一个声明:

extern "C" BOOL DeregisterEventSource ( HANDLE hEventLog );

这些信息足以生成一个call指令(目标地址除外)。extern关键字告诉编译器实现在其他地方定义,因此它无法知道需要填写的目标地址。编译器完成后,连接器将把各个部分连接起来,并使用从导入库收集到的信息查找所需的偏移量。

Windows API调用在错误日志中很容易被发现。它们具有__imp__前缀,有时还带有AW后缀,后面跟着@<n>,其中<n>表示参数所需的字节数。在Windows API调用的情况下,您可以在MSDN中查找该函数(如DeregisterEventSource)。在底部是要求,您可以查找导入库名称。

冲突警告表明并非所有模块都使用相同的运行时库。即使这只是一个警告,它也是一个严重的问题,应该得到解决。如果混合使用/ MD / MT 编译器开关,或者混合使用发布和调试运行时库(如/ MD / MDd ),则会收到此警告。要诊断此消息,您可以使用/ VERBOSE:LIB链接器开关来确定链接器正在搜索哪些库。有关此警告的其他信息可以在这个MSDN链接中找到。


3
对于指出 "imp" 前缀暗示着 Windows API 调用的洞见点赞。我之前在连接器错误中看到过这个前缀,但不知道它为什么被添加到符号前面。 - riderBill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接