2012-09-15 126 views
19

在VS中的“显示所有文件”选项中,我添加了一个文件夹并在该文件夹中创建了一个新类。由于我使用预编译头文件,我还需要包含相对于新类文件的根目录中的stdafx.h。如何从根目录中包含stdafx.h?

在我的cpp文件我有

#include "..\stdafx.h" 

然而,我得到以下错误:

error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?

我的理解是,该..应指示编译器去一级目录呢?

回答

-3

使用引号意味着它是你自己用<>意味着它是一个系统的头文件,如果我没有记错的话只是使用#include <stdafx.h>,让编译器发现它

+1

-1:'stdafx.h'不是系统文件。这是一个预编译的头文件。 –

+0

不是一个Windows的家伙,那么它为什么有一个.h扩展名? –

+0

因为它是一个头文件。它可能是预编译的,但它仍然是一个头文件。 –

2

PCH文件是奇怪,甚至moreso在头文件视觉工作室。在编译使用PCH的.cpp文件时,VS期望第一个非注释/空白文本为#include "PCH_NAME_HERE"PCH_NAME_HERE,正好是的PCH的名字。没有目录,没有。只是编译器选项中指定的PCH的名称。

如果你打算做这个目录捏造,那么你需要使得上述PCH是目录所在的目录搜索路径修改编译器设置。这样,你不需要有..\的一部分。

13

的Visual C++允许您定义设置预编译的头文件的几种方法。最常见的是在项目配置级别为所有源文件启用它,在Configuration Properties/C++/Precompiled Headers下,设置“Precompiled Header”,选择“Use”。设置“预编译头文件”的相同位置通常是“stdafx.h”。所有文件都将获得此设置(因此在项目的配置),除了....

一个文件是负责生成PCH文件。该文件通常是项目中的stdafx.cpp文件,除#include "stdafx.h"之外,该文件通常不包含任何内容。为这一个文件配置预编译头文件,从“使用”切换到“创建”。这可以确保如果PCH的主标题不同步stdafx.cpp总是首先编译以重新生成PCH数据文件。在Visual Studio中还有其他配置PCH设置的方法,但这是最常见的。

话虽这么说,你的问题是绝对刺激。在以上设置的“使用...”和“创建...”设置的PCH系统的主文件名必须匹配#include的所有文本,请正确匹配

因此,很有可能您可以通过将“..”添加到项目的include目录并从#include语句中删除“..”来解决您的问题。您也可以在项目配置级别将其更改为“.. \ stdafx.h”作为通过标题,但如果您在源文件分层存储在多个文件夹中,则可能会出现问题。

哦,如果在应聘一个PCH配置设置,如果你不想使用PCH对任何特定的源文件并不清楚你(和有原因不能有时),你可以把它关闭请确保在每个源文件(c/cpp等)的头部始终包含#include“your-pch-include-file.h”。

希望你休息一下。

+0

嘿,谢谢你的回答,但我想我可能误解了你。在配置属性中没有“使用预编译头文件”设置。另外,我在配置属性 - > C \ C++ - > General - > Additional Include Directories和Configuration Properties - > VC++ Diretories - > Include Directories中添加了“..”。它们都不起作用。 – Dante

+0

我更新以反映VS2010配置路径设置。如果将“..”添加到包含路径中,则还必须从c/cpp文件中的#include decls中删除它以将“stdafx.h”删除。 – WhozCraig

+0

我从cpp文件中删除了stdafx.h包含的“.. \”部分,它位于单独的文件夹中。每个其他文件编译正常,但在单独的文件夹中的一个现在产生一个错误“错误C1083:无法打开包含文件:'stdafx.h':没有这样的文件或目录”。 – Dante

3

您可以在每个文件的基础上调整了预编译头设置。

  1. 在解决方案资源管理器中,右键单击.cpp文件,选择“属性”。
  2. 我强烈建议在配置选择“所有配置”下拉列表中的项目。
  3. 浏览以 “C/C++” - “预编译头”。
  4. 调整从“stdafx.h中”,无论你需要(在你的情况下,例如"../stdafx.h")的“预编译头文件”。

注意这是单调乏味和容易出错的,因为它是以每个文件为基础完成的,未来的开发人员将文件添加到项目中必须遵循相同的步骤。如果他们不这样做,他们将面临警告和错误,如:

  • warning C4627: '#include "<path>"': skipped when looking for precompiled header use.

  • fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?

这并不会过多指示关于这个或任何其他方法。

我想他们最终会转向StackOverflow的,在这里结束了...你好,感谢您的阅读。

在此基础上,值得使用替代方法,例如在C++包含路径(C++ \ General下)上放置$(ProjectDir),但当包含其他头文件时会导致混淆。

-1

如果你的项目的.cpp和.h文件居住在不同的子目录(未清楚地在该项目的目录),这将是一个良好的编码风格来使用包括相对于解决方案目录(如果你不”路径使用专用的包含目录)。特别是如果您在解决方案中有多个项目并需要共享包含文件(例如项目之间的互操作性,例如.exe和.dll)。

重构你的项目,你需要做到以下几点:

  1. 在每个项目中指定其他包括目录 $(SolutionDir):右键单击项目,然后单击“属性”,进入到 “配置属性“ - >”C/C++“ - >”常规“(要对所有 配置立即执行此操作,请从 ”Configuration“下拉列表中选择”All Configurations“)
  2. 转至”C/C++“ - > “预编译头” 和更改“预编译头文件”值到路径相对于到 解决方案目录,例如PROJECT_NAME/stdafx.h中
  3. 在你的.cpp包括一些,使用路径时 文件包括 “PROJECT_NAME/stdafx.h中”,而不仅仅是 “stdafx.h中”
  4. 在你的.h和.cpp文件, “PROJECT_NAME/dir1/dir2/file。H”时,从 同一目录包括文件时除外
+0

使用固定包含路径是一个糟糕的主意。将源复制到另一台机器,或者甚至重新配置源已经启动的机器都不会导致编译。此外,如果您使用根路径包含stdafx.h,Visual Studio仍然会发出抱怨,因为它不使用标准路径解析算法来查找stdafx.h文件,它具有一些(imo半范围)自定义查找机制,它实际上问题的原因。 – Neutrino

+0

@Neutrino,我并不是指完全扎根的路径,例如从一个盘符开始,例如, 'C:'。我已经编辑了答案以使意思更清楚:我的意思是解决方案目录或专用的'include'目录作为根目录,以便包含文件被相对于这些目录的路径引用。这在移动整个解决方案在同一台计算机上的计算机或目录之间没有任何问题。 –

+0

@Neutrino,同样,我已经仔细检查了使用解决方案相关路径(如#include“PROJECT_NAME \ stdafx.h”)的建议,如果遵循上述步骤,它就可以工作。如果您尝试过,但没有奏效,那么错误是什么? –

0

混乱的原因是,Visual Studio中治疗的包括指令,其包括预编译的头不同,以其它包含指令。具体地它不看为预编译使用普通路径查找方法,它只是试图通过简单字符串比较来将include指令与项目配置中定义的include指令进行匹配

预编译器头配置设置为gobally,但可以对每个文件进行覆盖。 (通过项目属性 - >配置属性 - > C/C++ - >预编译头文件访问)为:

Precompiled Header: Use (/Yu) 
Precompiled Header File: stdafx.h 
Precompiled Header Output File: $(IntDir)$(TargetName).pch 

此配置默认应用于项目中的所有文件。然而,对于stdafx.cpp的配置被设定在文件级并覆盖预编译头值:

Precompiled Header: Create (/Yuc) 

这样做的效果是,对于任何的源文件构造,其通过使用该预编译的头(默认是除了stdafx.cpp之外的所有它们)VS将查找与配置的预编译头文件值相匹配的include指令。例如

#include "stdafx.h" 

因为校验使用简单字符串比较,而不是任何种类的目录搜索的,则(不论相对于源文件项目的根目录或StdAfx.h文件的位置的位置)的包含指令中使用的路径和文件名必须与项目预编译头文件配置设置使用的完全匹配。这意想不到的副作用是,如果你有一个包含各种源文件的项目子目录,在这些文件中,你不需要使用像.. \ stdafx.h这样的相对路径来引用stdafx.h文件(如果你做VS会引发一个错误,指出它在查找预编译头文件时遇到了文件的结尾)。

只需使用未包含的#include“stdafx.h”,它将正常工作,因为VS会将此识别为使用预编译头的指令,并且它已知道正确预编译头的位置是由于stdafx.cpp预编译头部配置设置为“创建(/ Yc)”。

5

我一般也喜欢在我的项目的等级秩序,我发现有两种简单的方法包括预编译的头:

要么

  1. 把目录下stdafx.h位于编译器的包含目录中。

    属性 - VC++目录 - 包含目录:添加$(ProjectDir)

或者

  • 如果不存在太很多子目录,一个简单的方法来规避错误信息是这样的:

    • 把一个stdafx.h文件到您的每一个子目录中只包括顶层stdafx.h:不是,包括顶层文件有
      #include "..\stdafx.h"
    • #include "stdafx.h"在你的子目录下的所有源文件的第一行。
  • 这样一来,所有的代码文件使用相同的预编译的头文件,并没有其他复杂的设置做。

    6

    有趣的是,我使用的技巧是不是答案:

    1. 在项目的根文件夹中创建的stdafx.h和stdafx.cpp。
    2. 转到项目属性 - >预编译头。更改为“使用”。
    3. 转到stdafx.cpp,右键单击属性 - >预编译头。更改为“创建”。
    4. 转到项目属性 - >高级;将“强制包含文件”更改为stdafx.h;%(ForcedIncludeFiles)

    不要更改任何CPP文件;保持您的头文件原样。按原样构建。

    没有打字,没有RSI,没有包含路径的麻烦,没有其他痛苦和痛苦。而美丽的是,当你将解决方案转移到另一个平台时它仍然可以工作。真棒。

    0

    我会建议使用:

    $(ProjectDir)/pch/my_pch.h 
    

    “预编译头文件”
    “高级>强制包含文件”

    这将自动包括pch.cpp文件在开始时,因此.cpp文件中无需更改。

    这比改变include目录更好,因为有时你可能在include目录中有多个pch文件,然后你就不知道哪个文件被使用了。