VC++ でインクルードされたヘッダー ファイルのパスを取得する
-
16-09-2019 - |
質問
環境:MS-VC++ 6.0を使用していますが、
- いくつかのデータを含むヘッダーファイルのグループを含めます。
- ヘッダーファイルは頻繁に変更されるため、変更ごとにパス設定と再コンパイラーを変更します
- 付属のヘッダーファイルに基づいてログファイルが生成されます
ログファイルからヘッダーファイルを追跡するには、ログ内のヘッダーファイルパスを印刷したい
質問1: プログラム内からヘッダーファイルパスを取得できますか?
- 質問2: 私はVC ++を使用していますが、GCCで可能であれば、簡単にポートできますので、GCCのような他の環境で可能であるかどうかを教えてください
解決
他のヒント
確かに - ヘッダーファイルPUT内部ます:
static const char *header_path = __FILE__;
..そして、単なる文字列を印刷し、あなたのログにheader_path
によって指されます。
あなたは#include "path/to/header.h"
を持つ、あなたがプログラム自体から「パス/に/がheader.h」を印刷することを意味するか?
#define INCLUDE_FILE "path/to/header.h"
#include INCLUDE_FILE
printf("Included: %s\n", INCLUDE_FILE);
あなたはこのようなファイルが含まれるのリストを取得することができます。
(project)
(export makefile)
(write dependencies when writing make files)
.MAKファイルおよび.DEPファイルを作成する、メイクファイルをエクスポートします。 インクルードファイルが.DEPファイルに記載されています。
実行中のプログラム内からインクルードファイルのフルパスを取得するというアイデアについては。一つは、IDEのうち、ファイルパスを含めるのリストを引っ張って、MSVC 6オブジェクトモデルを使用して使用することができるかもしれません。一度そのリストが知られています。一つは、関心のインクルードファイルのパスのリストを検索し、ファイルを見つける使用することができます。
OK、これが解決策です(正しく理解できたと思います)。
再帰的テンプレートを使用します。 __FILE__
マクロ、そして __COUNTER__
大きい。特別な headerlisting.h
ヘッダー ファイルにはテンプレート再帰のロジックが含まれており、2 つの便利なマクロ (およびいくつかのヘルパー マクロ) が含まれています。
ADD_HEADER_FILE
, 、リストに含めたいすべてのヘッダー ファイルにこの行を追加するだけです。LIST_HEADER(headers)
, これをソースに挿入すると、含まれるすべてのヘッダー ファイルのリストを実行時に取得できます。
おそらく Boost のテンプレート p0werz を使用して、これを行う簡単な方法があると思います。コメントしてください。
以下が最初です headerlisting.h
, 、次に 2 つのサンプル ヘッダーと main() ソース ファイルを含むサンプル プログラムです。これは Linux では g++ で動作しますが、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__
次にプログラム例を見てみましょう。
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__
ヘッダーテスト.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;
}
生成される出力は次のようになります (つまり、head1.h または head2.h を headertest.cpp から除外しない場合)。
Found 2 headers
header 0 : head1.h
header 1 : head2.h
これはうまくいくと教えてください。