初探iptables自动加载模块原理
2012-04-16 17:39
381 查看
iptables使用dlopen加载动态库,每个库中都定义了void _init(void)函数,在使用dlopen加载库的时候系统会调用_init函数, 在_init函数中调用xtables_register_match对模块进行注册。iptables这种动态加载模块的方式很适合做定制开发,所以我就自己摸索了下。 我自己写了一个测试的例子: gcc -O2 -Wall -fPIC -c hello.c gcc -shared -o hello.so hello.o hello.o: In function `_init': hello.c:(.text+0x0): multiple definition of `_init' /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../crti.o:(.init+0x0): first defined here 编译的时候出现了重复定义的错误。这是为什么? _init是共享库用来初始化全局变量和对象的,在库文件中已经定义过了。有什么办法可以使用_init来初始化我们自己的函数呢? 通过查看iptables的模块代码,发现所有的文件都包含#include <xtables.h>头文件,会不会是xtables.h中动了什么手脚? 在hello.c中包含xtables.h头文件,果然编译通过。 #include <stdio.h> #include <xtables.h> int main() { return 0; } void _init(void) { printf("init hello\n"); return ; } gcc -O2 -Wall -o hello -I/home/mogo/2.6.17-x86-old/user/iptables/include -fPIC hello.c [root@rhce lion]# ./hello init hello xtables.h头文件中到底做了什么呢? 我在代码中看到一个宏定义:# define _init __attribute__((constructor)) _INIT,会不会是这个? 于是在hello.c中去掉头文件xtables.h,将该宏定义换进去,果然没问题。 那这个宏定义是什么意思呢? 用__attribute__((constructor))来定义的函数,表示函数是构造函数,在main执行之前被调用;相应的用__attribute__ ((destructor))析构函数,在main退出时执行。 void _init(void)就相当于是__attribute__((constructor)) _INIT(void),其实不管函数名定义成什么都会被执行到。 自动初始化的问题解决了,现在就来看看dlopen是怎么用的。 库模块源码: #include <stdio.h> #include <match.h> #define _init __attribute__((constructor)) _INIT static int hello() { printf("hello called\n"); return 0; } static struct test_match test = { .name = "hello", .match = hello }; void _init(void) { printf("init hello\n"); register_match(&test); return ; } 复制代码 运行后生成libhello.so文件 主程式动态加载so文件并调用模块的函数 #include <stdio.h> #include <match.h> #include <dlfcn.h> int main() { struct test_match *ptr; if (dlopen("./libhello.so", RTLD_NOW) == NULL) { printf("load lib error.\n"); return 0; } ptr = find_match("hello"); if (ptr) { printf("find match:%s\n", ptr->name); ptr->match(); } return 0; } 复制代码 编译成可执行文件运行: [root@rhce netcos]# ./main init hello find match:hello hello called 复制代码 |
相关文章推荐
- 浅谈PSR规范与PHP框架中类的自动加载原理
- Android 之ko模块的自动加载
- Linux如何在系统启动时自动加载模块 .
- 嵌入式 Linux 与linux启动时自动加载模块
- 【Ubuntu】自动加载第三方ko模块
- Linux如何在系统启动时自动加载模块
- (五)带属性值的ng-app指令,实现自定义模块的自动加载
- 嵌入式 Linux 与linux启动时自动加载模块 分类: arm-linux-Ubuntu 2013-07-22 16:30 242人阅读 评论(0) 收藏
- 嵌入式 Linux 与linux启动时自动加载模块
- vsftpd服务自动加载模块和随系统启动的方法
- ubuntu开机自动加载iptables配置
- 深入理解composer的autoload自动加载原理
- 集下拉刷新、自动加载和侧滑菜单的RecyclerView基本实现原理
- CentOS启动时自动加载内核模块
- linux内核中udevd的模块自动加载机制。
- 浏览器加载 CommonJS 模块的原理与实现
- linux内核中udevd的模块自动加载机制
- django自动重新加载模块 源码分析
- seajs+backbone实现单页面应用模块自动加载
- JAVAEE——SpringBoot配置篇:配置文件、YAML语法、文件值注入、加载位置与顺序、自动配置原理