只有在代码使用时才能拥有动态库吗?

时间:2015-01-20 17:37:41

标签: linux ld

我有一个可以与某些外部库链接的大型程序,但这些只是某些特定功能所需要的。但是,即使我不使用这些功能,仍然需要外部库。我可以做一些事情(最好是在编译或链接时),以便只有在请求它们提供的功能时才需要库吗?

示例:

的hello.c

#include <stdio.h>
#include <unistd.h>
extern const char *myfunc();

main() {
  int z;
  char buf[32];
  z = gethostname(buf,sizeof buf);
  if (strcmp(buf,"#!#!#!#!#") == 0) {
    printf("%s\n", myfunc());
  } else {
    printf("%s\n", "No library used");
  }
  return 0;
}

shrobj.c:

const char *myfunc() {
  return "Hello World";
}

编译为:

$ gcc -fpic -c shrobj.c
$ gcc -shared -o libshared.so shrobj.o
$ gcc hello.c -lshared -L.
$ ./a.out 
./a.out: error while loading shared libraries: libshared.so: cannot open shared object file: No such file or directory

我的主机名显然不是#!#!#!#!#

$ LD_LIBRARY_PATH=. ./a.out 
No library used

所以,我想要的是能够在没有库(无论出于何种原因可能不可用)的情况下运行“./a.out”,只要它的函数不被调用。

我已经看到使用dlopen()可以获得延迟加载但是,即使上面的示例是在C中,我的大部分代码都在fortran中,特别是可能调用函数的部分库。

1 个答案:

答案 0 :(得分:0)

Linux可以通过其内核API实现这一点;具体来说,dlopen(3)功能。如果您需要详细信息,请使用man查找。

基本上,您使用要加载的库的名称调用dlopen,并返回库的句柄,您需要将其保存以供日后使用。

void* lib = dlopen("./lib.so"); // this can be any path

要从此库中加载函数,可以使用dlsym函数,并将其返回值分配给函数指针,然后可以像程序中的任何其他函数一样调用(主要是)。 / p>

int (*func)() = dlsym(lib, "thing");

完成后,您需要告诉内核您已完成库:

dlclose(lib)

为简洁起见,我在此省略了错误检查,但您需要在实际代码中执行此操作。

这样做意味着除非需要,否则程序不会尝试加载库,因此如果未安装或缺少所需的库或依赖项,则代码可以检测到并使用其他内容。你的程序 - 只要写得正确 - 在启动时不会崩溃,但如果你依赖库很多而且找不到它,你可能不得不退出错误。