解决Visual C++工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)的办法
2016-11-03 10:10
369 查看
之前使用网上的一个开源代码,被封装成Windows DLL库提供给外部使用。由于项目需要,需要将代码封装成静态库。于是,创建了一个Win32的静态库工程,将开源中的.h和.cpp文件都添加到该静库工程中。但是编译时却出现了这样的错误:libdui\source\stb_image.c : fatal error C1853: “.\Debug\libdui.pch”预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)。这怎么回事呢?之前stb_image.c在DLL中都能正常编译,放到静态库中则有这样的错误呢?
于是赶紧到网上查一下,发现是C文件在C++工程中编译的问题。stb_image.c是一个独立的功能文件,是不需要包含stdafx.h的。所以进一步看了一下相关的原理和处理办法。
当 Visual C++ 项目启用了预编译头 (Precompiled header) 功能时,如果项目中同时混合有 .c 和 .cpp 源文件,则可能收到 C1853 编译器错误:fatal error C1853: 'xxxxxx.pch' 预编译头文件来自编译器的早期版本,或者预编译头为C++ 而在C 中使用它(或相反)。该错误是因为当项目中混合了 .cpp 和 .c 文件时,编译器会对它们采取不同的编译方式(主要是因为对函数声明的处理方式不同),因而不能共用一个预编译头文件。在 VC++
中,默认的预编译头文件是针对 C++ 的 (stdafx.h 和 stdafx.cpp),当然也可以创建针对 C 的预编译头。有趣的是,在旧版的 VC++ 中,这个错误的提示很具有误导性:fatal error C1853: 'xxxxxxpch' is not a precompiled header file created with this compiler, 常常让人摸不着头脑。应该说,在新版中的这个提示是有所改进的。不过在网上搜索一番,对这个问题往往都是建议对整个项目取消预编译头的设置。这显然不是一个好的解决方案。对于一个比较大的工程来说,使用预编译头可以使总的编译时间大大减少,因而保留预编译头的设置才是比较好的解决方案。搜索
MSDN,针对不同的情况,可以有不同的解决方案:
方案1:适用于绝大多数文件是 .cpp 或绝大多数文件是.c的情况。在这种情况下,将少数的不同类文件设为不使用预编译头是比较平衡的做法,方法是:对于 VC++6.0,在 FileView 里对要取消预编译头的 .c (或 .cpp) 文件点右键,选择 settings,在弹出的对话框右边选择 category 为 precompiled headers,再设置选项为
Not Using Precompiled Headers;对于 VS2005及以上版本,则在 Solution Explorer 中对要取消预编译头的 .c (或 .cpp) 文件点右键选择 Properties,在 Precompiled Headers 项下设置 Not Using Precompiled Headers 即可,设置方法如下图所示:
如果需要设置多个文件,则可以按住 Ctrl 键再同时选中这些文件并设置。
方案2:如果受影响的文件比较多,则把它们都设置禁止预编译头的话仍然会使项目总体的编译速度大大降低,得不偿失。这时考虑可以为这组文件建立专用的预编译头。在 VC++ 极早期版本(1.5及以前版本)中是支持单个工程中建立分别针对 .c 和 .cpp 的预编译头的,但之后的版本中只支持单独的预编译头。在这种情况下,我们可以在workspace(或 solution)中建立一个新的静态链接库
(Static Library) 工程,将所有的 .c 文件独立出来加入到该工程中单独编译,这样就可以在该静态链接库中针对 .c 文件创建预编译头。但是这样做在一定程度上需要被独立出来的代码在逻辑上是属于同一模块中的,这样才便于维护。不过从设计的角度来说,这个要求一般是满足的,否则就应考虑下项目的总体设计了:P 最后别忘了设置原项目的依赖项 (dependency) 为独立出来的这个静态库项目。
有了上述的说明和阐述,对于我们遇到的问题,肯定是使用方案1来解决了。
于是赶紧到网上查一下,发现是C文件在C++工程中编译的问题。stb_image.c是一个独立的功能文件,是不需要包含stdafx.h的。所以进一步看了一下相关的原理和处理办法。
当 Visual C++ 项目启用了预编译头 (Precompiled header) 功能时,如果项目中同时混合有 .c 和 .cpp 源文件,则可能收到 C1853 编译器错误:fatal error C1853: 'xxxxxx.pch' 预编译头文件来自编译器的早期版本,或者预编译头为C++ 而在C 中使用它(或相反)。该错误是因为当项目中混合了 .cpp 和 .c 文件时,编译器会对它们采取不同的编译方式(主要是因为对函数声明的处理方式不同),因而不能共用一个预编译头文件。在 VC++
中,默认的预编译头文件是针对 C++ 的 (stdafx.h 和 stdafx.cpp),当然也可以创建针对 C 的预编译头。有趣的是,在旧版的 VC++ 中,这个错误的提示很具有误导性:fatal error C1853: 'xxxxxxpch' is not a precompiled header file created with this compiler, 常常让人摸不着头脑。应该说,在新版中的这个提示是有所改进的。不过在网上搜索一番,对这个问题往往都是建议对整个项目取消预编译头的设置。这显然不是一个好的解决方案。对于一个比较大的工程来说,使用预编译头可以使总的编译时间大大减少,因而保留预编译头的设置才是比较好的解决方案。搜索
MSDN,针对不同的情况,可以有不同的解决方案:
方案1:适用于绝大多数文件是 .cpp 或绝大多数文件是.c的情况。在这种情况下,将少数的不同类文件设为不使用预编译头是比较平衡的做法,方法是:对于 VC++6.0,在 FileView 里对要取消预编译头的 .c (或 .cpp) 文件点右键,选择 settings,在弹出的对话框右边选择 category 为 precompiled headers,再设置选项为
Not Using Precompiled Headers;对于 VS2005及以上版本,则在 Solution Explorer 中对要取消预编译头的 .c (或 .cpp) 文件点右键选择 Properties,在 Precompiled Headers 项下设置 Not Using Precompiled Headers 即可,设置方法如下图所示:
如果需要设置多个文件,则可以按住 Ctrl 键再同时选中这些文件并设置。
方案2:如果受影响的文件比较多,则把它们都设置禁止预编译头的话仍然会使项目总体的编译速度大大降低,得不偿失。这时考虑可以为这组文件建立专用的预编译头。在 VC++ 极早期版本(1.5及以前版本)中是支持单个工程中建立分别针对 .c 和 .cpp 的预编译头的,但之后的版本中只支持单独的预编译头。在这种情况下,我们可以在workspace(或 solution)中建立一个新的静态链接库
(Static Library) 工程,将所有的 .c 文件独立出来加入到该工程中单独编译,这样就可以在该静态链接库中针对 .c 文件创建预编译头。但是这样做在一定程度上需要被独立出来的代码在逻辑上是属于同一模块中的,这样才便于维护。不过从设计的角度来说,这个要求一般是满足的,否则就应考虑下项目的总体设计了:P 最后别忘了设置原项目的依赖项 (dependency) 为独立出来的这个静态库项目。
有了上述的说明和阐述,对于我们遇到的问题,肯定是使用方案1来解决了。
相关文章推荐
- 解决Visual C++工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)的办法
- 解决Visual C++工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)的办法
- VC 工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)
- 网狐编译时无法打开包含(D3D9.H)文件解决办法
- 在Eclipse中写 C++,cpp文件之只能编译为.o文件,不能生成.exe文件的解决办法
- vs2010中导入OFFICE库文件的类 excel.h,excel.cpp后出现编译错误的解决办法
- 最近研究Android,发现对于外部导入的工程,编译的时候不能够正常生成R.java文件的解决办法
- 我把一个VC6的工程转换为VS2008的工程后,编译总是出现找不到而且不能升级vc90.pdb文件的问题,error C2471--解决办法 2010-9-16 15:01
- [CentOS]CentOS下编译CPP文件时报错[undefined reference to `__gxx_personality_v0' collect2: ld]的解决办法
- cocos2d-x的eclipse工程解决jni目录下main.cpp文件编译错误的问题
- 同一段C++代码在win下和linux下同时编译时产生的头文件包含问题及解决
- 我把一个VC6的工程转换为VS2008的工程后,编译总是出现找不到而且不能升级vc90.pdb文件的问题,error C2471--解决办法
- 使用EMCV将工程.c文件改为.cpp文件所出现错误的解决办法
- 升级到VS2015 的 RC 文件包含 afxres.h,编译报错的解决办法
- 在Visual Studio 编译代码时出现警告warning C4819: 该文件包含不能在当前代码页(936)中表示的字符的解决办法?
- Android,发现对于外部导入的工程,编译的时候不能够正常生成R.java文件的解决办法
- 关于.cpp文件包含另一个.cpp文件出错的原因以及解决办法
- busybox编译根文件系统的一些错误解决办法
- VC6.0无法打开文件和无法向工程添加文件的解决办法
- 头文件相互包含问题的解决办法