本文主要是介绍C++工程编译链接错误汇总VisualStudio,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
一些小的知识点
make工具
可以使用windows下的事件查看器崩溃的地方
dumpbin工具查看dll是32位还是64位的
_MSC_VER
.cc 和.cpp
【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了
include<> 和 include""
WinMain 和 main 和 AfxWinMain
_tWinMain 和 wWinMain 和 WinMain
stdafx 的介绍
char 和 wchar之间的转化
manifest文件和mt工具
一些错误
error C2011: 'SteamworksSDKHelper' : 'class' type redefinition 1> d:\xxx\source\source\SteamworksSDK/SteamworksSDKHelper.h(6) : see declaration of 'SteamworksSDKHelper'
1>c1xx : fatal error C1083: Cannot open source file: 'simple_handler.cc': No such file or directory
error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0'
"error C2220: warning treated as error - no 'object' file generated"的解决办法
msvcprt.lib(MSVCP100.dll) : error LNK2005: already defined in JSONCPP.lib(json_writer.obj)
不同版本编译器编出来的library可以混用吗
一些链接错误
一些编译错误
1) C1189 #error: /RTCc rejects conformant code, so it is not supported by the C++ Standard Library. Either remove this compiler option, or define _ALLOW_RTCc_IN_STL to acknowledge that you have received this warning.
2)error C2039: “unique_ptr”: 不是“std”的成员
3)c1xx : fatal error C1083: 无法打开源文件:“lllll”: No such file or directory
4)无法打开预编译头文件:“xxx.pch”: No such file or directory
5)命令行编译msbuild 提示找不到头文件
6) msbuild和devenv的区别 还没搞明白
一些提醒
warning C4129: 'M' : unrecognized character escape sequence
VS2015 rc1106 invalid option -ologo
一些小的知识点
make工具
先看了一个这个文章
云风的 BLOG: IDE 不是程序员的唯一选择(一)
云风的 BLOG: IDE 不是程序员的唯一选择(二)
云风的 BLOG: IDE 不是程序员的唯一选择(三) gmake -n
云风的 BLOG: IDE 不是程序员的唯一选择(四) 如何使用宏,正则来简化Makefile的书写 gmake -d
云风的 BLOG: IDE 不是程序员的唯一选择(五)
https://blog.codingnow.com/2008/10/replacement_of_ide_6.html
make有许多分支版本,细节使用起来各有差异。VS 里带了一个叫做 nmake的小工具,是 Make 的一个旁支。我自己下了一个gmake,GnuWin32\bin\make.exe
make读取的默认文件是Makefile(ant读取的默认文件是build.xml)
Makefile中定义的是一些列的目标(目标的依赖,目标执行的的内容)以及目标之间的依赖关系。
make内部有一张依赖关系表,而Makefile文件就是描述,构建这张依赖关系表的。
Makefile中定义所有的目标,都被 make认为是一个文件。
它的规则就是,如果目标文件存在,就认为事情已经做完,如果目标文件不存在就构建目标。
这里注意,当目标文件存在,但是他依赖其他目标,而如果所依赖的目标文件存在,且比目标本身的时间新,就重新构键一次目标。如果不存在依赖的目标文件,那也要先构建依赖的目标,然后再构建自己。
make工作的时候,先读完整个文件,把完整的依赖关系表建立好,再根据命令行指定的目标开始工作,如果在命令行不指定目标,默认就是 Makefile 里写的第一个目标了。
可以使用windows下的事件查看器崩溃的地方
我的电脑——右键——管理 中找到事件查看器,或者在直接搜索 事件查看器
dumpbin工具查看dll是32位还是64位的
打开VisualStudioCommandPrompt
输入dumpbin:
dumpbin /headers xxxx.dll | findstr machine
因为有的太长了 所以用findstr截取一下
_MSC_VER
预处理宏
Predefined macros | Microsoft Learn
Visual Studio 6.0 | 1200 |
Visual Studio .NET 2002 (7.0) | 1300 |
Visual Studio .NET 2003 (7.1) | 1310 |
Visual Studio 2005 (8.0) | 1400 |
Visual Studio 2008 (9.0) | 1500 |
Visual Studio 2010 (10.0) | 1600 |
Visual Studio 2012 (11.0) | 1700 |
Visual Studio 2013 (12.0) | 1800 |
Visual Studio 2015 (14.0) | 1900 |
Visual Studio 2017 RTW (15.0) | 1910 |
Visual Studio 2017 version 15.3 | 1911 |
.cc 和.cpp
这两个后缀都表示C++的源文件。其实就是个文件后缀,唯一有关系的就是编译器是否能识别这个作为c++的源文件来进行编译,在windows系统中,visualstudio下cc和cpp都没问题,都是当作C++源文件的。
只是说cc在Unix系统的多,cpp在Unix以外的系统中用的多。
【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了
包含目录:默认是继承了环境变量 includepath宏。
附加包含目录:用于当前项目,对其他项目没有影响。
使用msbuild时直接在<AdditionalIncludeDirectories>节中修改即可,使用;来分隔每个路径
使用cl时使用/I(Include的开头字母,不是小写L也不是数字1,下同)开关指定附加包含目录,每个附加包含目录都要分开用/I指定
测试了一下,感觉包含目录和附加包含目录都是可以针对项目设置的。改变了一个工程的包含目录,另外一个工程也不会改变。
但是搜索路径的有所不同,先搜索【C/C++常规中的附加包含目录】,再搜索【VC++目录中的包含目录】。每个目录下的顺序就按照写的前后顺序查找了。(比如项目中有stlport库,就确保设置在再系统目录之前)
(同理库目录和附加库目录的区别)
SolutionExplorer窗口中 有一个文件夹是External Dependencies,这个文件夹就是那些需要用到的头文件,一般都是外部的文件,不是自己写的。库的或者系统的。有用到就会加到这里面进来。都是在设置的包含目录下的。
除了cpp定义的include,还有属性中可以配置的附加包含目录,以及VC++目录中的包含目录。
ps:【VC++目录中的包含目录】和【C/C++常规中的附加包含目录】的区别:
包含目录:修改了系统的include宏的值,是全局的;
附加包含目录:用于当前项目,对其他项目没有影响。————里面填写的相对路径就是指的是相对于项目路径的。如果有提示说找不到头文件的,应该就是这里配错了,看看是不是单词拼错了,还是路径层级弄错了,还是压根这里就没有配置。
(同理库目录和附加库目录的区别)
include<> 和 include""
注意其实#include后接<>或""包含的文件都是以实现定义(或者说implementation-defined)的方式去搜索的,
<>表示搜索系统+附加包含路径中的文件(而绝大多数实现里)
""表示搜索当前源文件所处路径下的文件,找不到时转而去搜索系统+附加包含路径
具体区别:
#include <>和#include ""的区别(一般来说自定义的类用"",更能快速找到文件)
二者的区别在于:当被include的文件路径不是绝对路径的时候,有不同的搜索顺序。
对于使用双引号""来include文件,搜索的时候按以下顺序:
先在这条include指令的父文件所在文件夹内搜索,所谓的父文件,就是这条include指令所在的文件
如果上一步找不到,则在父文件的父文件所在文件夹内搜索;
如果上一步找不到,则在编译器设置的include路径内搜索;
如果上一步找不到,则在系统的include环境变量内搜索
对于使用尖括号<>来include文件,搜索的时候按以下顺序:
在编译器设置的include路径内搜索;
如果上一步找不到,则在系统的include环境变量内搜索
WinMain 和 main 和 AfxWinMain
如果你要链接成为win32的程序,我们写的代码中的入口函数是WinMain,所以必须要要有这个函数,否则链接出错。
如果你要链接成为windows控制台的程序,我们写的代码中的入口函数是main,必须要要有这个函数,否则链接出错。
AfxWinMain是MFC工程的入口函数。
我们在vs中新建工程的时候,选择了是控制台还是win32,我们也可以在工程配置中修改
上面的配置写在项目文件中 .vcxproj中
_tWinMain 和 wWinMain 和 WinMain
_tWinMain是个宏,具体是wWinMain还是 WinMain 就看有没有定义Unicode。而wWinMain 和 WinMain 区别就是签名不一致,一个是宽字符相关的类型,一个是多字节相关的类型
#ifdef _UNICODE
#define _tWinMain wWinMain
#else
#define _tWinMain WinMain
#endif
stdafx 的介绍
比如用vs创建win32工程的时候有个选项,没有选择empty project,就会自动给你生成一些文件,其中就有stdafx.h 和 stdafx.cpp
stdafx的英文全称为:Standard Application Framework Extensions(标准应用程序框架的扩展)
这样第一个被编译的文件就是stdafx.cpp
当VisualC++进行编译的时候,会先编译stdafx.cpp(stdafx.cpp 默认 include 了 stdafx.h,stdafx.h默认是包含了常用的系统头文件)文件时,它将结果保存在一个名为 工程名.pch 的文件里。(扩展名pch表示预编译头文件。)
编译选项中有一个是否使用预编译头,如果是使用的话 你编写的任何.cpp文件都必须首先包含stdafx.h。在它前面的所有代码将被忽略,所以其他的头文件应该在这一行后面被包含。否则,你将会得到一些“No such file or directory”的错误提示。
(如果想排除一个文件不使用预编译头,也可以用右击相应的.cpp文件,点击“属性”,在左侧配置属性中,点开“C/C++”,单击“预编译头”,把选项从“使用预编译头(/Yu)”改成“不使用预编译头”)
因为在随后编译的每个.cpp文件时,它阅读并使用它刚生成的.pch文件,对于那些已经编译过的庞大的头文件就不需要再重新编译了。
预编译的思想就是把那么一堆头文件,是几乎所有 cpp 都必须包含的这些头文件提取出来,只编译一编,然后所有其它 cpp 就都能使用了。
预编译的代码可以是任何的C/C++代码 – 甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会被经常改变。如果这些代码被修改,则需要重新编译生成预编译头文件。注意生成预编译头文件是很耗时间的。同时你得注意预编译头文件通常很大,通常有10M+大(由于.pch文件具有大量的符号信息,它是你的工程文件里最大的文件)。注意及时清 理那些没有用的预编译头文件。如果你有工程文件里的大多数.cpp文件需要.h文件,顺便将它们加在stdafx.h(后部)上,然后预编译stdafx.cpp。
使用预编译头会使得编译过程加快。前提是你的预编译头里面的东西不经常改动。如果那个一改动的话,所有的cpp都会重新编译的。
相关错误:
fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "StdAfx.h"' to your source?
项目把其他作为预编译头的例子——stdGame.h:
修改了预编译头里面的头文件里面的东西以后,pch就会重新生成。
char 和 wchar之间的转化
相关文章:C++中的字符编码方式_c++设置字符编码_ivy_0709的博客-CSDN博客
相关错误:
cannot convert parameter 2 from 'const char [54]' to 'LPWSTR'
manifest文件和mt工具
打开visual studio command prompt(2010)
输入mt(Mt.exe - Win32 apps | Microsoft Learn),就会列出其使用方法了。下面使用写在构建后事件中的,把manifest文件嵌入到应用程序中的命令行:
mt.exe -nologo -manifest "compatibility.manifest" "ShadowBrowser.exe.manifest" -outputresource:"../out/Debug/XXXBrowser.exe";#1
从exe/dll中提取Manifest文件。
mt.exe -inputresource:d:\test.exe -out:d:\test.manifest
manifest文件:
Manifest是个XML的描述文件,对于每个DLL有DLL的Manifest文件(程序集清单 - Win32 apps | Microsoft Learn),对于每个应用程序Application也有自己的Manifest(应用程序清单 - Win32 apps | Microsoft Learn)。Manifest中每个字段的含义查看这两个链接即可。
允许多个版本的库共同存在,应用程序通过manifest描述自身所依赖的文件。
对于应用程序而言,Manifest可以是一个和exe文件同一目录下的.manifest文件,也可以是作为一个资源嵌入在exe文件内部的(Embed Manifest)。
系统启动exe时,会先检查其EXE的Manifest文件(如果没有查找到当前EXE中有Manifest,则会报“程序配置不正确的”的错误提示)
查找系统中是否有注册相应的Dll组件。
如果有,则会去c:\windows\winsxs\Manifest文件夹根据相应的调用策略及DLL的Manifest文件,
然后再根据Manifest中的内容去c:\windows\winsxs同名文件夹中查找到关的DLL。
如果没有查找到相应的DLL,
则会到当前目录来查找Microsoft.VC80.CRT.manifest和Microsoft.VC80.MFC.manifest。
如果没有查找到当前EXE中有Manifest,则会报“程序配置不正确的”的错误提示。
查到之后,就会去找相应的DLL。然后执行程序。
下面是一个例子:
使用manifest管理应用程序的依赖文件 - 简书
将SampleApp.exe.manifest嵌入到应用程序中,有两种方式可以嵌入:
方法一:
如果采用Visual Studio构建应用程序,默认情况下,VS会将manifest嵌入到应用程序中。按下面方式设置应用程序的依赖程序集:
Properties > Configuration Properties > Linker > Manifest File > Additional Manifest Dependencies >
type='win32' name='SampleAssembly' version='1.0.0.0' processorArchitecture='x86'
也可以采用comment prama
方式:(mfc工程的,stdafx.h中有类似的)
#pragma comment(linker, "\"/manifestdependency:type='win32' name='SampleAssembly' version='1.0.0.0' processorArchitecture='x86' \"")
方法二:
使用mt.exe工具嵌入,如果采用VS构建应用程序,使用这种方式需要先关闭VS默认嵌入manifest的行为:
Properties > Configuration Properties > Linker > Manifest File > Generate Manifest > No (/MANIFEST:NO)
然后在Properties > Configuration Properties > Build Events > Post Build Event
中写入以下命令:
mt.exe -manifest SampleApp.exe.manifest -outputresource:$(OutDir)$(TargetName)$(TargetExt);#1
上面命令的前提是文件SampleApp.exe.manifest在你的工程目录下。
一些错误
error C2011: 'SteamworksSDKHelper' : 'class' type redefinition 1> d:\xxx\source\source\SteamworksSDK/SteamworksSDKHelper.h(6) : see declaration of 'SteamworksSDKHelper'
没有写progma once 或者 ifdef 那个宏
.h 被多个cpp引用了
1>c1xx : fatal error C1083: Cannot open source file: 'simple_handler.cc': No such file or directory
看solution explorer中有这个文件啊
但是,点进去就是确实是打不开了
原来是磁盘中被误删了。solution explorer中显示只是filter文件中的记录的有这一项。
error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0'
_ITERATOR_DEBUG_LEVEL 迭代器调试等级 2 是debug,0是release
编译debug版本用的请用debug的dll
编译release版本请用release的dll
"error C2220: warning treated as error - no 'object' file generated"的解决办法
解决的办法是:将警告级别设置为低 或者 关闭将警告视为错误
msvcprt.lib(MSVCP100.dll) : error LNK2005: already defined in JSONCPP.lib(json_writer.obj)
确保使用相同的运行时设置编译所有目标文件,库等
多线程(/ MT)
多线程DLL(/ MD)
多线程调试(/ MTd)
多线程调试DLL(/ MDd)
根据提示可以看出:
JSONCPP库的运行时库用的是静态版本,用的标准库(/ MT)
代码程序的运行时库用的是动态链接版本(/ MD)
需要改成一样的
不同版本编译器编出来的library可以混用吗
不同版本编译器编出来的library可以混用吗? - 知乎
不同编译器编译出来的静态库,甚至于相同编译器用不同编译选项编译出来的静态库很可能都是没有办法静态链接的。
如果你只是应用了系统调用或者C Runtime Library 那还好说,如果用到了C++ 标准库函数、类或者模版,那么很大可能都是没法链接的。
通常用MSVC编译的静态链接库都会链接Microsoft C Runtime Library(MSCRL),后面有一串版本号,如果你运行程序时,调用了两个不同版本的C Library很有可能就会出现错误。
动态链接库有些许区别,许多时候都能用编译器链接另一个编译器产生的动态链接库。
当动态链接库是由C语言写成的,即便需要链接的程序是用C++写的也没有关系,很多时候都能成功链接。如果是用C++编译产生的动态链接库,那么如果你只跟其中用extern "C"定义的部分通信那么也没问题,否则的话可能就会有链接错误。
因为编译器处理C++函数的时候采用了一些不同的策略(like name-mangling scheme)。
一些运行时错误
Stack around the variable ‘’ was corrupted 是指 “某变量周围的堆栈区被破坏了”,更详细的分析可以参照这篇博客。
如果想看详细,就把下断点,看这个变量的内存地址,正常结尾是CCCCCCCC4个字节,当运行到越界的时候,就会覆盖这个标记了,也就是检测到堆栈区被破坏了。
总的来说就是,编译器为这函数预留的栈空间,比 你写的实际的函数需要使用的栈空间 要小,也就是写到了栈外。造成的原因可以是各有不同的。
这个还是需要解决一下的,具体看实现了,总之让编译器知道你需要多大的空间。
一些链接错误
我们经常在遇到一些连接错误
1.LNK1104 ,这里遇到过一次。
2.LNK2005 ,重定义错误,可能跟不同项目使用了不同的运行库有关系(上述的运行库设置)
3.LNK1169
一些编译错误
1) C1189 #error: /RTCc rejects conformant code, so it is not supported by the C++ Standard Library. Either remove this compiler option, or define _ALLOW_RTCc_IN_STL to acknowledge that you have received this warning.
代码生成-》较小类型检查 从/RTCc 改成 否
2)error C2039: “unique_ptr”: 不是“std”的成员
因为没有包含 unique_ptr 所在的头文件 #include<memory>
3)c1xx : fatal error C1083: 无法打开源文件:“lllll”: No such file or directory
看看是不是真的无法打开 lllll 没有找到这个源文件
4)无法打开预编译头文件:“xxx.pch”: No such file or directory
将 C++->预编译头 【创建/使用编译头】 改为“不使用编译头”
5)命令行编译msbuild 提示找不到头文件
在jenkins上使用 msbuild命令行编译工程的时候 提示找不到某头文件,但打开vs工程编译没有问题。
原因是在工程的配置中有添加头文件目录,但是 msbuild 不认识$(SolutionDir)这个宏,所以提示找不到头文件
解决加上一个参数,定义此宏:
/p:SolutionDir=path
msbuild - How to "get rid of" $(SolutionDir) when building Visual Studio project from outside Visual Studio - Stack Overflow
解决方法二:使用硬链接,放到系统的include下
cd /d C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include
mklink /D 取个文件夹名 头文件真正所在的路径
6) msbuild和devenv的区别 还没搞明白
在jenkins上编译工程的时候,同一个sln下,有的用msbuild 有的用devenv。
set MSBuild=C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
set devenv="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe"
set Src=%JENKINS_HOME%\jobs\Checkout\workspace\XXX\Src
set PubSrc=%JENKINS_HOME%\jobs\Checkout\workspace\YYY\Project
set Config=/t:Rebuild /p:Configuration=Release;Platform=Win32
set DevConfig=/Rebuild "Release|Win32"cd /d %Src%\UnrealBuildTool\
::Msbuild
%MSBuild% UnrealBuildTool.csproj %Config%;OutputPath=..\..\Intermediate\UnrealBuildTool\Release\
%MSBuild% %PubSrc%\Common.vcxproj %Config%
::devenv
%devenv% %Src%\GamePhysLibDev.vcxproj %DevConfig%
一些调试错误
1)排除了其他的可能,但是就是无法下断点
原因是行数超过了65535行以后的代码就不能下断点了,vs2010有这个问题,vs2012后面的就没有这个问题了。
How can I debug code with more than 65535 lines?
一些提醒
warning C4129: 'M' : unrecognized character escape sequence
\是转移字符的开头,说是\M没有找到这个转移字符
原来是
char * cmd = "d:\MJ\Tool\cef\cef\build\tests\cefsimple\Release\cefsimple.exe";
改成了
char * cmd = "d:\\MJ\\Tool\\cef\\cef\\build\\tests\\cefsimple\\Release\\cefsimple.exe";
VS2015 rc1106 invalid option -ologo
适用情况:
1. 查看 工程属性--- VC++目录----执行目录---是否有
C:\Program Files (x86)\Windows Kits\8.1\bin\x86 (应该是执行的这个目录下的 rc.exe)
2. 查看 目录 C:\Program Files (x86)\Windows Kits下是否没有【8.1】,或者【8.1】下的文件夹是否不全(对比【8.0】文件夹,比如是否少了【bin】文件夹),也就是根本找不到 C:\Program Files (x86)\Windows Kits\8.1\bin\x86 这个路径。
如果是的话,就下 sdk8.1 然后重启电脑,如果不是的话,就不适用了。。。
windows sdk8.1下载地址:
Windows SDK 和模拟器存档 | Microsoft Developer
选择8.1,下载exe。
如果安装的电脑可以联网,运行exe,选择第一个安装。
如果需要在其他电脑上离线安装,运行exe的时候,选择第二个,见下图。到时候就把下载路径下文件拷到其他电脑上,进行离线安装即可。
========================
两篇文章:
- .这篇文章介绍了
一:Property Manager属性管理器的使用:
1.打开属性管理器
2.双击属性表PropertySheet打开进行设置
1)VC++ Directories 的设置 ,设置VC++编译、链接需要的各种工具和资源的路径
2)用户自定义宏的设置
3.添加或导入Property Sheet
二:项目属性的继承关系:
1. 来自 MSBuild CPP工具集的默认设置(..\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.Cpp.Default.props,它将被 ProjectName.vcxproj文件导入)。
2. Property sheets(属性表),也就是Property Manager中设置的属性表。
3. 工程文件ProjectName.vcxproj .(可以重写默认值和property sheet 中的设置)。
4. 每一项的元数据。
- 这篇文章讨论了 WindowsSDK_IncludePath 存在哪里
Microsoft.Cpp.WindowsSDK.props
Microsoft.Cpp.Default.props
Microsoft.Cpp.Common.props
Microsoft.Cpp.Win32.user.props
Visualstudio中的框架和引用是什么意思呢
如果某个项目依赖与其他项目,那么就在项目依赖项中右键选择项目依赖项目就可以了。如果找不到你要的项目,先把项目添加到这个解决方案中才行。
这篇关于C++工程编译链接错误汇总VisualStudio的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!