C语言插件开发模式

           我也找不到合适的列子。我直接上代码吧。通过输入不同的so或者dll执行不同的内容。本文件以Unix/Linux中的C语言代码为例子。使用到的知识很简单。就是dlopen和dlsym函数。所有的函数都在dlfcn.h头文件中。

          

  1. void * dlopen( const char * pathname, int mode);  
  2.   
  3. pathname:so或者dll文件的路径,在Linux中必须是以"./"或者"../"开始的相对路径 或者 以"/"开始的绝对路径  
  4. mode:解析so或者dll文件的方式,可以取以下值 <div class="para">RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用总是立即解析)。</div><div class="para">RTLD_NOW: 需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL  
  5.   
  6. <div class="para">打开错误返回NULL</div><div class="para">成功,返回库引用</div>.</div>  
  1.  dlsym(void *dp, char * funtionname);  
  2. dp:已经打开的so或者dll文件句柄  
  3. functionname:要解析的文件名字  
  4.   
  5. 数返回值是void*,指向函数的地址  
  1. dlclose(void *dp)  
  2. 关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。  

主函数

  1. #include <stdio.h>  
  2. #include <dlfcn.h>  
  3. #include "dll.h"  
  4.   
  5. int main(){  
  6.     void *dp;  
  7.     char *err;  
  8.     char fname[20];  
  9.     dll p;  
  10.     void (*init)(dll *p);  
  11.     pirntf("请输入要加载模块的名字:model1 或者model2");  
  12.     scanf("%s", fname);  
  13.     sprintf("./%s^, fname);  
  14.     dp = dlopen(fname, RTLD_LAZY);//打开动态库。  
  15.     if( NULL == dp) {  
  16.         printf("%s\n", dlerror());  
  17.         exit(1);  
  18.     }  
  19.     init = dlsym(dp, "init");//找到init函数的地址。  
  20.     init(&p);  
  21.     printf("%s\n", p.name);  
p.done();//注意这里done虽然是so中函数。却没有使用使用dlsym找done函数的地址。 err = dlerror(); dlclose(dp);}model1.c
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include "dll.h"  
  5.   
  6. void done(){  
  7.     printf("This is test module 1!\n");  
  8. }  
  9.   
  10. void init(dll *p){  
  11.     p->name = (char *)calloc(3, sizeof(char));  
  12.     strcpy(p->name, "so1");  
  13.     p->done = done;  
  14. }  

model1.c

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include "dll.h"  
  5.   
  6. void done(){  
  7.     printf("This is test module 2!\n");  
  8. }  
  9.   
  10. void init(dll *p){  
  11.     p->name = (char *)calloc(3, sizeof(char));  
  12.     strcpy(p->name, "so2");  
  13.     p->done = done;  
  14. }  


dll.h 头文件

  1. typedef struct dll{  
  2.     char * name;  
  3.     void (*done)() ;  
  4. }dll;  

以下为gcc的编译过程
  1. gcc -rdynamic -o test  test.c dll.h -ldl  //-ldl (指定dl库)因为dlopen和dlsym在dl库中  
  2. gcc -shared -o module1.so  module1.c dll.h  
  3. gcc -shared -o $module2.so module2.c dll.h  

将会根据输入的不同显调用不同的dll中的函数。
.

blog: http://blog.csdn.net/rentiansheng/article/details//8606125

转载于:https://my.oschina.net/rentiansheng/blog/110033

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值