В вашем очень неясном вопросе упоминаются файлы .so
(но не указано ни одной операционной системы) и nm
. Поэтому я предполагаю, что вы на Linux, и мой ответ специфичен для Linux. Я не понимаю, хотите ли вы работать при компиляции & времени сборки или во время выполнения.
Учитывая общий объект /some/path/to/foo.so
можно использовать dlopen(3) и dlsym(3) функции, чтобы выяснить (во время выполнения), если это общий объект определяет данный символ. Но имейте в виду, что в ELF символами файлов являются почти нетипизированы (например, вы не можете знать подпись некоторой функции в общем объекте ELF от своего имени, без наличия некоторого файла заголовка C, объявляющего его).
Возможно, у вас может быть более сложная процедура software build (например, добавив специальные правила для вашего Makefile
). Помните, что вы можете использовать методы metaprogramming и иметь встроенный генератор кода C. Если ваше программное обеспечение достаточно сложно (например, стоит потратить несколько недель на такие инструменты), вы даже можете настроить компилятор GCC с помощью GCC MELT (или написать собственный плагин GCC).
Обратите внимание, что некоторые файлы заголовков (для данной библиотеки) можно определить функцию inline
или может определить макрос с аргументами для него (например, см waitpid(2), часть POSIX API; WIFEXITED
практически макро). В обоих случаях эта функция не будет символом общей библиотеки ELF, но может быть использована из исходного кода правильно с использованием этой библиотеки (и правильно #include
-в соответствующих заголовках). Другими словами, API не совпадает с набором символов ELF.
Читайте также Good Practices in Library Design, Implementation, and Maintenance и How To Write Shared Libraries и D.Wheeler Program Library HOWTO.
Наконец, компилятор не может оптимизировать, если добавить код в зависимости от условий, которые, как известно, всегда являются ложными (см. Примерно opaque predicates), например.
int main(int argc, char**argv) {
// in practice, all the tests above are false,
// but the compiler is not clever enough to optimize
if (getpid()==0) funct1(); // always false
if (argc<0) funct2(); //always false
if (argv[0][0]==(char)0) funct3(); //always false
/// etc
В случае сигнатура функции требуют некоторые аргументы, вы могли бы просто проверить свой адрес:
extern void func1(int); // actually, in some included header
if (argv[0]==NULL || (void*)func1 == NULL
|| (void*)func1 == (void*)3) abort();
(я считаю, что стандарты C позволяют компилятору оптимизировать (void*)func1 == NULL
-as всегда ложно - но это не будет оптимизировать (void*)func1 == (void*)3
, которые в практике всегда ложна на Linux ...)
, но опять же, API больше набор символов ELF и функция «API» API могут фактически быть inline
или макросом. Вас может заинтересовать weak symbols.
Попробуйте перекомпилировать gcc '-O0', он должен отключить все оптимизации – Arseniy
Очень неясный вопрос. Не могли бы вы быть более конкретными и дать реальный прецедент и мотивацию. Я даже не понимаю, что означает «недостающая функция в API», учитывая, что API является документированным набором публичных функций и т. Д. Поэтому, пожалуйста, ** отредактируйте свой вопрос **, чтобы улучшить его и мотивировать. Быть более конкретным и конкретным. –
Каково практическое применение? Вы хотите взять все C-функции из Стандарта и проверить, поддерживает ли ваш компилятор? Это большая работа. Почему бы не спросить автора компилятора, что поддерживает компилятор и каковы ограничения? –