在 Visual Studio 2013 上遇到过,但可以在任何版本中重现.
Encountered on Visual Studio 2013, but it's reproducible with any version.
我从 github 克隆了协议缓冲区库,在其上运行了 CMake-gui(我将所有内容都保留为默认值,所以它是静态版本),只构建了 libprotobuf(其他项目由于某种原因失败,cmd.exe 错误,可能有与测试有关,但 libprotobuf 构建良好).
I cloned the protocol buffer library from github, ran CMake-gui on it (I left everything to default, so it's the static version), only built libprotobuf (other project failed for some reason, cmd.exe error, might have something to do with tests, but libprotobuf builds fine).
我的项目使用在 mapbox 矢量切片规范的 github 上找到的 .proto 文件生成的标头.
My project uses headers generated with the .proto file found on the mapbox vector tiles spec's github.
当我链接时,我首先遇到这个错误
When I link, I first have this error
错误 1 错误 C4996:'std::_Copy_impl':带有可能不安全的参数的函数调用 - 此调用依赖于调用者来检查传递的值是否正确.要禁用此警告,请使用 -D_SCL_SECURE_NO_WARNINGS.请参阅有关如何使用 Visual C++ 'Checked Iterators' s:program files (x86)microsoft visual studio 12.0vcincludexutility 的文档
我尝试在其他命令行参数中使用 -D_SCL_SECURE_NO_WARNINGS
禁用它,但随后出现了其他错误:
I tried disabling it with -D_SCL_SECURE_NO_WARNINGS
in additional command line arguments, but then I have other errors:
Error 1 error LNK2038: mismatch detection for 'RuntimeLibrary': value 'MTd_StaticDebug' 与 main.obj S:eiogit3misc-projsmaploadmaploadlibprotobufd.lib 中的值 'MDd_DynamicDebug' 不匹配(common.obj)
VStudio C(和 C++)运行时库 (VCRTLib 或 UCRT - 检查 libprotobuf 项目.让我详细说明:
It's a mismatch of how the VStudio C (and C++) RunTime Library (VCRTLib or UCRT - check [SO]: How to circumvent Windows Universal CRT headers dependency on vcruntime.h (@CristiFati's answer)) is used by your project and by libprotobuf project. Let me detail:
假设有一些 C (C++) 代码.该代码的目的是运行.比可以实现的:
Let's say there's some C (C++) code. The purpose of that code is to be run. Than can be achieved:
您可以查看[SO]: LNK2005 Error in CLR Windows Form(@CristiFati 的回答) 有关如何将 C (C++) 代码转换为可执行格式的详细信息.此外,Google 充满了关于静态库和动态库之间差异的文章,何时使用其中一个,可以在 [SO]:何时使用动态库与静态库.
You can check [SO]: LNK2005 Error in CLR Windows Form (@CristiFati's answer) for details of how C (C++) code gets to be transformed in executable format. Also Google is full of articles about differences between static and dynamic libraries, when to use one or the other, an example can be found on [SO]: When to use dynamic vs. static libraries.
如您所料,CRT 或 C 运行时库(包含使 C能够运行的代码——一个例子是内存管理函数:malloc、free) 也不例外——它相当于 Nix 的 libc.a(静态或存档)与 libc.so(动态或共享对象) - 但在 VStudio 中它有点复杂:
As you guessed, the CRT or C RunTime library (that contains the underlying system that makes C code able to run - one example are memory management functions: malloc, free) makes no exception - it's the equivalent of Nix's libc.a (static or archive) vs. libc.so (dynamic or shared object) - but in VStudio it's a little bit more complicated:
注意事项:
现在,UCRT 部分不像任何其他库一样包含在项目中(项目属性 -> 链接器 -> 输入 -> 附加依赖项),但是因为它们的性质(静态或动态)在编译时是必需的,所以它们被配置为:[MS.Docs]:/MD、/MT、/LD(使用运行时库),其中有 4 个可用选项:>
Now, UCRT parts, are not included in the project like any other lib (Project Properties -> Linker -> Input -> Additional Dependencies), but because their nature (static or dynamic) is required at compile time they are configured from: [MS.Docs]: /MD, /MT, /LD (Use Run-Time Library), where there are 4 available choices:
显然,包含Debug"的那些是在为 Debug 配置构建而其他用于 Release 时;关键是那些有DLL的使用的是动态运行时版本,而其他的是静态版本.
Obviously, the ones that contain "Debug" are when building for Debug configuration while the other ones for Release; the key point is that the ones that have DLL are using the dynamic runtime version, while the other ones the static version.
回到你的错误:链接器抱怨main.obj(你项目的一部分)有MDd_DynamicDebug(链接到动态调试版本),而common.obj(libprotobuf 项目的一部分)具有MTd_StaticDebug(链接到 静态调试 版本),因此您链接到同一个可执行文件(或 .dll)中的 2 个运行时 - 这是不可能的.
Back to your error: the linker complains that main.obj (part of your project) has MDd_DynamicDebug (linking against the dynamic debug version), while common.obj (part of libprotobuf project) has MTd_StaticDebug (linking against the static debug version), so you link against 2 runtimes in the same executable (or .dll) - which is not possible.
为了修复它,您应该确保 libprotobuf 和您的主项目对于 UCRT 具有相同的值.
当然,更改更简单您的主要项目设置与 libprotobuf 的设置相匹配,但建议使用动态运行时版本(在涉及 .dll 的大型项目中,事情可能会变得混乱)甚至如果这需要重新编译 libprotobuf(好吧,如果更改该选项会产生错误,使 libprotobuf 很难构建,并且您的项目将保持如此简单,您可以使用静态UCRT).
In order to fix it, you should make sure that both libprotobuf and your main project have the same value for UCRT.
Of course it's simpler to change your main project setting to match libprotobuf's one, but it's recommended to use the dynamic runtime version (things can get messy in larger projects that have .dlls involved) even if this requires to recompile libprotobuf (well, if changing that option generates errors that make libprotobuf very hard to build, and your project is going to stay this simple, you can use the static UCRT).
注意:不要将 UCRT 类型(静态/动态)误认为 libprotobuf 的构建方式(此时是静态的,但是我相信它也可以构建为动态的).
Note: Not to mistake UCRT type (static / dynamic) with the way libprotobuf is being built (static at this point, but I'm sure that it can be built as dynamic too).
在上面的注释中添加一些额外的信息,因为一些评论要求它,它可能对其他用户有用.
Adding some additional info on the above note, as some comments requested it, and it might be useful to other users.
关于库(包括libprotobuf)有两个方面完全不相关:
There are 2 aspects about a library (including libprotobuf), that are totally unrelated:
因此,有 4 种完全有效的组合:
So, there are 4 perfectly valid combinations:
对于 libprotobuf,每个方面都由一个布尔 cmake 选项控制:
For libprotobuf, each of the aspects is controlled by a boolean cmake option:
可以通过以下任一方式设置 2 个标志:
The 2 flags can be set by either:
-Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF
)-Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF
)上述 4 种组合因此可能(至少在 v3.5 中),但是#2. 默认禁用(指定 -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_MSVC_STATIC_RUNTIME=ON
将构建一个 .dll动态 UCRT),以避免可能的运行时问题,启用它需要手动干预.
The above 4 combinations are thus possible (at least in v3.5), but #2. is disabled by default (specifying -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_MSVC_STATIC_RUNTIME=ON
will build a .dll which will link to the dynamic UCRT), in order to avoid possible runtime problems, and enabling it requires manual intervention.
有关构建说明的更多详细信息(通过 cmake),请查看:[GitHub]: protocolbuffers/protobuf - (master) protobuf/cmake/README.md.
For more details regarding build instructions (via cmake), check: [GitHub]: protocolbuffers/protobuf - (master) protobuf/cmake/README.md.
#1:只有在库导出符号时才会创建.lib文件, 因为否则它没有意义(链接时不需要任何东西,并且 .dll 将被创建,但几乎无法使用)
#1: The .lib file will only be created if the library exports symbols, as it wouldn't make sense otherwise (nothing needed at link time, and the .dll will be created, but pretty much unusable)
#2:对于较新的 VStudio 版本(从 v2015 开始em>),msvcr(t) 部分已被替换为 vcruntime(或者至少这是入口点,因为它被分成更小的逻辑部分(检查开头的 URL))
这篇关于链接到 MS Visual C 上的 protobuf 3 时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!