Получение включенного пути заголовочного файла в VC ++ - PullRequest
1 голос
/ 08 декабря 2009

Среда: я использую MS-VC ++ 6.0,

  • Я включаю группу заголовочных файлов с некоторые данные.
  • Заголовочные файлы часто меняются, поэтому каждое изменение я меняю путь настройка и повторный компилятор
  • Файл журнала создается на основе включенные заголовочные файлы
  • Для отслеживания файла заголовка из файл журнала, я хочу напечатать путь к заголовочному файлу внутри журнала

  • Вопрос-1: Получает заголовок путь к файлу внутри программы возможно

  • Вопрос-2: Я использую VC ++, но если можно в gcc, тогда могу легко портировать, поэтому, пожалуйста, дайте мне знать, если это возможно в любом другом окружающая среда, как GCC

Ответы [ 5 ]

4 голосов
/ 08 декабря 2009

В VC ++ компиляция с параметром /FC поместит полный путь текущего обработанного файла в макрос __FILE__.

Это будет учитывать ваши изменения в пути включения.

Подробности здесь.

1 голос
/ 08 декабря 2009

Вы имеете в виду, что имея #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);
1 голос
/ 08 декабря 2009

Конечно - внутри заголовочного файла положено:

static const char *header_path = __FILE__;

.. затем просто напечатайте строку, на которую указывает header_path, в ваш журнал.

0 голосов
/ 08 декабря 2009

Хорошо, вот решение (теперь, надеюсь, я вас правильно понял).

Используются рекурсивные шаблоны, макрос __FILE__ и макрос __COUNTER__. Специальный заголовочный файл headerlisting.h содержит логику для рекурсии шаблона и включает два полезных макроса (плюс несколько вспомогательных макросов)

  1. ADD_HEADER_FILE, просто добавьте эту строку в каждый заголовочный файл, который вы хотите включить в свой список.
  2. LIST_HEADER(headers), который вы можете поместить в исходный код для получения во время выполнения списка всех включенных заголовочных файлов

Я уверен, что есть более простой способ сделать это, может быть, с помощью шаблонов Boost p0werz, пожалуйста, прокомментируйте.

Ниже сначала headerlisting.h, а затем пример программы, содержащей два примера заголовков и основной () исходный файл. Это работает на Linux с g ++, надеюсь, что это работает и в Visual Studio (сейчас не могу протестировать).

headerlogic.h

#ifndef __HEADERLOGIC_H__
#define __HEADERLOGIC_H__

// By catchmeifyoutry, 2009-12-08
//  See /1405451/poluchenie-vklychennogo-puti-zagolovochnogo-faila-v-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;
}

Сгенерированный вывод должен выглядеть следующим образом (если вы не исключаете head1.h или head2.h из headertest.cpp, то есть):

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

Пожалуйста, скажите мне, что это работает.

0 голосов
/ 08 декабря 2009

Вы можете получить список включаемых файлов следующим образом.

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

экспорт файлов make, который создает файлы .mak и .dep. Включаемые файлы перечислены в файлах .dep.

Что касается идеи получения полного пути к включаемым файлам из запущенной программы. Можно использовать объектную модель msvc 6 для извлечения списка путей включаемых файлов из IDE. Как только этот список известен. Можно использовать поиск файла для поиска в этом списке путей для включаемых файлов.

...