在Visual Studio 2013 上遇到,但它可以在任何版本中重现。
我从github克隆了协议缓冲库,在其上运行了CMake-gui(我将所有内容保留为默认值,因此它是静态版本),只构建了libprotobuf(其他项目由于某种原因失败了,cmd.exe错误,可能与测试有关,但libprotobuf构建正常)。
我的项目使用在mapbox矢量图块规范的github上找到的.proto文件生成的标题。
当我链接时,我首先出现此错误
Error 1 error C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' s:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility
我尝试在其他命令行参数中使用-D_SCL_SECURE_NO_WARNINGS
禁用它,但之后我还有其他错误:
Error 1 error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in main.obj S:\eiogit3\misc-projs\mapload\mapload\libprotobufd.lib(common.obj)
答案 0 :(得分:7)
VStudio C(和C ++)运行时库( VCRTLib - 检查[SO]: How to circumvent Windows Universal CRT headers dependency on vcruntime.h (@CristiFati's answer)不匹配)由您的项目和 libprotobuf 项目使用。让我详细说明一下:
让我们说一些 C 代码。该代码的目的是运行。比可以实现:
您可以查看[SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer),了解 C 代码如何以可执行格式转换的详细信息。此外 Google 还有很多关于静态库和动态库之间差异的文章,何时使用其中一个,可以在[SO]: When to use dynamic vs. static libraries上找到一个示例。
正如您所猜测的那样, CRT 或 C运行时库(包含使 C 的基础系统能够运行的代码 - 一个例子是内存管理功能: malloc , free )也不例外 - 它相当于 Ux &#39> libc.a (静态或存档)与 libc.so (动态或共享对象) - 但在 VStudio 中& #39;有点复杂:
备注强>:
现在, VCRTLib 部分不像任何其他lib一样包含在项目中(项目属性 - >链接器 - >输入 - >附加依赖项),但由于在编译时需要它们的性质(静态或动态),因此它们的配置来自:[MS.Docs]: /MD, /MT, /LD (Use Run-Time Library),其中有4个可用选项:
显然,那些包含" Debug"在构建 Debug 配置时,其他用于 Release ;关键点是 DLL 的那些使用动态运行时版本,而其他版本使用静态版本。
返回错误:链接器抱怨 main.obj (项目的一部分) MDd_DynamicDebug (链接到动态调试版本),而 common.obj ( libprotobuf 项目的一部分)有 MTd_StaticDebug < / em> (链接到静态调试版本),因此您可以在同一个可执行文件(或 .dll )中链接2个运行时 - 这是不可能的
为了解决这个问题,您应该确保 libprotobuf 和您的主项目都具有 VCRTLib 的相同值。
当然它&#39 ;更容易更改主项目设置以匹配 libprotobuf 的一个,但建议使用动态运行时版本(在具有<的大型项目中,事情会变得混乱em> .dll 参与其中)即使这需要重新编译 libprotobuf (好吧,如果更改该选项会产生使 libprotobuf 很难构建的错误,以及您的项目将保持这么简单,您可以使用静态 VCRTLib )。
注意:不要错误地将 VCRTLib 类型(静态/动态)与 libprotobuf 构建错误(此时是静态的,但是我确信它也可以构建为动态的。)
<强> @ EDIT0 强>:
在上面的注释中添加一些额外的信息,就像一些评论所要求的那样,它可能对其他用户有用。
库有两个方面(包括 libprotobuf ),完全不相关:
所以,有4种完全有效的组合:
对于 libprotobuf ,每个方面都由布尔 cmake 选项控制:
可以通过以下任一方式设置2个标志:
-Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF
)以上4种组合因此可能(至少在 v 3.5 中),但 #2。< / em> 默认情况下已停用(指定-Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_MSVC_STATIC_RUNTIME=ON
将构建一个 .dll ,它将链接到动态 VCRTLib ),为了避免可能的运行时问题,并启用它需要手动干预。
有关构建说明的详细信息(通过 cmake ),请检查:[GitHub]: protocolbuffers/protobuf - (master) protobuf/cmake/README.md。
1 :只有在库导出符号时才会创建 .lib 文件,否则它将无法理解(链接时不需要, .dll 将被创建,但几乎无法使用)
2 :对于较新的 VStudio 版本(从 2015 开始), msvcr(t) 部分已被 vcruntime 取代(或者至少这是入口点,因为它被分成较小的逻辑部分)