我已经浏览了下面的链接,通过它我了解了如何创建和使用共享库。 https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
Step 1: Compiling with Position Independent Code
$ gcc -c -Wall -Werror -fpic foo.c
Step 2: Creating a shared library from an object file
$ gcc -shared -o libfoo.so foo.o
Step 3: Linking with a shared library
$ gcc -L/home/username/foo -Wall -o test main.c -lfoo
Step 4: Making the library available at runtime
$ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
$ ./test
This is a shared library test...
Hello, I am a shared library
但是,我有几个问题:
动态库
当我们将应用程序链接到共享库时,链接器会留下一些存根(未解析的符号),以便在应用程序加载时填充。这些存根需要在运行时或应用程序加载时由称为动态链接器的工具填充。
共享库的加载有两种类型,
这里有一个程序与共享库链接,内核在执行时加载该库(如果它不在内存中)。 这在提到的链接中进行了解释。
对于创建“插件”架构很有用。 顾名思义,动态加载是指按需加载库并在执行期间链接。 程序通过调用库函数来完全控制。 这是使用 dlopen()、dlsym()、dlclose() 完成的。 dlopen() 函数打开一个库并准备使用。 通过此系统调用,可以打开共享库并使用其中的函数,而无需与其链接。你的程序刚刚启动,当它发现需要使用特定库中的函数时,它会调用 dlopen() 打开该库。如果该库在系统上不可用,则该函数将返回 NULL,并且由您(程序员)来处理。你可以让程序优雅地死掉。
深度学习示例: 此示例加载数学库并打印 2.0 的余弦,并在每一步检查错误(推荐):
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
}
编译 DL 源代码时使用 -rdynamic。
例如。 gcc -rdynamic -o progdl progdl.c -ldl