如何从根目录中包含stdafx.h?

时间:2012-09-15 02:47:37

标签: c++ visual-c++

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

在我的cpp文件中我有

#include "..\stdafx.h"

然而我收到以下错误:

  

错误 C1010 :查找预编译标头时意外结束文件。您是否忘记在源代码中添加“#include”stdafx.h“'?

我的理解是,..应该指示编译器进入一个目录级别?

7 个答案:

答案 0 :(得分:10)

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

  1. 在项目的根文件夹中创建stdafx.h和stdafx.cpp。
  2. 转到项目属性 - >预编译的头文件。更改为"使用"。
  3. 转到stdafx.cpp,右键单击属性 - >预编译的头文件。更改为"创建"。
  4. 转到项目属性 - >高级;改变"强制包含文件"到stdafx.h;%(ForcedIncludeFiles)
  5. 不要更改任何CPP文件;保持头文件不变。按原样构建。

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

答案 1 :(得分:9)

我通常也喜欢在我的项目中使用分层顺序,我发现有两种简单的方法可以包含预编译的标题:

无论

  1. stdafx.h所在的目录放入编译器的include目录中。

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

  2. 或者

    1. 如果没有太多子目录,绕过错误消息的简单方法是这样的:

      • stdafx.h文件放入每个子目录中,这些子目录只包含顶级stdafx.h
        #include "..\stdafx.h"
      • #include "stdafx.h"写为子目录中所有源文件的第一行,而不是在那里包含顶级文件。
    2. 这样,您的所有代码文件都使用相同的预编译头文件,并且没有其他复杂的设置可以执行。

答案 2 :(得分:3)

您可以基于每个文件调整预编译的标头设置。

  1. 在解决方案资源管理器中右键单击.cpp文件,选择"属性"。
  2. 我强烈建议您选择"所有配置"在“配置”下拉列表项中。
  3. 浏览" C / C ++" - "预编译标题"。
  4. 调整"预编译的头文件"来自" stdafx.h"满足您的需求(例如"../stdafx.h")。
  5. 请注意,这样做既繁琐又容易出错,因为它是基于每个文件完成的,未来的开发人员在项目中添加文件时必须遵循相同的步骤。如果他们不接受警告和错误,例如:

    • 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并最终来到这里......您好,感谢您的阅读。

    在此基础上,值得使用替代方案,例如将$(ProjectDir)放在C ++ Include路径上(在C ++ \ General下),但这会在包含其他头文件时引起混淆。

答案 3 :(得分:1)

我建议使用:

$(ProjectDir)/pch/my_pch.h

as &#34;预编译的头文件&#34;
&#34;高级&gt;强制包含文件&#34;

这会在开头自动为您的pch文件添加.cpp,因此.cpp文件中无需更改任何内容。

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

答案 4 :(得分:0)

混淆的原因是Visual Studio将包含预编译头的include指令与其他include指令区别对待。具体来说,它不使用普通路径查找方法查找预编译头,而只是尝试通过简单的字符串比较将include伪指令与项目配置中定义的匹配。

预编译器头配置是通过gobally设置的,但每个文件都可以覆盖。正常的全局配置(通过项​​目属性访问 - &gt;配置属性 - &gt; C / C ++ - &gt;预编译标题)是:

$foo = 12;
$bar = 'hello';

$vars = get_defined_vars();

foreach (array_keys($vars) as $var) {
    $vars[$var] = &$$var; // keep refs of all variables from current scope
}

$run = function() use($vars) {
    extract($vars, EXTR_REFS);
    $foo = 13;
    $bar = 'bye';
};

// execute $run function
$run();
print $foo; // prints 13
print $bar; // prints bye

此配置默认应用于项目中的所有文件。但是,stdafx.cpp的配置在文件级别设置,并将预编译的标头值覆盖为:

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

这样做的结果是,对于任何配置为使用预编译头文件的源文件(默认情况下除了stdafx.cpp之外都是其中所有头文件),VS将查找与配置的预编译头文件值匹配的include指令。 e.g。

Precompiled Header: Create (/Yuc)

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

只需使用朴素的#include&#34; stdafx.h&#34;并且它会正常工作,因为VS会将此识别为使用预编译头的指令,并且它已经知道正确的预编译头的位置,因为stdafx.cpp预编译头配置被设置为&#34;创建(/ Yc) &#34;

答案 5 :(得分:-1)

如果你项目的.cpp和.h文件存在于不同的子目录中(不明显地位于项目目录中),那么使用包含相对于解决方案目录的路径的编码风格是一种很好的编码方式(如果你没有&#39 ; t使用专用的include目录)。特别是如果您在解决方案中有多个项目并且需要共享包含文件(例如,项目之间的互操作性,例如.exe和.dll)。

要重构您的项目,您需要执行以下操作:

  1. 在每个项目中指定其他包含目录 $(SolutionDir):右键单击项目,单击&#34;属性&#34;,转到 &#34;配置属性&#34; - &gt;&#34; C / C ++&#34; - &gt;&#34;一般&#34; (为所有人这样做 配置一次,选择&#34;所有配置&#34;来自 &#34;结构&#34;下拉)
  2. 转到&#34; C / C ++&#34; - &gt;&#34;预编译标题&#34; 并更改&#34;预编译的头文件&#34;相对于路径的值 解决方案目录,例如PROJECT_NAME / stdafx.h中
  3. 在你的.cpp中 文件包括&#34; PROJECT_NAME / stdafx.h&#34;,而不仅仅是&#34; stdafx.h&#34;
  4. 在.h和.cpp文件中,当包含某些内容时,请使用path as &#34; PROJECT_NAME / dir1 / dir2 / file.h&#34;,除非包含来自 同一目录

答案 6 :(得分:-3)

使用引号意味着它是您自己使用的头文件<>意味着它是一个系统头文件,如果我没有弄错,只需使用#include <stdafx.h>并让编译器找到它