为什么我不能使用链接的功能?
Why can i not use a function that is linked?
我正在使用 Gtkmm4 开发一些库。该库的目的是替换 Gtkmm3 中删除的 API(例如 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
库的应用程序的阶段抛出的。库本身可以很好地编译和链接。
I just do not understand why I cannot use that function in my library, even though it is defined / available in the Gtk library.
$ 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
中 定义 函数是正确的,但错误 函数可用: nm
输出中的 t
表示它是一个 local 函数。不能从外部调用此类函数。
一个函数可能会局部化的原因有几个 linkage:
- 函数在定义它的文件中声明
static
。
- 该函数是全局的,但在编译 (
-fvisibility=hidden
) 或 link 时隐藏(使用 linker 版本脚本)。
修复取决于为什么函数是本地的。对于上面的 1),删除 static
限定符即可。对于 2),您可能需要添加 __attribute__((visibility("default")))
,或者您可能需要编辑 linker 版本脚本。
我正在使用 Gtkmm4 开发一些库。该库的目的是替换 Gtkmm3 中删除的 API(例如 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
库的应用程序的阶段抛出的。库本身可以很好地编译和链接。
I just do not understand why I cannot use that function in my library, even though it is defined / available in the Gtk library.
$ 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
中 定义 函数是正确的,但错误 函数可用: nm
输出中的 t
表示它是一个 local 函数。不能从外部调用此类函数。
一个函数可能会局部化的原因有几个 linkage:
- 函数在定义它的文件中声明
static
。 - 该函数是全局的,但在编译 (
-fvisibility=hidden
) 或 link 时隐藏(使用 linker 版本脚本)。
修复取决于为什么函数是本地的。对于上面的 1),删除 static
限定符即可。对于 2),您可能需要添加 __attribute__((visibility("default")))
,或者您可能需要编辑 linker 版本脚本。