1

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

  • 我包括一组带有一些数据的头文件。
  • 头文件经常更改,所以每次更改我都会更改路径设置并重新编译
  • 根据包含的头文件生成日志文件
  • 为了从日志文件中跟踪头文件,我希望在日志中打印头文件路径

  • 问题1:是否可以从程序内部获取头文件路径?

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

5 回答 5

4

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

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

详情在这里。

于 2009-12-08T01:37:37.717 回答
1

当然 - 在头文件里面放:

static const char *header_path = __FILE__;

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

于 2009-12-08T01:30:07.247 回答
1

你的意思是#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);
于 2009-12-08T01:30:47.120 回答
0

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

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

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

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

于 2009-12-08T03:23:17.873 回答
0

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

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

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

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

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

头逻辑.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__

现在对于示例程序:

头1.h

#ifndef __HEAD1__
#define __HEAD1__

#include "headerlisting.h"
ADD_HEADER_FILE

#endif // __HEAD1__

头2.h

#ifndef __HEAD2__
#define __HEAD2__

#include "headerlisting.h"
ADD_HEADER_FILE

#endif // __HEAD2__

头文件测试.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

请告诉我这行得通。

于 2009-12-08T03:23:27.810 回答