`
sealbird
  • 浏览: 570942 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

C语言插件机制(上)

阅读更多
http://abruzzi.iteye.com/blog/739673

2010-08-17
C语言插件机制(上)
文章分类:C++编程
前言
插件机制可以使得应用程序在发布之后,在不经过重新编译的情况下修改应用程序的行为,这种形式使得应用的框架比较小巧,也可以给用户一些自由(不是完全的自由,有一定的限制)。Java中,使用*.jar或者其他的脚本引擎都可以完成这样的工作,如Eclipse那样。在C语言中,当然可以使用脚本引擎来实现,比如emacs,内置一个lisp的引擎,用户可以自己为emacs写脚本,访问emacs环境的一些组件,从而定制emacs.这里要讨论的无需使用脚本引擎,而是用C语言访问动态链接库来实现。

Linux下的动态库
Linux环境中,与windows下一样,函数库有两种方式:静态库和动态库,静态库参与连接,由于要将目标代码.o与lib中的函数符号合并在一起,所以最终生成的可执行文件较大。一般以.a结尾。如libxxx.a。而动态库(共享库)则不参与编译,只是在运行时才加载如内存,且仅加载一次,因此最终的可执行文件较小。事实上,当一个可执行文件需要运行动态库中的函数时,系统会在内存中查找,如果已经加载,则直接调用,否则才做一次加载,动态库的结尾一般为.so,如libxxx.so。



Linux为动态库的访问提供了4个API,分别为dlopen , dlerror , dlsym 和 dlclose。这些API的原型定义在文件dlfcn.h中,其实现则分别对应有两个库文件(静态库 libdl.a 和动态库 libdl.so)。




dlopen加载动态库,并返回句柄
dlerror如果加载,访问符号出错,可以通过此接口获得详细的描述
dlsym返回一个动态库中的符号,即通过函数名获得此函数的指针
dlclose完成之后,释放dlopen返回的句柄
动态库的使用较为简单,比如动态库的名称为plugina.so,其中包含这样的函数原型:


C代码
int func(int a, int b);  
int func(int a, int b
);
可以看下一个例子:


C代码
 include <dlfcn.h>      
//句柄   
void *flib;   
  
//入口函数原型   
int (*pfunc)(int a, int b);   
  
//错误信息字符串   
char *error_message;   
  
int plugin_test(){   
    int a = 1, b = 4;   
    int result = 0;   
       
    //加载plugina.so,以RTLD_LAZY方式   
    flib = dlopen("/home/juntao/.libs/plugina.so", RTLD_LAZY);   
    error_message = dlerror();   
       
    if(error_message){   
        return (-1);   
    }   
       
    //找到函数名为func的函数,返回其指针   
    *(void **)(&pfunc) = dlsym(flib, "func");   
    error_message = dlerror();   
    if(error_message){   
        return (-1);   
    }   
       
    //调用pfunc指向的指针,及func函数   
    result = pfunc(a, b);   
       
    //释放   
    int code = dlclose(flib);   
    error_message = dlerror();   
  
    if(error_message){   
        return (-1);   
    }   
       
    return 0;   
}  

#include <dlfcn.h>

//句柄
void *flib;

//入口函数原型
int (*pfunc)(int a, int b);

//错误信息字符串
char *error_message;

int plugin_test(){
	int a = 1, b = 4;
	int result = 0;
	
	//加载plugina.so,以RTLD_LAZY方式
	flib = dlopen("/home/juntao/.libs/plugina.so", RTLD_LAZY);
	error_message = dlerror();
	
	if(error_message){
		return (-1);
	}
	
	//找到函数名为func的函数,返回其指针
	*(void **)(&pfunc) = dlsym(flib, "func");
	error_message = dlerror();
	if(error_message){
		return (-1);
	}
	
	//调用pfunc指向的指针,及func函数
	result = pfunc(a, b);
	
	//释放
	int code = dlclose(flib);
	error_message = dlerror();

	if(error_message){
		return (-1);
	}
	
	return 0;
} 
编译运行
假设plugina.so的源文件为plugina.c,内容为:


C代码
//file plugina.c   
  
int func(int a, int b){   
    int c = 0;   
    c = 3*a + 4*b + 6;   
       
    return c;   
}  

//file plugina.c

int func(int a, int b){
	int c = 0;
	c = 3*a + 4*b + 6;
	
	return c;
}


我们将这个.c文件编译为.so,命令如下:




//生成plugina.o
$gcc -c -fpic plugina.c

//生成plugina.so
$gcc -shared -lc -o plugina.so plugina.o



将动态库访问部分的代码存为plugintest.c,然后使用下列命令编译:




C代码
$gcc -o plugintest plugintest.c -ldl  

$gcc -o plugintest plugintest.c -ldl 


-ldl意思是,使用库libdl.so,linux下访问搜索路径内的库文件无需加lib前缀。



将生成的plugina.so放入路径/home/juntao/.libs/,然后运行plugintest。





$./plugintest

result = 25



好了,这一次先介绍一些基础知识,相信在此基础上,很多朋友都可以自己设计出一些简单实用的支持“插件”的应用来了,我们下一次详细讨论一个更实际一些的例子,一个计算器的实现,这个计算器只有简单的框剪,所有的运算都通过插件来实现。用户可以通过配置文件来定制插件的路径,入口等信息。

分享到:
评论

相关推荐

    C语言插件机制(下) 转

    NULL 博文链接:https://sealbird.iteye.com/blog/756577

    c语言华容道源码.rar

    它包含了完整的游戏逻辑和界面设计,可以帮助我们深入理解华容道的运行机制,以及如何在计算机程序中实现这种机制。这份资料包的内容丰富,包括了华容道游戏的初始化、方块的移动、判断游戏是否胜利等核心功能。同时...

    c语言图书借阅系统源码.rar

    同时,该系统可能还包括了错误处理机制,让用户能够更好地理解如何确保程序的健壮性和稳定性。对于正在学习C语言编程的学生来说,通过分析和运行这个图书借阅系统的源码,可以加深对C语言语法的理解,提升编程技巧,...

    c语言学生成绩管理系统源码 + 运行程序

    此外,系统还考虑到了数据的安全性和完整性,通过适当的错误处理和验证机制,确保了数据的准确性和可靠性。 值得一提的是,这套C语言学生成绩管理系统源码资源不仅具有高度的实用性,还具备很强的可扩展性和可定制...

    课程作业-基于epoll机制的高并发聊天室,c语言实现+源代码+文档说明

    基于epoll机制的高并发聊天室,c语言实现 - 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! 1、该资源内...

    c语言 条形码识别实例代码

    以下是对C语言条形码识别的描述,不包含具体的代码实现: 图像处理:条形码识别首先需要对输入的图像进行预处理。这包括图像的二值化、去噪和增强等操作,以提高条形码的边缘清晰度和对比度。 条形码定位:在...

    C语言实现基于Risc-V 的操作系统内核模拟设计与实现源代码,一个运行在RISC-V架构处理器上的玩具嵌入式操作系统

    C语言实现基于Risc-V 的操作系统内核模拟设计与实现源代码,一个运行在RISC-V架构处理器上的玩具嵌入式操作系统 完成了操作系统的引导、UART 串口驱动、中断管理、动态内存管理、多任务调度、自旋锁、信号量、FAT32...

    c语言-球球大作战软件

    吞噬成长机制:通过吞噬地图中的小颗粒使球球不断变大,以达成更高分数。 ai小球设置:地图内设有多个ai小球,它们可以根据自身的大小和与玩家的距离来选择追击玩家或者逃跑,增加游戏的趣味性。 积分系统:设立...

    c语言种地要浇水游戏源码

    4. **游戏机制与玩法**: - 玩家需要定时给作物浇水,保持土壤湿润度。 - 可能包含升级系统,如改进灌溉设备以提高浇水效率。 - 游戏内可能设有任务系统,完成任务获得奖励或解锁新作物。 - 可能存在经济系统,...

    c语言自创推箱子游戏改版源码

    游戏保留了经典推箱子游戏的核心玩法,即推动箱子到指定位置,但在此基础上加入了众多创新元素和机制,使得游戏更加丰富和有趣。 二、核心玩法与特色 多样化的关卡设计:每个关卡都有独特的布局和难度,需要玩家运用...

    基于C语言实现的坦克游戏源代码.zip

    设计敌方坦克生成和控制机制,包括生成位置、难度递增等。 实现碰撞检测,包括坦克与子弹、坦克与障碍物等的碰撞判断。 关卡设计: 设计关卡地图,包括障碍物的位置、敌方坦克的生成等。 设计关卡目标和胜利条件,...

    ASP基于Web的C语言教学系统的研究与实现.zip

    其特点包括清晰的代码结构、高效的数据库访问、安全的用户认证和授权机制、响应式布局以适应不同设备、友好的用户界面等。这些项目源码还提供了丰富的功能模块和插件,支持用户管理、权限控制、数据可视化、电子支付...

    C语言嵌入式Linux编程第3期:程序的编译、链接和运行

    本课程为《C语言嵌入式Linux编程》第3期,主要对程序的编译、链接及运行机制进行分析。同时对静态库链接、动态链接的过程、插件原理、内核模块运行机进行探讨,后对嵌入式系统比较难理解的u-boot重定位、u-boot加载...

    摘录自FastDFS的高性能网络通信框架 .rar

    FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。 FastDFS架构  FastDFS架构...

    java基础学习笔记 java整合技术 java工具类.rar

    健壮性:java的健壮性与自动垃圾回收机制有关,自动垃圾回收机制简称GC机制,java语言运行过程中产生的垃圾是自动回收的,不需要程序员关心。 可移植性:java程序可以做到一次编译,到处运行。在Windows操作系统上...

    Lua 入门教程

    Lua 教程 lua Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用...扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统

    Ceedling:基于RubyRake的C项目构建和测试系统

    Ceedling还可以通过方便的插件机制进行扩展。 使用说明文件 文档和许可证信息存在 入门 首先,请确保Ruby已安装在您的系统上(如果尚未安装)。 然后,在命令提示符下: &gt; gem install ceedling (为打算成为开发...

    Tcl_TK编程权威指南pdf

    我一直使自己在很大程度上保持着一个Tcl程序员的角色,而我们工作组中的其他人员则埋头于Tcl本身的C语言实现。我创建的应用程序有HTML编辑器、EMAIL比用户接口程序、Web服务器以及用户数据库,我们的商务应用就建立...

    UML State Machine Wizard VC Addin 7.0

    UML StateWizard for VS.NET/VC6/EVC4可为嵌入式系统或Win32/WinCE开发带来可视化、基于可移植C语言的UML状态机编程机制。同时,作为Visual C++的插件,它使得开发者可以在强大的Visual C++开发环境中进行嵌入式系统...

    计算机毕业设计 - ARM实验,保证可靠运行,计算机毕业生可参考,免费资源下载

    通过实验,我们深入了解了ARM处理器的内部结构和运行机制,掌握了ARM汇编语言编程和C语言混合编程的技巧。同时,我们还学会了如何配置和使用ARM处理器的各种功能和外设接口,为后续的嵌入式系统开发打下了坚实的基础...

Global site tag (gtag.js) - Google Analytics