本文转载自:http://blog.csdn.net/jocklyhu/article/details/5663576
相关其他文章:
http://connect.microsoft.com/VisualStudio/feedback/details/597858/c1859-bug-in-windows-7-x64-is-still-there
http://support.microsoft.com/kb/976656 (实际操作中按照这个链接的方法3重启计算机解决问题)
之前有人在win7 上遇到了类似的错误, Error 1 fatal error C1859: 'Debug/CppDllExport.pch' unexpected precompiled header error, simply rerunning the compiler might fix this problem f:/document/visual studio 2008/codefx/visual studio 2008/cppdllexport/cppdllexport.cpp 18 CppDllExport
这个错误一般出现在以下条件:
Visual C++ 编译器是在 win7 上被调用的;
预编译头(PCH) 被启用 (enable) 了 ;
/analyze 被启用了, 这不是一个必须的条件 , 但是增加了遇到问题的重现几率)
尽管错误提示建议道: 简单的重新编译吧 , 但是这个情况可能好转不了. 事实上 , 这个 ” 简单 ” 的错误起因是预编译头和 win7 的增强安全技术 .
Visual c++ 预编译头和 ASLR
预编译的头文件存储着编译在某时刻的 ”状态 ”, 这个状态的信息可以被之后的编译器重用 . 之前的 15年 , 编译器都是把预编译头以文件放着 , 再从虚拟内存里读取 , 这样有 99.999%的可靠并且效率也挺好的 . 不过这玩意也是架构上的一个痛点 .
因为 PCH文件本身包含着内部指针 , 它在被重新载入的时候 , 必须是写入虚拟内存的时候那个相同的地址 . 所以如果 PCH被之后的编译器加载的时候指针会变得不一样或错误 . 复杂点说 , PCH 还包括多态对象和每个多态对象自包含的虚方法表指针 (virtual function table pointer –VFTP), 这个表指针 , 指向了模块中的虚方法 . 这样子 , 当 PCH 中的多态对象依赖于某个特殊模块的指针表时候 , 模块必须以创建 PCH 文件时候指针值载入. 如果模块以不同地址加载的话 , PCH中的 VFTP 指针 就不对了 .
说了这么长 , 简单说就是 , 无论是 PCH还是模块 , 都不能在编译器变动 . Visual C++编译器将在启动前检这 2个条件 , 要不然立刻就报这个错 . 说一下地址空间布局随机化 (Address Space Layout Randomization (ASLR) .的一点算法 , ASLR可以通过随机进程的模块 , 来减少一些恶意攻击模块的影响 . 在 VISTA的时候 , VS2008通过 /dynamicbase:no 在编译前来绕过了这个东西 , 当然 , 在 win7上这个情况变糟了点 .
所以一开始的想法是通过把编译模块地址放到一个 ”安全 ”的地方 ,(还是绕过 ASLR, 比如减少模块的重调用次数 ), 糟糕的是失败了, 模块地址还是会移动。 因为一些让人郁闷的因素,如 NativeDLL loader,进程创建顺序, devenv.exe条用 cl.exe等等, 错误很难调试, 就像蝴蝶效应, 牵一发而动全身。
解决方案
这个修复将于 VS2010和 vs2008的补丁包里中出现, 你现在则可以这样弄:
l 禁用 /analyze (C++ => advanced => enable code analysis for C++)
l 清除项目。 (之前的预编译头都删了)
l 重启机器
l 禁用 PCH文件 (C++ => Precompiled headers => create/use pre-compiled headers)
来源在这里
http://www.cnblogs.com/read-acquisitions-docs/archive/2009/12/02.html