2009-03-06 1 views
1

Для библиотеки отладки и регистрации я хочу, чтобы во время выполнения находил список всех исходных файлов, которые был скомпилирован проектом, и связаны между собой. Я предполагаю, что я буду включать какой-то заголовок в каждом исходном файле, а макрос препроцессора __FILE__ может дать мне константу символа для этого файла, поэтому мне просто нужно как-то «транслировать» эту информацию из каждого файла, который будет собран время выполнения.Регистрация каждого исходного файла C/C++ для создания списка использованных источников времени исполнения

Вопрос в том, как изящно сделать это, и особенно если это можно сделать с C, а не с C++. В C++ я бы попытался создать класс со статическим хранилищем для хранения списка имен файлов. Каждый заголовочный файл создавал бы локальный статический экземпляр этого класса, который при создании добавлял бы указатель FILE или что-то еще в члены статических данных класса, возможно, в качестве связанного списка.

Но я не думаю, что это сработает на C, и даже на C++ я не уверен, что будет гарантированно, что каждый элемент будет создан.

+0

Вы используете make-файлы или Visual Studio/Eclipse/etc? –

ответ

4

Я бы так не делал этого в коде. Я бы написал инструмент, который проанализировал файл проекта (vcproj, makefile или даже просто сканировать каталог проекта для файлов * .c *) и сгенерировал дополнительный исходный файл C, в котором были указаны имена всех исходных файлов в некотором пред- инициализированная структура данных.

Я бы сделал этот инструмент частью процесса сборки, чтобы каждый раз, когда вы делаете сборку, все это произойдет автоматически. Во время выполнения все, что вам нужно сделать, это прочитать структуру данных, которая была построена.

+0

Проведите анализ vcproj - это дополнительная работа. Scan dir ничего не гарантирует. –

0

Я не думаю, что вы можете сделать это так, как вы начертаете в «пассивном» режиме. То есть вы собираетесь каким-то образом запустить код для каждого исходного файла, который будет добавлен в реестр, трудно заставить его произойти автоматически.

Конечно, вы можете сделать этот код очень ненавязчивым с помощью макросов. Это может быть проблематично для исходных файлов C, у которых нет «точки входа», поэтому, если ваш код еще не организован как «модули», например, функция init() для каждого модуля, это может быть сложно. Статический код инициализации может быть возможен, я не уверен на 100%, если порядок, в котором происходит инициализация, создает проблемы здесь.

Использование static Хранилище в модуле реестра звучит как отличная идея, простой связанный список или простая хеш-таблица должны быть достаточно легкими для реализации, если ваш проект еще не включает в себя универсальную библиотеку утилиты.

+0

Можно автоматизировать. См. Мой ответ. –

0

В C++ ваше решение будет работать. Это гарантировано.

Edit: Только что узнал решение в моей голове: Изменить правила в вашем Makefile, чтобы добавить «-Include„cfiles_register.h“» каждому «file.cpp г ++».

%.o : %.cpp 
    $(CC) -include 'cfiles_register.h' -o [email protected] $< 

Поместите предложенное в вопрос воплощение на этот вопрос «cfiles_register.h».

1

Там нет способа сделать это в C. В C++ вы можете создать класс, как это:

struct Reg { 
    Reg(const char * file) { 
     StaticDictionary::Register(file); 
}; 

где StaticDictionary одноэлементно контейнер для всех ваших имен файлов. Затем в каждом исходном файле:

static Reg regthisfile(__FILE__); 

Вы хотели бы сделать словарь Meyers синглтона, чтобы избежать проблем, порядка создания.

+0

Почему заказ в этом случае является проблемой? –

+0

Потому что вы должны убедиться, что статический словарь создан до того, как вы попытаетесь его использовать. Поскольку вы не можете зависеть от порядка создания глобалов, вам нужно создать его при первом использовании через шаблон singleton. –

+0

Не StaticDictionary :: Регистрация будет выполнять эту работу? –

2

Я согласен с Ferruccio, лучший способ сделать это - в системе сборки, а не в самом коде. Как расширение его идеи, добавьте цель в свою систему сборки, которая выгружает список файлов (которые он должен знать в любом случае) в файл C в виде строки или массива строк и компилирует этот файл в ваш источник. Это позволяет избежать множества осложнений в источнике и расширяться, если вы хотите добавить дополнительную информацию, такую ​​как номер версии из вашей системы управления исходным кодом, кто создал исполняемый файл и т. Д.

0

Использование статических экземпляров на C++ было бы работа хорошо.

Вы можете сделать это и в C, но вы должны использовать во время выполнения конкретных функций - для MSVC ЭЛТ взглянуть на http://www.codeguru.com/cpp/misc/misc/threadsprocesses/article.php/c6945/

Для C - вы можете сделать это с помощью макроса - определить переменную, соответствующую ваш файл, а затем вы можете сканировать символы исполняемого файла, так же, как идея:

#define TRACK_FILE(name) char _file_tracker_##name; 

использовать его в my_c_file.c так:

TRACK_FILE(my_c_file_c) 

и чем Grep все файлы/имена переменных из двоичного файла как этот

nm my-binary | grep _file_tracker 

Не очень приятно, но ...

2

Существует стандартный способ на UNIX и Linux - ident. Для каждого исходного файла вы создаете идентификационный тег - обычно он назначается системой управления версиями, например. SVN keywords.

Затем, чтобы узнать имя и ревизию каждого исходного файла, вы просто используете команду ident. Если вам нужно сделать это во время выполнения, проверьте, как это делается ident - источник для него должен быть свободно доступен.

0

Ужасная идея, я уверен, но использую синглтон. И в каждом файле что-то вроде

Singleton.register(__FILE__); 

at global scope. Однако это будет работать только на cpp-файлах. Я сделал что-то вроде этого года назад как новичок, и это сработало. Но я бы съежился, чтобы сделать это сейчас. Я бы добавил шаг сборки сейчас.

0

Я согласен с теми, кто говорит, что лучше избегать делать это во время выполнения, но в C, вы можете инициализировать статическую переменную с вызовом функции, то есть, в каждом файле:

static int doesntmatter = register(__FILE__); 
+0

register - это ключевое слово в c, и его обычно следует избегать – EvilTeach

+0

да, согласитесь, взял его из другого ответа, как кажется - слепо :-) – dmityugov

Смежные вопросы