Легкая проверка на неразрешенные символы в общих библиотеках?

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

Чтобы взять примеры, с которыми я знаком, инструментарий GTK + (в C) имеет надежные привязки OCaml, в то время как Qt и Cocoa (соответственно в C ++ и Objective C) имеют только проверки концепций для таких привязок. Я считаю, что сложность интерфейса с другими языками, кроме C, с OCaml является одной из причин.

75
задан Braiam 13 June 2014 в 20:30
поделиться

4 ответа

Проверьте параметр компоновщика -z defs / - no-undefined . При создании общего объекта это приведет к сбою ссылки, если есть неразрешенные символы.

Если вы используете gcc для вызова компоновщика, вы будете использовать параметр компилятора -Wl для передачи параметр для компоновщика:

gcc -shared ... -Wl,-z,defs

В качестве примера рассмотрим следующий файл:

#include <stdio.h>

void forgot_to_define(FILE *fp);

void doit(const char *filename)
{
    FILE *fp = fopen(filename, "r");
    if (fp != NULL)
    {
        forgot_to_define(fp);
        fclose(fp);
    }
}

Теперь, если вы встроите его в общий объект, все будет успешно:

> gcc -shared -fPIC -o libsilly.so silly.c && echo succeeded || echo failed
succeeded

Но если вы добавите -z defs , ссылка не удастся и сообщит вам об отсутствующем символе:

> gcc -shared -fPIC -o libsilly.so silly.c -Wl,-z,defs && echo succeeded || echo failed
/tmp/cccIwwbn.o: In function `doit':
silly.c:(.text+0x2c): undefined reference to `forgot_to_define'
collect2: ld returned 1 exit status
failed
88
ответ дан 24 November 2019 в 11:41
поделиться

А как насчет набора тестов? Вы создаете фиктивные исполняемые файлы, которые ссылаются на нужные вам символы. Если связывание не удается, это означает, что интерфейс вашей библиотеки не завершен.

8
ответ дан 24 November 2019 в 11:41
поделиться

Однажды у меня была такая же проблема. Я разрабатывал компонентную модель на C ++, и, конечно же, компоненты должны загружаться во время выполнения динамически. На ум приходят три решения, которые я применил:

  1. Найдите время, чтобы определить систему сборки, которая может компилироваться статически. Вы потеряете время на его разработку, но это сэкономит вам много времени на выявление этих надоедливых ошибок времени выполнения.
  2. Сгруппируйте свои функции в хорошо известные и понятные разделы, чтобы вы могли сгруппировать функции / заглушки, чтобы быть уверенными, что у каждой соответствующей функции есть заглушка. Если вы потратите время на его хорошее документирование, вы, возможно, сможете написать сценарий, который проверяет определения (например, через его комментарии doxygen) и проверяет соответствующий файл .cpp на его наличие.
  3. Выполните несколько тестовых исполняемых файлов, которые загружают тот же набор библиотек и укажите флаг RTLD_NOW для dlopen (если вы используете * NIX). Они будут сигнализировать о недостающих символах.

Надеюсь, что это поможет.

cpp для него.
  • Выполните несколько тестовых исполняемых файлов, которые загружают один и тот же набор библиотек, и укажите флаг RTLD_NOW для dlopen (если вы используете * NIX). Они будут сигнализировать о недостающих символах.
  • Надеюсь, что это поможет.

    cpp для него.
  • Выполните несколько тестовых исполняемых файлов, которые загружают один и тот же набор библиотек, и укажите флаг RTLD_NOW для dlopen (если вы используете * NIX). Они будут сигнализировать о недостающих символах.
  • Надеюсь, что это поможет.

    3
    ответ дан 24 November 2019 в 11:41
    поделиться

    В Linux (который, похоже, вы используете) ldd -r a.out должен дать вам именно тот ответ, который вы ищете.

    ОБНОВЛЕНИЕ: тривиальное способ создания a.out для проверки:

     echo "int main() { return 0; }" | g++ -xc++ - ./libMySharedLib.so
     ldd -r ./a.out
    
    14
    ответ дан 24 November 2019 в 11:41
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: