Skip to content

C语言

根据结构体成员取结构体首地址

member_address - &(((TYPE *)0)->member);

后半部分看似会解引用0地址而crash,但编译器会优化为直接计算member的offset。参见kernel代码常用的container_of。

动态链接库

编译动态链接库本身

使用gcc编译出动态链接库:

gcc <source C file> -shared -fPIC -o lib<source>.so

编译原项目时指定动态链接库

使用-l指定加载链接库,注意去掉库文件的lib开头和.so结尾。编译时,注意把库放在整个命令的结尾,否则可能提示库函数未定义。

比如gcc main.c -lcapstone不会报错,gcc -lcapstone main.c会提示报错。(假设这里main.c调用了capstone的库函数)

如果动态链接库不在默认的系统库中,可以添加-L来指定动态链接库的保存位置。

运行项目时加载动态链接库

即便编译成功,运行可能报错。搜索顺序为:

  1. 在编译时添加-Wl,-rpath=xxx来指定运行时所需的动态库文件
  2. 在环境变量LD_LIBRARY_PATH指定的目录中搜索
  3. /etc/ld.so.conf给出的目录中搜索
  4. 在默认的搜索路径/lib/lib64/usrlib/usrlib64等搜索