Одним из важных аспектов в дополнение к другим, которые, несомненно, будут упомянуты, является то, что C легче взаимодействовать с другими языками, поэтому в случае библиотеки, предназначенной для широкого использования, C может быть выбран даже сегодня для этой цели.
Чтобы взять примеры, с которыми я знаком, инструментарий GTK + (в C) имеет надежные привязки OCaml, в то время как Qt и Cocoa (соответственно в C ++ и Objective C) имеют только проверки концепций для таких привязок. Я считаю, что сложность интерфейса с другими языками, кроме C, с OCaml является одной из причин.
Проверьте параметр компоновщика -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
А как насчет набора тестов? Вы создаете фиктивные исполняемые файлы, которые ссылаются на нужные вам символы. Если связывание не удается, это означает, что интерфейс вашей библиотеки не завершен.
Однажды у меня была такая же проблема. Я разрабатывал компонентную модель на C ++, и, конечно же, компоненты должны загружаться во время выполнения динамически. На ум приходят три решения, которые я применил:
Надеюсь, что это поможет.
cpp для него.Надеюсь, что это поможет.
cpp для него.Надеюсь, что это поможет.
В Linux (который, похоже, вы используете) ldd -r a.out
должен дать вам именно тот ответ, который вы ищете.
ОБНОВЛЕНИЕ: тривиальное способ создания a.out
для проверки:
echo "int main() { return 0; }" | g++ -xc++ - ./libMySharedLib.so
ldd -r ./a.out