#c #shared-libraries #dynamic-linking #gtkmm
#c #совместно используемые библиотеки #динамическое связывание #gtkmm
Вопрос:
Я разрабатываю некоторую библиотеку, используя Gtkmm4. Цель этой библиотеки — заменить удаленный API Gtkmm3 (например, Gtk::Window::move
). Особенно для этой конкретной функции мне нужно использовать gdk_x11_surface_move
. Компоновщик указывает неопределенную ссылку на gdk_x11_surface_move
. Моя библиотека libgdp.so
ссылается на следующие библиотеки Gtk:
$ ldd libgdp.so.1 | grep gtk
libgtkmm-4.0.so.0 => /home/user/.local/built/lib/libgtkmm-4.0.so.0 (0x00007f981fb5a000)
libgtk-4.so.1 => /home/user/.local/built/lib/libgtk-4.so.1 (0x00007f981d57a000)
И в этом libgtk-4.so.1
gdk_x11_surface_move
определяется:
$ nm /home/user/.local/built/lib/libgtk-4.so.1 --defined-only | grep x11_surface_move
0000000000461cc0 t gdk_x11_surface_move
0000000000462730 T gdk_x11_surface_move_to_current_desktop
0000000000462540 T gdk_x11_surface_move_to_desktop
Интересным / важным может быть следующий вывод, которого gdk_x11_surface_move
нет:
$ nm -D /home/papa/.local/built/lib/libgtk-4.so.1 --defined-only | grep x11_surface_move
0000000000462730 T gdk_x11_surface_move_to_current_desktop
0000000000462540 T gdk_x11_surface_move_to_desktop
В моем коде я использую gdk_x11_surface_move
так:
window.cpp
#include <window.hpp>
...
void Window::move(int x, int y) {
auto surface = this->get_surface().get();
gdk_x11_surface_move(surface, x, y);
}
...
window.hpp
...
extern "C" {
void gdk_x11_surface_move(Gdk::Surface *surface, int x, int y);
}
...
Я просто не понимаю, почему я не могу использовать эту функцию в своей библиотеке, хотя она определена / доступна в библиотеке Gtk. Можете ли вы найти решение? Если вам нужна дополнительная информация, пожалуйста, дайте мне знать, написав мне комментарий!
РЕДАКТИРОВАТЬ Библиотека связывается со следующей командой:
/bin/bash ./libtool --tag=CXX --silent --mode=link g -g -O2 -version-info 1:0: -L/home/user/.local/built/lib -o libgdp.la -rpath /home/user/.local/built/lib src/libgdp_la-logger.lo src/libgdp_la-window.lo src/libgdp_la-utils.lo -L/home/user/.local/built/lib -lgtkmm-4.0 -lpangomm-2.48 -lgiomm-2.68 -lglibmm-2.68 -lcairomm-1.16 -lsigc-3.0 -lgtk-4 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -L/home/user/.local/built/lib
и приложение со следующей командой, которая выдает ошибку:
g -g -O2 -L/home/user/.local/built/lib -o gdp-screenshot src/gdp_screenshot-main.o src/gdp_screenshot-application.o src/gdp_screenshot-prefswindow.o src/gdp_screenshot-savewindow.o src/gdp_screenshot-screenshot.o -L/home/user/.local/built/lib -L/home/user/Programme/c /GDP-Gtk/libgdp/.libs -lgdp -lgtkmm-4.0 -lpangomm-2.48 -lgiomm-2.68 -lglibmm-2.68 -lcairomm-1.16 -lsigc-3.0 -lgtk-4 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lX11 -L/home/user/.local/built/lib -lgtkmm-4.0 -lpangomm-2.48 -lgiomm-2.68 -lglibmm-2.68 -lcairomm-1.16 -lsigc-3.0 -lgtk-4 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -L/home/user/.local/built/lib -lfribidi -L/home/user.local/built/lib -lglibmm-2.4 -lgobject-2.0 -lglib-2.0 -lsigc-2.0 -L/home/user/.local/built/lib
/home/user/Programme/c /GDP-Gtk/libgdp/.libs/libgdp.so: warning: undefined reference to »gdk_x11_surface_move(Gdk::Surface*, int, int)«
collect2: error: ld returned 1 exit status
Makefile:525: recipe for target 'gdp-screenshot' failed
и фактически выбрасывается на этапе, когда приложение, использующее libgdp.so
библиотеку, связано. Сама библиотека компилируется и связывается нормально.
Комментарии:
1. Пожалуйста, вставьте точную ошибку.
2. @Бесполезно сделано.
3. И я предполагаю
/home/papa/...
, что и/home/user/...
на самом деле это один и тот же путь?4. @Точно бесполезно, я забыл заменить это! 🙁 и извините за долгое время ответа.
5.
gdk_x11_surface_move
похоже на функцию C, ваш компоновщик жалуется на функцию C . Возможно, выextern "C"
где-то забыли.
Ответ №1:
Я просто не понимаю, почему я не могу использовать эту функцию в своей библиотеке, хотя она определена / доступна в библиотеке Gtk.
$ nm /home/user/.local/built/lib/libgtk-4.so.1 --defined-only | grep x11_surface_move
0000000000461cc0 t gdk_x11_surface_move
Вы правы в том, что функция определена в libgtk-4.so.1
, но вы ошибаетесь в том, что она доступна: t
в nm
выводе означает, что это локальная функция. Такие функции не могут быть вызваны извне.
Есть несколько причин, по которым функция может получить локальную связь:
- функция объявляется
static
в файле, где она определена. - функция является глобальной, но скрыта во время компиляции (
-fvisibility=hidden
) или компоновки (с использованием сценария компоновщика).
Исправление зависит от того, почему функция является локальной. Для 1) выше подойдет удаление static
квалификатора. Для 2), возможно, вам потребуется добавить __attribute__((visibility("default")))
или отредактировать сценарий компоновочной версии.