2014-01-17 23:36 5128人阅读 评论(1) 收藏 举报
分类:
资料集(282)

版权声明:本文为博主原创文章,未经博主允许不得转载。

之前使用网上的一个开源代码,被封装成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来解决了。

解决Visual C++工程中包含 .c 或cpp文件编译时产生的.pch预编译头错误(C1853)的办法的更多相关文章

  1. 解决gvim 8.1中zip插件打开zip文件内容时,而文件路径带有空格的问题。

    解决gvim 8.1中zip插件打开zip文件内容时,而文件路径带有空格的问题. 现象是只能打开一次,第二次打开就显示为空了. 通过 lcd切换工作目录.使得命令行操作中不再有带空格的路径 vim81 ...

  2. 用CMake设置Visual Studio工程中第三方库

    较大的工程文件中一般会调用动态库或者静态库,如果这些库文件是当前工程包含的项目,CMake会自动识别并添加Debug和Release编译时需要的库文件路径和文件名,可以使用命令: Target_Lin ...

  3. [C++] 在Visual Studio工程中管理C++第三方库

    目前的项目依赖于很多第三方库,每次要再一个新的环境编译/运行,都要花很长时间先编译/安装各种第三方库,而且会出现各种问题,因此决定将所有第三方库编译好之后,放入工程的子目录中,以后就不用重复编译了. ...

  4. 用CMake设置Visual Studio工程中预处理器定义值

    构建VS工程时预处理值是不可缺少的,如动态库的导出配置等.在通过CMake构建VS工程时,可以通过CMake命令进行定义,下面讲三种应用. 字符集:默认装填下VS工程是多字节字符集,如果需要使用Uni ...

  5. Visual Studio 2013 配置多个Release版本,并为每个版本配置预编译的宏

    最近开发过程中,需要将同一份工程编译成两个版本,分别为ReleaseA和ReleaseB. ReleaseB比ReleaseA少了部分功能,所以希望在编译的时候,根据不同的版本编译工程中相应的代码. ...

  6. Android Studio中通过CMake使用NDK并编译自定义库和添加预编译库

    Note:这篇文章是基于Android Studio 3.01版本的,NDK是R16. step1:创建一个包含C++的项目 其他默认就可以了. C++ Standard 指定编译库的环境,其中Too ...

  7. error C1853: “Debug\BigBuffer.pch”预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)

    <pre id="best-content-1299104064" mb-10"="" style="font-size: 14px; ...

  8. 解决Visual Stuido 2013中Xamarin的*.axml文件没有智能提示问题

    最近发现VS2013开发Android,发现.axml无法进行智能提示. 1.打开VS2013菜单栏中,点击工具--选项--文本编辑器--文件扩展名 2.增加一个扩展名为"axml" ...

  9. 解决eclipse maven工程中src/main/resources目录下创建的文件夹所显示样式不是文件夹,而是"包"图标样式的问题

    参考:http://blog.csdn.net/luwei42768/article/details/72268246 eclipse项目中创建maven项目后,有时在执行命令maven update ...

随机推荐

  1. IOCP结合AcceptEx实例

    在普通IOCP的基础上注意两点: 1.记得把监听socket绑定到端口 2.在Accept处理过程中,抛出接受连接的AcceptEx请求,绑定客户端socket到端口和抛出recv请求 客户端要断开连 ...

  2. Docker学习总结(一)—— namespace,cgroup机制

    1.namespace: Linux Namespaces机制提供一种资源隔离方案.PID,IPC,Network等系统资源不再是全局性的,而是属于特定的Namespace.每个 Namespace里 ...

  3. java后台读取配置文件中key与value -----demo2

    /** * * @Title: getValue * @Description: TODO * @param key * @return import java.util.Properties; * ...

  4. Oracle段高水位(HWM, high water mark)问题

    Oracle对表做全表扫描的时候 ,会扫描完HWM以下的数据块.如果某个表delete(delete操作不会降低高水位)了大量数据,那么这时对表做全表扫描就会做很多无用功,扫描了一大堆数据块,最后发现 ...

  5. 一些Java相关的

    都是从<Thinking in Java>英文第四版中摘抄的 _______________________________________________________________ ...

  6. ceph集群jewel版本 rbd 块map 报错-故障排查

    测试信息如下: [root@ceph_1 ~]# ceph osd pool lsrbdchy_123swimmingpool #新建rbd 块: rbd create swimmingpool/ba ...

  7. Log4j记录日志使用方法

    1.导入相关JAR包 log4j-1.2.15.jar slf4j-api-1.6.1.jar slf4j-log4j12-1.6.1.jar log4jdbc4-1.2.jar 2.配置log4j. ...

  8. Mysql 中的伪列用法1

    SELECT ( @rowNO := @rowNo + 1 ) AS rowno, A.*FROM ( SELECT * FROM t_user ) a, ( SELECT @rowNO := 0 ) ...

  9. WPF——Sharder实现Logo走光动画

    利用WPF的走光动画实现的走光动画. 资源  实例程序 示例代码 LogoEffect logoEffect = }; //要添加走光动画的物体 logo.Effect = logoEffect; D ...

  10. 从0开始用spring boot编写分布式配置中心-peppa

    欢迎大家一起来编写peppa github地址: github 交流群: 目前市面上比较流行的分布式配置中心有disconf.apollo,用起来还是比较方便的,然而由于在权限管理这块做得不够好,导致 ...