«Неопределенная ссылка на функцию» выдается даже после связывания библиотеки с определением - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь создать исполняемый файл с файлами .o, .so, .a.

Вот моя команда сборки: -

pkgs/gcc/v4.8.3/bin/gcc -L/usr/X11R6/lib -O2 -DUSE_FLEX -Wall -Wno-char-subscripts -fPIC -DLINUX -DG_DISABLE_CONST_RETURNS -fno-strict-aliasing -o ../build/kl/Release/test/bin/pure.exe -L../build/kl/Release/test/modules ../build/kl/Release/test/maker/constrfunc.TCL.o ../../build/kl/Release/test/maker/pvdbprocs.TCL.o .. ../build/kl/Release/test/maker/maker/memmaker.TCL.o .. ../build/kl/Release/test/maker/modules/libdenbase.a .. ../build/kl/Release/test/maker/guibase.o -litk3.2 -litcl4.0.0 -ltk8.3 -lcdnviptcl8.4 -litclstub4.0.0 -ldenbase -lglib-2.0 -ldenbase -lX11 -ldl -lm -lviputil -lvippli -lcdsCommonMT_sh -lpthread  -L/home/dlb/extlibs/arm/lib 

У меня есть библиотеки с определениямифункции в пути "-L / home / dlb / extlibs / arm / lib".Тем не менее, это ошибка ниже.

Ошибка:

../build/kl/Release/test/maker/guibase.o: In function `decodeAddrList':
tree234.c:(.text+0xc): undefined reference to `ptritclStubsPtr'
tree234.c:(.text+0x20): undefined reference to `ptrlitclStubsPtr'
tree234.c:(.text+0x12c): undefined reference to `ptrlitclStubsPtr'
tree234.c:(.text+0x140): undefined reference to `ptrlitclStubsPtr'

У меня есть символ в библиотеке, который находится по пути / home / dlb / extlibs / arm / lib: -

Команда: -

readelf -s libitcl4.0.0.so | grep ptrlitclStubsPtr

348: 0000000000060f10     8 OBJECT  LOCAL  DEFAULT   24 ptrlitclStubsPtr

Я что-то здесь упускаю?

Обратите внимание, OP предоставил больше информации в репосте того же вопроса;
цитата из комментария OP:
"Из-за некоторых проблем с конфиденциальностью ... Я переименовываю символы ... Это было отредактировано мной ... Это была опечатка ... Я просто исправил это ... :)"
Т.е. идентификаторы в сообщении об ошибке и в строке grep и на выходе строки grep были изменены вручную.

1 Ответ

0 голосов
/ 21 мая 2018

Похоже, что функции, о которых вы спрашиваете, local к файлу, в котором они были определены.То есть, похоже, что они были явно предназначены для (и даже не разрешены) для внешнего вызова.

То есть где-то в пределах источника для общей библиотеки libitcl4.0.0.so, вероятно, появляется объявление вроде:

static tclStubs *ptrlitclStubsPtr;

Это ключевое слово static указывает, что видимость результирующего символа ptrlitclStubsPtr ограничена его собственным исходным файлом.

Я выведу все это изтот факт, что ваш вывод readelf содержит строку

348: 0000000000060f10     8 OBJECT  LOCAL  DEFAULT   24 ptrlitclStubsPtr

Этот флаг LOCAL указывает, что символ является локальным.Если бы он был глобальным, предназначенным (и способным) вызываться извне, вместо него появился бы флаг GLOBAL.

Почему переменные стали частными (static), как это, поэтому вы не можете их использовать?Это программная технология, «скрытие информации», предназначенная для уменьшения «ширины» интерфейса между вами и библиотекой, такой как libitcl4.Частные символы более тесно связаны с решениями по реализации в libitcl4, решениями, которые не должны быть видны вызывающим абонентам или вызывать какие-либо опасения.Предполагается, что если бы у вызывающих абонентов был доступ к этим символам, они также должны были бы знать другие подробности реализации, что означает, что автор libitcl4 не сможет изменить эти подробности реализации, не нарушив (аннулировав) вызывающий код.Поэтому, чтобы предотвратить эту ситуацию, обычно делается выбор, чтобы вызывающая сторона не могла стать зависимой таким образом.

В этой ситуации у вас в основном есть три пути вперед:

  1. Удалите теги static из объявлений переменных в источниках до libitcl4.0.0.so.(Это, очевидно, требует, чтобы у вас был доступ к источникам libitcl4.0.0.so и возможность его перестроить. Это также, вероятно, очень плохая идея. Как я объяснил, эти символы, вероятно, были сделаны статичными по уважительной причине.)

  2. Добавьте новую функцию в libitcl4.0.0.so, которая делает все, что вам нужно, и которая благодаря своему расположению в том же исходном файле имеет доступ к этим символам.(Это также требует, чтобы у вас был доступ и возможность перестраивать `` libitcl4.0.0.so`.)

  3. Найдите другой способ сделать то, что вам нужно, используясуществующие общественные объекты libitcl4.0.0.so.

...