Nmd*_*ery 6 c++ linux codeblocks dynamic-library
重新提出问题(尽管已经解决了):
我在使用dlopen(3)在linux上加载共享对象库时遇到了麻烦.该库是由我构建的库系统的一部分,它们都在运行时由中央可执行文件加载.所有这些都被组织到Code :: Blocks中的单个工作区中,其中每个项目在名为Source的目录中被赋予其自己的文件夹,该目录将随程序一起提供.可执行文件的构建目录是从其自己的源代码向后的两个目录,因此exectuable和Source文件夹位于同一目录中.这些库也构建到与可执行文件相同的目录中,所以我自然会传递库的名称我正试图打开如图所示:
int main(int argc, char** argv) {
void* hLibrary = dlopen("libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
if(hLibrary == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当构建目录与源代码相同时,这一点正在工作,直到我将源代码的目录更改为上述安排.此时的问题是dlerror()返回"无法打开libLibrary.so:没有这样的文件或目录",即使该文件明显存在并且与可执行文件位于同一目录中.然后我尝试传入"/libLibrary.so",因为根据dlopen(3)上的手册页,添加/表示相对目录.这返回了相同的错误.
对此的解决方案是需要"./" - 其中"." 表示可执行文件的工作目录 - 并且需要在Code :: Blocks中将工作目录更改为要构建可执行文件的位置.以下工作完美:
void* hLibrary = dlopen("./libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
Run Code Online (Sandbox Code Playgroud)
这并没有真正显示完整的解决方案,但以下基本上相当于我正在做的事情:
void* hLibrary = dlopen("./../../libLibrary.so", RTLD_NOW | RTLD_GLOBAL);
Run Code Online (Sandbox Code Playgroud)
希望这能更好地解释情况.
Bas*_*tch 14
阅读dlopen(3)手册页(例如,man dlopen在您的机器上输入一个终端):
如果filename包含斜杠("/"),则将其解释为(相对或绝对)路径名.否则,动态链接器将按如下方式搜索库(有关详细信息,请参阅ld.so(8)):
o (ELF only) If the executable file for the calling program
contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag,
then the directories listed in the DT_RPATH tag are searched.
o If, at the time that the program was started, the environment
variable LD_LIBRARY_PATH was defined to contain a colon-separated
list of directories, then these are searched. (As a security
measure this variable is ignored for set-user-ID and set-group-ID
programs.)
o (ELF only) If the executable file for the calling program
contains a DT_RUNPATH tag, then the directories listed in that
tag are searched.
o The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is
checked to see whether it contains an entry for filename.
o The directories /lib and /usr/lib are searched (in that order).
Run Code Online (Sandbox Code Playgroud)
所以你需要调用dlopen("./libLibraryName.so", RTLD_NOW)- 不仅仅是dlopen("libLibraryName.so", RTLD_NOW)哪个想要你的插件在你$LD_LIBRARY_PATH的/usr/lib/等等.... - 或添加.到你的LD_LIBRARY_PATH(我不建议出于安全原因).
正如Jhonnash所回答的那样,你应该使用并显示dlerror何时dlopen(或dlsym)失败的结果:
void* dlh = dlopen("./libLibraryName.so", RTLD_NOW);
if (!dlh)
{ fprintf(stderr, "dlopen failed: %s\n", dlerror());
exit(EXIT_FAILURE); };
Run Code Online (Sandbox Code Playgroud)
您可能希望阅读一些书籍,如高级Linux编程,以获得有关Linux系统编程的一般知识.