共享库和.h文件(Shared libraries and .h files)

2019-06-26 16:22发布

我对如何做程序使用共享库的一些疑问。

当我建立一个共享库(具有-shared -fPIC开关)我使可从一个外部程序的一些功能。 通常我做的dlopen()来加载库,然后对dlsym(),以上述的功能链接到一些函数指针。 这种方法不涉及包括任何.h文件中。 有没有办法避免这样做的dlopen()的dlsym(),只是包括共享库的.H?

这可能是C ++程序如何使用存储在系统中的共享库代码。 即只包括文件stdlib.h等。

Answer 1:

尼克,我认为所有的其他的答案实际上是回答你的问题,这是你如何链接库,但你那句你的问题的方式暗示你有头文件和库之间的差异的误解。 他们不一样。 你需要,和他们没有做同样的事情。

生成可执行具有两个主要阶段,编译(其将您的源成中间形式,包含可执行二进制指令,但并不是一个可运行程序),和连接(结合了这些中间文件转换成单个运行可执行文件或库)。

当你这样做gcc -c program.c ,你是编译和你产生program.o 。 这一步是在那里无所谓。 你需要#include <stdlib.h>program.c到(例如)使用mallocfree 。 (同样,你需要#include <dlfcn.h>dlopendlsym )。如果你不这样做,编译器会抱怨它不知道这些名称,并以一个错误终止。 但是,如果你#include头中的编译器不会插入用于调用到函数的代码program.o 。 它只是向其中插入一个参考 。 原因是为了避免重复代码:代码只会需要通过你的程序的每一个部分访问一次,因此,如果您需要进一步的文件( module1.cmodule2.c等),即使他们使用malloc你只会与以单拷贝多次提到最终malloc 。 这单拷贝存在于标准或者它的共享或静态的形式( libc.solibc.a )但这些都不是在源引用,编译器不知道他们。

该连接头 。 在链接阶段你做gcc -o program program.o 。 然后,链接器将搜索你通过它的命令行上的所有库,并找到你叫未在自己的代码中定义的所有功能的统一的定义。 这是什么-l做(因为其他人解释):告诉链接你需要使用库列表。 他们的名字往往很少与你在上一步中使用的头。 例如,要获得使用dlsym需要libdl.solibdl.a ,所以你的命令行会gcc -o program program.o -ldl 。 要使用malloc或大部分功能std*.h头你需要libc ,但由于该库是由每一个 C程序即自动与使用(因为如果你做了-lc )。

很抱歉,如果我进入了很多细节,但如果你不知道其中的差别,你会想。 这是很难做的,如果你没有C语言编译如何工作的意义。

最后一两件事: dlopendlsym不连接的正常方法。 它们用于要动态地确定要基于也就是说,不管出于什么原因,只在运行时可用信息的行为有什么特殊情况。 如果你知道你要在编译时调用什么功能(真正的情况占99%),则不需要使用dl*功能。



Answer 2:

您可以链接共享库像静态的。 然后,他们被搜索启动程序时。 作为事实上,在默认情况下-lXXX会喜欢libXXX.so到libXXX.a。



Answer 3:

你需要给链接器的正确指示链接共享库。

共享库的名称是像libNAME.so,因此对于连接你应该使用-lname

libmysharedlib.so调用它,然后链接你的主要程序为:

gcc -o myprogram myprogram.c -lmysharedlib 


Answer 4:

如果您使用的CMake来构建你的项目,你可以使用

TARGET_LINK_LIBRARIES(targetname libraryname)

如:

TARGET_LINK_LIBRARIES(myprogram mylibrary)

要创建库“在MyLibrary”,你可以使用

ADD_LIBRARY(targetname sourceslist)

如:

ADD_LIBRARY(mylibrary ${mylibrary_SRCS})

此外,此方法是跨平台的(而简单地通过标志与gcc不是)。



文章来源: Shared libraries and .h files