QLibrary::load 失败,但 LD_LIBRARY_PATH 在此之前刚刚正确更新,为什么?
QLibrary::load fails, but LD_LIBRARY_PATH just updated correctly before that, why?
我有一个依赖于外部应用程序(即 Matlab)的库(我们称之为 mydll.so)。为了动态加载mydll.so
,我写了这样一段代码(Ubuntu, g++ 4.8.5, qt 5.12.6):
// update LD_LIBRARY_PATH with ALL required paths (Matlab, boost, etc.)
bool res = qputenv("LD_LIBRARY_PATH", required_path.toStdString().c_str());
assert(res);
// loading the dll
QLibrary my_dll;
my_dll.setFileName(dll_path);
if (!my_dll.load())
{
std::cout << my_dll.errorString().toStdString() << std::endl;
}
以上代码失败并显示此消息:
Cannot load library /home/user/code/test/lnx_x64/debug/mydll.so: (libMatlabDataArray.so: cannot open shared object file: No such file or directory)
这很奇怪,因为 load()
函数抱怨来自 Matlab 的库,即 libMatlabDataArray.so
它的路径已经包含在 LD_LIBRARY_PATH 中。但是,如果我 运行 ldd
在相同的环境中,我有:
user@everest:~/code$ ldd /home/user/code/test/lnx_x64/debug/mydll.so
linux-vdso.so.1 (0x00007ffcb4da2000)
libMatlabDataArray.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabDataArray.so (0x00007f6af95f2000)
libMatlabEngine.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabEngine.so (0x00007f6af93e7000)
也就是说libMatlabDataArray.so
可以通过ldd
命令找到,LD_LIBRARY_PATH
的内容是正确的。那么在我的案例中,这个问题背后的原因是什么?
更新 1: 如果我在应用程序启动前设置 LD_LIBRARY_PATH,一切正常。在启动应用程序之前和在应用程序内部设置 LD_LIBRAARY_PATH 有什么区别?
问题是您从进程中更改了环境变量 LD_LIBRARY_PATH
。但是,该过程仍然使用具有旧值的“旧”环境变量块。结果它无法正确找到依赖库并最终失败。
因此,您的方法将行不通。我会提出以下解决方案:
- 在启动进程之前设置
LD_LIBRARY_PATH
变量,以便进程可以考虑更新的块,
- 尝试使用
QCoreApplication::setLibraryPaths()
函数设置库搜索路径。
我有一个依赖于外部应用程序(即 Matlab)的库(我们称之为 mydll.so)。为了动态加载mydll.so
,我写了这样一段代码(Ubuntu, g++ 4.8.5, qt 5.12.6):
// update LD_LIBRARY_PATH with ALL required paths (Matlab, boost, etc.)
bool res = qputenv("LD_LIBRARY_PATH", required_path.toStdString().c_str());
assert(res);
// loading the dll
QLibrary my_dll;
my_dll.setFileName(dll_path);
if (!my_dll.load())
{
std::cout << my_dll.errorString().toStdString() << std::endl;
}
以上代码失败并显示此消息:
Cannot load library /home/user/code/test/lnx_x64/debug/mydll.so: (libMatlabDataArray.so: cannot open shared object file: No such file or directory)
这很奇怪,因为 load()
函数抱怨来自 Matlab 的库,即 libMatlabDataArray.so
它的路径已经包含在 LD_LIBRARY_PATH 中。但是,如果我 运行 ldd
在相同的环境中,我有:
user@everest:~/code$ ldd /home/user/code/test/lnx_x64/debug/mydll.so
linux-vdso.so.1 (0x00007ffcb4da2000)
libMatlabDataArray.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabDataArray.so (0x00007f6af95f2000)
libMatlabEngine.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabEngine.so (0x00007f6af93e7000)
也就是说libMatlabDataArray.so
可以通过ldd
命令找到,LD_LIBRARY_PATH
的内容是正确的。那么在我的案例中,这个问题背后的原因是什么?
更新 1: 如果我在应用程序启动前设置 LD_LIBRARY_PATH,一切正常。在启动应用程序之前和在应用程序内部设置 LD_LIBRAARY_PATH 有什么区别?
问题是您从进程中更改了环境变量 LD_LIBRARY_PATH
。但是,该过程仍然使用具有旧值的“旧”环境变量块。结果它无法正确找到依赖库并最终失败。
因此,您的方法将行不通。我会提出以下解决方案:
- 在启动进程之前设置
LD_LIBRARY_PATH
变量,以便进程可以考虑更新的块, - 尝试使用
QCoreApplication::setLibraryPaths()
函数设置库搜索路径。