Dynamic libmergestream.so:未定义符号:XUnlockDisplay

Dynamic libmergestream.so:未定义符号:XUnlockDisplay,dynamic,shared-libraries,Dynamic,Shared Libraries,我环顾四周,尽了最大努力,但我无法解决这个问题: 我正在编译一个应用程序,它将动态加载用户创建的共享对象,例如libmergestream.so mergestream.cpp(libmergestream.so的派生源)包含CImg库调用。我使用-lpthread-lX11-lXext-lXrandr标志编译共享对象 接下来,我将应用程序的第二部分构建为一个可执行文件,并通过链接器标志提供相同的标志和库:-L/usr/lib/x86_64-linux-gnu 运行应用程序时,加载共享对象失败,

我环顾四周,尽了最大努力,但我无法解决这个问题:

我正在编译一个应用程序,它将动态加载用户创建的共享对象,例如libmergestream.so

mergestream.cpp(libmergestream.so的派生源)包含CImg库调用。我使用
-lpthread-lX11-lXext-lXrandr
标志编译共享对象

接下来,我将应用程序的第二部分构建为一个可执行文件,并通过链接器标志提供相同的标志和库:
-L/usr/lib/x86_64-linux-gnu

运行应用程序时,加载共享对象失败,消息如下:

Sun Jun  3 19:35:24 2012[1,6]<stdout>:0x7f46705e4180 ../DALProcesses/lib/libmergestream.so: undefined symbol: XUnlockDisplay
二进制本身有未定义的符号,我仍然可以让它执行

对于CImgExample上的ldd:

linux-vdso.so.1 =>  (0x00007fff988f5000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4f08e61000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f4f08b2d000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4f0882c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4f08532000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4f0831c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4f07f5e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4f090ab000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f4f07d40000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4f07b3c000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f4f07938000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f4f07732000)
为了进行比较,以下是libmergestream.so的nm输出:

nm libmergestream.so | grep 'XUn'
                 U XUngrabKeyboard
                 U XUnlockDisplay
                 U XUnmapWindow
linux-vdso.so.1 =>  (0x00007fff8dfff000)
libmpi.so.1 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa79c69a000)
libmpi_cxx.so.1 => not found
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa79c495000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa79c195000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa79bf7e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa79bbc1000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa79c8e4000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa79b8c7000)
下面是应用程序的ldd(称为“main”),它将动态加载libmergestream.so:

nm libmergestream.so | grep 'XUn'
                 U XUngrabKeyboard
                 U XUnlockDisplay
                 U XUnmapWindow
linux-vdso.so.1 =>  (0x00007fff8dfff000)
libmpi.so.1 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa79c69a000)
libmpi_cxx.so.1 => not found
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa79c495000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa79c195000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa79bf7e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa79bbc1000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa79c8e4000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa79b8c7000)
我注意到“main”中缺少这两个库引用:

libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f4f07938000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f4f07732000)

有趣的是,我在Linux服务器上为共享库和“main”运行相同的构建过程,一切都很顺利。是我的笔记本讨厌什么,我不知道是什么。

你没说,但看起来你在Linux上使用gcc。如果是这样,请尝试将--no undefined标志设置为ld来构建libmergestream.so(如果您是通过编译器驱动程序传递它,请使用-Wl,-no undefined)。这将使libmergestream.so的链接失败,除非链接行上提供了满足其未定义符号所需的所有库。你可能会发现,链接现在失败了,人们抱怨这些符号。现在,您可以将任何必需的库添加到libmergestream.so的库列表中,直到链接成功。这些新的依赖项将添加到库的“必需”集中,并在运行时随库一起加载


除非libmergestream.com中有一些符号,否则这应该可以工作,因此加载可执行文件本身(在这种情况下应使用--export dynamic编译)应该可以满足这些符号。如果是这样的话,您可能无法通过--no undefined找到一个完整的链接,但是您可以使用它来确定仍然需要添加哪些库:当链接失败的唯一符号是可执行文件提供的符号时,您可以删除--no undefined,此时您应该可以。但最好将支持抽象到另一个共享库中,而不是依赖于可执行文件。对于要在运行时加载的库,您应该尽可能使用--no undefined。

您没有说,但看起来您在Linux上使用的是gcc。如果是这样,请尝试将--no undefined标志设置为ld来构建libmergestream.so(如果您是通过编译器驱动程序传递它,请使用-Wl,-no undefined)。这将使libmergestream.so的链接失败,除非链接行上提供了满足其未定义符号所需的所有库。你可能会发现,链接现在失败了,人们抱怨这些符号。现在,您可以将任何必需的库添加到libmergestream.so的库列表中,直到链接成功。这些新的依赖项将添加到库的“必需”集中,并在运行时随库一起加载


除非libmergestream.com中有一些符号,否则这应该可以工作,因此加载可执行文件本身(在这种情况下应使用--export dynamic编译)应该可以满足这些符号。如果是这样的话,您可能无法通过--no undefined找到一个完整的链接,但是您可以使用它来确定仍然需要添加哪些库:当链接失败的唯一符号是可执行文件提供的符号时,您可以删除--no undefined,此时您应该可以。但最好将支持抽象到另一个共享库中,而不是依赖于可执行文件。您应该尽可能对要在运行时加载的库使用--no undefined。

此外,如果您的库中不需要CImg的显示功能,您可以通过放置

#define cimg_display 0

在包含“CImg.h”文件之前。

如果您的库中不需要CImg的显示功能,您可以通过放置

#define cimg_display 0

就在包含“CImg.h”文件之前。

非常感谢您提供的提示。我会试试看,然后拿着我看到的回来。哦,我的天啊!经过半个小时的尝试,这个终于成功了!!我在使用CUDA,NVCC在将CImg链接到X11时遇到问题!谢谢:-)非常感谢你的提示。我会试试看,然后拿着我看到的回来。哦,我的天啊!经过半个小时的尝试,这个终于成功了!!我在使用CUDA,NVCC在将CImg链接到X11时遇到问题!谢谢:-)