【问题标题】:Getting included header file path in VC++在 VC++ 中获取包含的头文件路径
【发布时间】:2009-12-08 01:25:06
【问题描述】:

环境:我使用的是MS-VC++ 6.0,

  • 我包含一组头文件 一些数据。
  • 头文件经常变化,以此类推 每一次改变我都会改变路径 设置并重新编译
  • 根据 包含头文件
  • 用于跟踪头文件 日志文件,我希望打印 日志里面的头文件路径

  • 问题 1: 正在获取标题 程序内部的文件路径 可能吗?

  • 问题 2: 我正在使用 VC++,但如果 在 gcc 中是可能的,那么我可以 轻松移植,所以,请告诉我, 如果有可能在任何其他 gcc 等环境

【问题讨论】:

  • 你的意思是你的程序会生成一个运行时日志,它应该记录程序编译时使用的所有头文件(至少是一些特别准备的头文件)?
  • @Vainstah,我更改了头文件路径并重新编译。这是一个非常基本的事情,我认为这是显而易见的。

标签: c visual-c++ gcc visual-c++-6 header-files


【解决方案1】:

在 VC++ 中,使用选项 /FC 进行编译会将当前处理的文件的整个路径放入 __FILE__ 宏中。

这将解释您对包含路径的更改。

Details here.

【讨论】:

  • 我不明白,这如何回答这两个问题?是 gcc 的替代品吗?
【解决方案2】:

当然 - 在头文件里面放:

static const char *header_path = __FILE__;

..然后只需将header_path 指向的字符串打印到您的日志中。

【讨论】:

  • 然后每个包含该头文件的翻译单元都会获得自己的 header_path 副本 :)
  • 我也在考虑这个问题,但是如何获得所有头文件的单个列表?带有该行的两个头文件将无法编译,如果您使用不同的变量名,您仍然需要在源代码中为您添加的每个头文件提供一些宏逻辑......对吗?
  • 我确定我见过一个编译器,其中__FILE__ 不包含路径,只包含文件名部分。不过,不记得某些 Symbian 模拟器使用的 Intel x86 编译器是什么?不过,根据要求,这对 MSVC 和 GCC 都适用。
  • “如何获得所有头文件的单一列表”。您可以使用工具链生成一些 cpp 文件的头文件依赖项的单个列表,并将结果转储到单个 cpp 文件中并编译它。使用 gcc 和 make 或 shell 脚本应该非常简单,但我无法提供一个 MSVC/Windows shell 等价物。
  • @pmg:您可以通过使用一些宏有条件地定义header_path 来避免多重定义。然后只有 #define logging.c 中的那个宏,或者它被调用的任何东西。
【解决方案3】:

您的意思是拥有#include "path/to/header.h",您想从程序本身打印“path/to/header.h”?

#define INCLUDE_FILE "path/to/header.h"
#include INCLUDE_FILE

printf("Included: %s\n", INCLUDE_FILE);

【讨论】:

    【解决方案4】:

    你可以像这样获取包含文件的列表。

    (project)
    (export makefile)
    (write dependencies when writing make files)
    

    导出 make 文件,这将创建 .mak 文件和 .dep 文件。 包含文件列在 .dep 文件中。

    关于从正在运行的程序中获取包含文件的完整路径的想法。可以使用 msvc 6 对象模型将包含文件路径列表拉出 IDE。一旦知道该列表。可以使用查找文件,在路径列表中搜索感兴趣的包含文件。

    【讨论】:

      【解决方案5】:

      好的,这是一个解决方案(现在我希望我理解正确)。

      它使用递归模板、__FILE__ 宏和__COUNTER__ 宏。 一个特殊的headerlisting.h 头文件包含模板递归的逻辑,并包含两个有用的宏(加上一些辅助宏)

      1. ADD_HEADER_FILE,只需将此行添加到您要包含在列表中的每个头文件中。
      2. LIST_HEADER(headers),您可以将其放入源代码中,以便在运行时检索所有包含头文件的列表

      我确信有一种更简单的方法可以做到这一点,也许使用 Boost 的模板 p0werz,请发表评论。

      下面首先是headerlisting.h,然后是一个包含两个示例头文件和一个 main() 源文件的示例程序。这适用于带有 g++ 的 Linux,希望它也适用于 Visual Studio(目前无法测试)。

      headerlogic.h

      #ifndef __HEADERLOGIC_H__
      #define __HEADERLOGIC_H__
      
      // By catchmeifyoutry, 2009-12-08
      //  See http://stackoverflow.com/questions/1863995/getting-included-header-file-path-in-vc
      
      #include <vector>
      #include <string>
      
      namespace HeaderListing
      {
      
      // Recursive templates to store header files, templatized by a header index I.
      // Header files will be stored by template specialization, adding new specializations
      // for every new header.
      //
      // The recursive headers depend on the assumption that the for the previous index I-1
      // there is a HeaderFile<I-1> defined which contains a method
      //   void HeaderFile<I-1>::list_headers(std::vector<std::string> &headers)
      // to list all I-1 previous header files.
      // The I-th HeaderFile then defines it's own list_header(...) to add one name
      // to the list.
      
      // -------------------------------------
      // Recursive case
      //    By default, list_headers() adds no name to the list, but if this default case
      //    is specialized with c-string for name, it will add to the list
      template <int I>
      class HeaderFile
      {
      public:
          typedef HeaderFile<I-1> PrevHeader;
      
          // in the specalization, this will store the name of header file;
          // but if no header with index I is given, name will be NULL by default
          static const char * name;
      
          // in the recursive case
          static inline void list_headers(std::vector<std::string> &headers)
          {
              PrevHeader::list_headers(headers);
              if (name != NULL) {
                  headers.push_back(name);
              }
          }
      };
      template <int I> const char * HeaderFile<I>::name = NULL;
      
      // -------------------------------------
      // Base case
      //    Ensures recursion ends, implements dummy list_headers()
      template <>
      class HeaderFile<-1>
      {
      public:
          static inline void list_headers(std::vector<std::string> &headers)
          { /* end of recursion, do nothing! */ }
      };
      
      }; // namespace HeaderListing
      
      // -------------------------------------
      // Macros to add header files
      
      // Add n-th header file name (as a string) to the list
      #define ADD_HEADER_FILE_NAME_N(n, file) template <> const char * HeaderListing::HeaderFile<n>::name = __FILE__; \
      
      // Add a given string (e.g. a header filename) to the to the list
      //   Uses built-in __COUNTER__ macro to track the current header count.
      //   NOTE: it doesn't matter if count was used in between since there can be gaps in between the header indices
      #define ADD_HEADER_FILE_NAME(file) ADD_HEADER_FILE_NAME_N(__COUNTER__, file)
      
      // Add the current (header) file to the list
      //   Uses the built-in __FILE__ macro.
      #define ADD_HEADER_FILE ADD_HEADER_FILE_NAME(__FILE__)
      
      // List all defined header files
      //   The "headers" argument should be a std::vector<std::string>
      #define LIST_HEADERS(headers) HeaderListing::HeaderFile<__COUNTER__>::list_headers(headers);
      
      #endif // __HEADERLOGIC_H__
      

      现在是示例程序:

      head1.h

      #ifndef __HEAD1__
      #define __HEAD1__
      
      #include "headerlisting.h"
      ADD_HEADER_FILE
      
      #endif // __HEAD1__
      

      head2.h

      #ifndef __HEAD2__
      #define __HEAD2__
      
      #include "headerlisting.h"
      ADD_HEADER_FILE
      
      #endif // __HEAD2__
      

      headertest.cpp

      #include <iostream>
      #include <vector>
      #include <string>
      
      #include "headerlisting.h"
      #include "head1.h" // <-- TRY COMMENTING THESE OUT!
      #include "head2.h" // <-- TRY COMMENTING THESE OUT!
      
      using namespace std;
      
      int main()
      {
          // list included header files
          vector<string> headers;
          LIST_HEADERS(headers);
      
          // display included header files
          size_t n = headers.size();
          cout << "Found " << n << " headers" << endl;
          for (size_t h = 0; h < n; ++h)
          {
              cout << "header " << h << " :\t" << headers[h] << endl;
          }
      
          return 0;
      }
      

      生成的输出应该是这样的(如果不排除headertest.cpp中的head1.h或head2.h,即):

      Found 2 headers
      header 0 :  head1.h
      header 1 :  head2.h
      

      请告诉我这是可行的。

      【讨论】:

        猜你喜欢
        • 2014-10-21
        • 2021-07-11
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 2012-12-16
        • 2021-04-03
        • 2015-11-01
        相关资源
        最近更新 更多