Связанный .lib-файл связан с .dll
У меня была такая же проблема. Скажем, у меня есть проекты MyProject и TestProject. Я эффективно связал файл lib для MyProject с TestProject. Однако этот файл lib был создан, так как была построена DLL для MyProject. Кроме того, я не содержал исходный код для всех методов в MyProject, но только доступ к точкам входа DLL.
Чтобы решить проблему, я построил MyProject как LIB и связал TestProject с этим .lib-файлом (скопируйте вложенный файл .lib в папку TestProject). Затем я смогу снова создать MyProject как DLL. Он компилируется, поскольку lib, с которым связан TestProject, содержит код для всех методов в классах MyProject.
Если ваш исполняемый файл (и связанные библиотеки) скомпилирован с информацией об отладке (т. е. с флагом -g
до gcc
или g++
), вы можете использовать libbacktrace
Яна Тейлора (объявлено здесь здесь ]) изнутри GCC - см. его код здесь
В этой библиотеке (бесплатное программное обеспечение, лицензированное BSD) используется DWARF отладочная информация из исполняемых файлов и связанных библиотек по этому процессу. См. Его файл README .
Остерегайтесь того, что если вы скомпилируете с оптимизацией, некоторые функции могут быть встроены (даже не будучи явно помечены inline
в исходном коде и static
встроенные функции могут не иметь собственного собственного кода). Тогда backtracing не расскажет о них много.
Да, рассмотрев свой собственный исполняемый файл (/proc/self/exe
), используя, например, libbfd
или библиотеку синтаксического анализа файлов ELF, чтобы самостоятельно анализировать сами символы. По сути, вы должны написать код C, который делает эквивалент чего-то вроде
env LANG=C LC_ALL=C readelf -s executable | awk '($5 == "LOCAL" && $8 ~ /^[^_]/ && $8 !~ /\./)'
Насколько мне известно, динамический интерфейс компоновщика в Linux (<dlfcn.h>
) не возвращает адреса для статического (локального ).
Простым и довольно надежным подходом является выполнение readelf
или objdump
из вашей программы. Обратите внимание, что вы не можете указать путь псевдофайла /proc/self/exe
к ним, поскольку он всегда ссылается на собственный исполняемый файл процесса. Вместо этого вы должны использовать, например. realpath("/proc/self/exe", NULL)
, чтобы получить динамически выделенный абсолютный путь к текущему исполняемому файлу, который вы можете предоставить команде. Вы также определенно хотите, чтобы среда содержала LANG=C
и LC_ALL=C
, так что вывод команды легко анализируется (а не локализован на любой язык, который предпочитает текущий пользователь). Это может показаться немного глупым, но для этого требуется установить пакет binutils
, и вам не нужно обновлять свою программу или библиотеку, чтобы идти в ногу с последними событиями, поэтому я думаю, что это в целом довольно Хороший подход.
Хотелось бы привести пример?
Одним из способов облегчения создания отдельных массивов с информацией о символе во время компиляции. В принципе, после создания объектных файлов отдельный исходный файл динамически генерируется путем запуска objdump
или readelf
над связанными объектными файлами, генерируя массив имен и указателей, похожих на
const struct {
const char *const name;
const void *const addr;
} local_symbol_names[] = {
/* Filled in using objdump or readelf and awk, for example */
{ NULL, NULL }
};
возможно, с простой функцией поиска, экспортированной в файл заголовка, так что, когда последний исполняемый файл связан, он может легко и эффективно получать доступ к массиву локальных символов.
Он дублирует некоторые данные, поскольку такая же информация уже находится в исполняемом файле, и если я правильно помню, вы должны сначала связать конечный исполняемый файл с массивом-заглушкой, чтобы получить фактические адреса для символов, а затем повторно связать с массивом символов, что делает его немного сложным время компиляции. Но это позволяет избежать зависимости от времени выполнения binutils
.