qua*_*ark 49
尼克,我认为所有其他答案实际上都在回答你的问题,这就是你如何链接库,但你说出问题的方式表明你误解了头文件和库之间的区别.他们不一样.你需要两者,他们没有做同样的事情.
构建可执行文件有两个主要阶段,编译(将源转换为中间形式,包含可执行二进制指令,但不是可运行程序)和链接(将这些中间文件组合成单个运行的可执行文件或库).
当你这样做时gcc -c program.c,你正在编译,然后你就会生成program.o.这一步是标题很重要的地方.您需要#include <stdlib.h>在program.c到(例如)使用malloc和free.(同样,你需要#include <dlfcn.h>为dlopen和dlsym).如果你不这样做,编译器会抱怨它不知道这些名称,并以一个错误终止.但是,如果你#include的头编译器不会插入用于调用到函数的代码program.o.它只是插入一个引用.原因是为了避免重复代码:代码只会需要通过你的程序的每一个部分访问一次,因此,如果您需要进一步的文件(module1.c,module2.c等),即使它们都使用malloc你只会落得有许多引用单个副本malloc.该单个副本以共享或静态形式(或)存在于标准库中,但这些副本未在源中引用,并且编译器不知道它们.libc.solibc.a
链接器是.在连接阶段,你做gcc -o program program.o.然后,链接器将在命令行中搜索您传递的所有库,并找到您调用的所有函数的单一定义,这些函数未在您自己的代码中定义.这就是-l它(正如其他人所解释的那样):告诉链接器你需要使用的库列表.它们的名称通常与您在上一步中使用的标题几乎没有关系.例如,要获得使用的dlsym需要libdl.so或者libdl.a,让您的命令行会gcc -o program program.o -ldl.要malloc在所需的std*.h标题中使用或大多数函数libc,但由于每个 C程序都使用该库,它会自动链接(就像你已经完成的那样-lc).
对不起,如果我进入很多细节,但如果你不知道你想要的差异.如果不这样做,很难理解C编译的工作原理.
最后一两件事:dlopen和dlsym不连接的正常方法.它们用于特殊情况,您希望根据无论何种原因仅在运行时可用的信息动态确定所需的行为.如果您知道在编译时要调用哪些函数(99%的情况都是如此),则不需要使用这些dl*函数.