VC常见编译链接错误(.obj : error LNK,fatal error)

VC常见编译链接错误 : error LNK2019、2005、1169、2026、4098,fatal error C1083、C1010,fatal error C1189,C2061、C2146、C4430、C2079、C2440


VC常见问题fatal error

fatal error C1189: #error: “No Target Architecture”

解决方法
打开vs项目属性,C/C++,预处理器,在预处理器定义中添加相应的宏即可:
win32项目,就添加_X86_;
x64项目,就添加_ia64_;
其实也不需要在预处理器定义中添加这些宏,只需要包含头文件<windows.h>就可以了,即是说,只要包含了 Windows.h,那么 WIN32 常量是肯定定义了的。但是如果在预处理定义里删掉_WIN32,又不包含 Windows.h,那么_WIN32 未定义。

参考链接:
关于VC预定义常量_WIN32,WIN32,_WIN64等预定义宏的介绍


error LNK2001: 无法解析的外部符号 _EnumProcessModules@16

打开vs项目属性,链接,输入,在附加依赖项中添加Psapi.Lib即可。


*.obj : error LNK2019: 无法解析的外部符号 __imp_FindWindow

解决方法1:
#pragma comment(lib,"User32.lib")

解决方法2
项目属性、链接器、输入、附加依赖项,填写User32.lib即可(Debug和Release两个编译模式都要加入该链接库)。


error LNK2019: 无法解析的外部符号 __imp__SHDeleteKeyA@8,该符号在函数 xxx 中被引用

我们发现SHDeleteKey在#include <Shlwapi.h>中有声明,而我们的.cpp中已经包含了该头文件,注意错误提示是说没有符号,也就是这个链接库没有找到。

解决方法
在MSDN中搜索SHDeleteKey查看这个函数的说明,除了要包含shlwapi.h这个头文件,还要导入shlwapi.lib库;
即项目属性、链接器、输入、附加依赖项,填写shlwapi.lib即可(Debug和Release两个编译模式都要加入该链接库)。


Run_Time Check Failure #2 Stack around the variable chOpt was corrupted

解决方法
打开项目属性,C/C++,代码生成,基本运行时检查设置成默认值。


fatal error C1083: 无法打开预编译头文件:“Debug***.pch”: No such file or directory

问题原因
将stdafx.h和stdafx.cpp文件移动到其他文件夹下后,清理,重新生成,仍然报以上错误,观察项目文件*.vcxproj:

<ClCompile Include=“mycommon\stdafx.cpp”>
<PrecompiledHeader Condition=“‘$(Configuration)|$(Platform)’==‘Debug|Win32’”>Create</PrecompiledHeader>
</ClCompile>

我们发现,预编译头标签PrecompiledHeader那里由Create改为了Use,原来是stdafx.cpp的属性被修改了。

解决方法
鼠标右击stdafx.cpp,属性、C/C++、预编译头,将预编译头由使用 (/Yu)改为创建 (/Yc)即可。


fatal error C1083: 无法打开包括文件:“winable.h”: No such file or directory

问题原因
winable.h was moved from the Windows SDK in July 2005 because functionality was duplicated in winuser.h. (winable.h在2005年7月已经从Windows SDK移除,因为它的功能已经在winuser.h被复制。)

解决方法
将#include <winable.h>改为#include <winuser.h>即可。


RC : fatal error RC1106: invalid option: -ologo

我用的vs2012,当按照我博客中的《MFC常用技巧》10、复制别人项目中的界面资源,发现用vs2012打不开*.rc,经百度发现是我的Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin目录下没有rc.exe和rcdll.dll,搜索磁盘找到这两个文件拷贝到该目录下,编译报错:
RC : fatal error RC1106: invalid option: -ologo

解决方法
配置属性->资源->常规->取消显示版权标志修改为否,即可解决!
(其实这个错误的根本原因是VS2012中关于Windows SDK的路径宏定义在某种情况下被其他配置串扰到了,例如VS2010中定义包含目录的宏为$(WindowsSdkDir)include,指向的目录是C:\Program Files (x86)\Windows Kits\8.0\Include,而我们搜索到的SDKDDKVer.h文件在C:\Program Files(x86)\Windows Kits\8.0\Include\shared路径下。
vs2012的vc目录设置沿用了错误的路径,所以必须调整目录包括包含目录,库目录等,具体修改方法在下一节fatal error RC1015: cannot open include file ‘SDKDDKVer.h’.

最佳解决方法:rc.exe和rcdll.dll这两个文件要拷贝你安装的SDK的版本,就像我的电脑上可能是以前安装过其他版本的VS或SDK:

在这里插入图片描述
如上图所示v7.1A,里面的C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin目录下有rc.exe和rcdll.dll,但是不符合我安装的vs2012的版本,一直编译有问题;
换成后来最新安装的C:\Program Files (x86)\Windows Kits\8.0\bin\x86里面的rc.exe和rcdll.dll就没有RC1106: invalid option: -ologo这个错误了;相应的include也应更换为windows kits 8.0这个版本的。


fatal error RC1015: cannot open include file ‘SDKDDKVer.h’.

按照上一节修改后重新生成,编译报错:
targetver.h(8): fatal error RC1015: cannot open include file 'SDKDDKVer.h'.

解决方法
配置属性->资源->常规->附加包含目录,修改为

$(IntDir);C:\Program Files (x86)\Windows Kits\8.0\Include\shared;D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\include;C:\Program Files (x86)\Windows Kits\8.0\Include\um;%(AdditionalIncludeDirectories)

重新编译成功!


Windows环境下编译zlib.lib库常见问题

提示fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include “stdafx.h””

解决方法1
在.cpp文件最开头添加头文件#include “stdafx.h”,如果还不行就采用方法2。

解决方法2
打开项目属性,C/C++,预编译头,选择不使用预编译头即可。


Debug编译模式下,提示LIBCMT.lib(invarg.obj) : error LNK2005一堆函数已经在中定义

fatal error LNK1169: 找到一个或多个多重定义的符号,LINK : warning LNK4098: 默认库“LIBCMT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
我们发现这种错误在Release模式下编译不会出现,这是怎么回事呢?
原因:在Debug模式编译的时候,它会有一个多线程的调试库,vs自带的这个多线程的调试库和zlib库编译时候用的多线程调试库,此时这两个库都被调用了,这样就会出问题。

解决方法
打开项目属性,链接器,输入,忽略特定默认库,输入LIBCMT即可。


Release编译模式下,提示error LNK2026: 模块对于 SAFESEH 映像是不安全的

解决方法
打开项目属性,链接器,命令行,在“其他选项”框里输入/SAFESEH:NO即可。


Windows环境下用nmake编译常见问题

fatal error C1083: 无法打开包括文件:“excpt.h”

在编译Detours4.0的时候,nmake提示错误:
Windows Kits\8.0\include\um\windows.h fatal error C1083: 无法打开包括文件:“excpt.h”,找不到相关头文件。

解决方法1
设置头文件搜索路径(少啥添啥)

在这里插入图片描述
该方法最实用,少INCLUDE文件你搜到后,就将该文件所在的目录添加到系统环境变量INCLUDE里面,少LIB文件你就将它的目录添加到系统环境变量LIB里面,少啥添啥。

解决方法2(如果头文件不在VC目录下面的话,就以上面的方法1为主)

打开cmd命令控制台,找到vcvars32.bat所在路径,例如:D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin,运行该批处理文件;

或者运行vcvarsall.bat文件:

cd D:\Program Files (x86)\Microsoft Visual Studio 11.0\VC
vcvarsall.bat

参考链接:
Windows环境下用nmake编译libevent

nmake编译libraw


编译使用了Detours库的项目报错fatal error C1189

fatal error C1189: #error : Unknown architecture (x86, amd64, ia64, arm, arm64)
在vs中编译使用了Detours库的项目时,报上述错误。

解决方法
在include "detours.h"之前要先包含windows.h头文件,即:

#include <windows.h>
#include "detours.h"
#include "detoursHookApi.h"

其他问题

注册表中无法删除 LEGACY_*: 删除项时出错

在这里插入图片描述
点击开始,运行,输入regedit,打开注册表编辑器,找到相关条目,在左侧目录该条目上点鼠标右键,选Permissions(权限),给Everyone用户组赋予完全控制的权限,确定,然后即可删除。

在这里插入图片描述

error C2365: “PS_PAUSED”: 重定义;以前的定义是“枚举数”

在编译电驴源码的时候报错,原因可能是工程依赖了另外一个目录导致的。

解决方法
随便找一个.cpp文件,打开最开头的stdafx.h文件,在stdafx.h文件最后面加上如下:

#define PS_PAUSED PS_PAUSED2

重新编译,又出现一个同样的重定义问题:“IDR_MANIFEST”: 宏重定义,仍然是在stdafx.h文件中加上如下:

#define IDR_MANIFEST IDR_MANIFEST2

头文件互相包含错误(C2061、C2146、C4430、C2079)

一个对话框类,一个数据处理类,它们的头文件互相包含(因为要互相使用对方的类生成的对象,对话框类定义中定义了一个数据处理类对象),很容易导致很多错误:

error C2061: 语法错误: 标识符“XXDlg”
这是一个互相包含的错误,编译器不知道应该先生成哪一个类,后生成哪一个类了,这样就导致了这样一个错误。

解决方法
我们可以在没有编译的时候,在数据处理类的定义前面先声明一下对话框类(前置声明),这样就能够避免这种错误。

前置声明解决了C2061错误后,编译后还是有其他错误:

error C2146: 语法错误: 缺少“;”(在标识符“m_XXXBase”的前面)
error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int

我们在对话框类的定义前面声明一下数据处理类(前置声明),结果错误又变成了对话框类使用了未定义的数据处理类(对话框类定义中定义了一个数据处理类对象):

error C2079: “XXXDlg::m_XXXBase”使用未定义的 class“XXXBase”

这样我们就不能将在对话框类定义中定义的这个数据处理类对象写到.h文件里面来了,我们先把对话框类定义前面那个数据处理类的前置声明删除,在.cpp中将这个数据处理类对象变成一个全局变量,并修改使用这个对象的代码即可解决这个错误。。。。。。


error C2440: “类型转换”: 无法从“overloaded-function”转换为“LPTHREAD_START_ROUTINE”

线程函数需要静态成员函数或全局函数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值