Объектные файлы и библиотеки - C (СИ)
Формулировка задачи:
Доброго времени суток.
Хотелось бы узнать несколько вещей:
1. Есть ли разница между объектником и статической библиотекой, сделанной из одного объектного файла? Другими словами, могу ли я использовать объектник как статическую библиотеку?
2. Есть ли возможнсоть как-то в хедере записать адреса функций из статической библиотеки (уже готовой), так чтобы компилятор не включал код библиотеки в код программы, а ссылался на статическую библиотеку? (соответственно нужно будет наличие библиотеки всегда вместе с программой, это чем-то напоминает динамические библиотеки, только извращенно и через статические)
Буду благодарен если не будет ответов вида "используй динамические библиотеки и не заморачивайся". Мне интересно именно возможно ли сделать так. Позволяет ли сама структура статических библиотек такого извращения, и какие есть подводные камни в случае если позволяет.
Как я вижу эту ситуацию:
1. Разница между объектником и статической библиотекой минимальна, или отсутствует.
2. Это можно сделать только в случае знания точного адреса самой библиотеки и функций внутри библиотеки. Придется как-то заморачиваться через указатели на функцию.
Но в своем мнении я не уверен, ибо не сильно шарю в теме.
Гуглил - не нашел почти ничего, возможно плохо гуглю, тогда проблема куда печальнее...
Спасибо за ответы.
Решение задачи: «Объектные файлы и библиотеки»
textual
Листинг программы
typedef char*(__thiscall*type_pfnDebugExecute)(void*, const char *); type_pfnDebugExecute g_pfnDebugExecute; //... g_pfnDebugExecute = Pattern("DebugEx", { 0x64,0xa1,0x00,0x00,0x00,0x00, 0x6a,0xff, 0x68,0,0,0,0, 0x50, 0x64,0x89,0x25,0x00,0x00,0x00,0x00, 0x83,0xec,0x50, 0x56 }, "xxxxxxxxx????xxxxxxxxxxxx"); //... int DebugExecute(const char *code) { if (g_pfnDebugExecute == NULL || g_pEngineObject == NULL) return 0; return atoi(g_pfnDebugExecute(g_pEngineObject, code)); }
Объяснение кода листинга программы
typedef char*(__thiscall*type_pfnDebugExecute)(void*, const char *);
- это определение типа функции обратного вызова, которая принимает два аргумента: указатель на объект и строку.type_pfnDebugExecute g_pfnDebugExecute;
- это объявление переменной типаtype_pfnDebugExecute
с именемg_pfnDebugExecute
.g_pfnDebugExecute = Pattern(
DebugEx,...)
- это присваивание переменнойg_pfnDebugExecute
значения, возвращаемого функциейPattern
. ФункцияPattern
ищет шаблон в исполняемом файле и возвращает указатель на соответствующую функцию.int DebugExecute(const char *code)
- это объявление функцииDebugExecute
, которая принимает один аргумент типаconst char*
и возвращаетint
.if (g_pfnDebugExecute == NULL || g_pEngineObject == NULL)
- это проверка наличия функции обратного вызова и объектаEngineObject
. Если хотя бы одно из условий не выполняется, функцияDebugExecute
возвращает0
.return atoi(g_pfnDebugExecute(g_pEngineObject, code));
- это возвращение значения, преобразования строки в целое число с помощью функцииatoi
. Значение берется из функции обратного вызова, переданной в качестве аргументаg_pfnDebugExecute(g_pEngineObject, code)
.