- 浏览: 570924 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (365)
- Tomcat调优 (2)
- Apache Http (20)
- Webserver安装 (5)
- Linux安装 (28)
- Linux常用命令 (17)
- C语言及网络编程 (10)
- 文件系统 (0)
- Lucene (12)
- Hadoop (9)
- FastDFS (8)
- 报表 (0)
- 性能测试 (1)
- JAVA (18)
- CSharp (3)
- C++ (38)
- BI (0)
- 数据挖掘 (0)
- 数据采集 (0)
- 网址收集整理 (3)
- Resin (0)
- JBoss (0)
- nginx (0)
- 数据结构 (1)
- 随记 (5)
- Katta (1)
- Shell (6)
- webservice (0)
- JBPM (2)
- JQuery (6)
- Flex (41)
- SSH (0)
- javascript (7)
- php (13)
- 数据库 (6)
- 搜索引擎排序 (2)
- LVS (3)
- solr (2)
- windows (1)
- mysql (3)
- 营销软件 (1)
- tfs (1)
- memcache (5)
- 分布式搜索 (3)
- 关注的博客 (1)
- Android (2)
- clucene (11)
- 综合 (1)
- c c++ 多线程 (6)
- Linux (1)
- 注册码 (1)
- 文件类型转换 (3)
- Linux 与 asp.net (2)
- perl (5)
- coreseek (1)
- 阅读器 (2)
- SEO (1)
- 励志 (1)
- 在线性能测试工具 (1)
- yii (7)
- 服务器监控 (1)
- 广告 (1)
- 代理服务 (5)
- zookeeper (8)
- 广告联盟 (0)
- 常用软件下载 (1)
- 架设自已的站点心得 (0)
最新评论
-
terry07:
java 7 用这个就可以了 Desktop desktop ...
关于java Runtime.getRunTime.exec(String command)的使用 -
HSINKING:
怎么设置打开的dos 窗口是指定的路径下
关于java调用bat文件,不打开窗口 -
liubang201010:
hyperic hq更多参考资料,请访问:http://www ...
hyperic-hq -
^=^:
STDIN_FILENO是unistd.h中定义的一个numb ...
深入理解dup和dup2的用法 -
antor:
留个记号,学习了
[转]用java流方式判断文件类型
[img][/img]http://www.iteye.com/topic/747159
前言
上一篇文章简单介绍了*NIX下的动态库的使用,我们在这篇文章中实现一个计算器,计算器程序calc本身不做运算,只是将操作数传递给具体的插件(adder, suber, muler, diver)来完成实际运算。首先,计算器根据插件配置文件plugin.xml来确定插件的位置,名称,入口符号的定义,然后依次调用各个插件完成计算。
插件列表
文中涉及到的插件定义在plugin.xml中,文档结构如下:
Xml代码
每个插件为一个plugin标签,plugin标签中包含library, entry两个字标签,分别定义动态库文件的路径及名称和插件函数的入口。为了简便,我们不重复设计list及xml解析,这里使用libxml2作为xml的分析器,GLIB中的GSList(单链表)来作为插件列表的链表对象。
每一个插件在C语言中的定义如下,非常简单(plugin.h)
C代码
这里为了行文方便,Plugin结构中的字符串为静态尺寸。
计算器
计算器调用parseconf模块中的load_plugins将plugin.xml中定义的Plugin加载进一个GSList,以备后用:
C代码
插件中的函数原型应该符合接口定义:
C代码
计算器的主要代码如下:
C代码
首先,定义一个GSList,然后将其传递给load_plugins,load_plugins解析plugin.xml,然后填充list返回,calc_test遍历插件列表,并调用每一个插件定义的entry.
除法器
我们来看一个具体的插件:做除法的模块
C代码
运行结果如下图所示:
其他代码如xml的解析,GSList的使用等与插件机制关系不大,感兴趣的朋友可以在附件中查看。
前言
上一篇文章简单介绍了*NIX下的动态库的使用,我们在这篇文章中实现一个计算器,计算器程序calc本身不做运算,只是将操作数传递给具体的插件(adder, suber, muler, diver)来完成实际运算。首先,计算器根据插件配置文件plugin.xml来确定插件的位置,名称,入口符号的定义,然后依次调用各个插件完成计算。
插件列表
文中涉及到的插件定义在plugin.xml中,文档结构如下:
Xml代码
<plugins> <plugin name="adder"> <library path="/home/juntao/.libs/adder.so"> </library> <entry name="add"> </entry> </plugin> <plugin name="suber"> <library path="/home/juntao/.libs/suber.so"> </library> <entry name="sub"> </entry> </plugin> <plugin name="muler"> <library path="/home/juntao/.libs/muler.so"> </library> <entry name="mul"> </entry> </plugin> <plugin name="diver"> <library path="/home/juntao/.libs/diver.so"> </library> <entry name="div"> </entry> </plugin> </plugins> <plugins> <plugin name="adder"> <library path="/home/juntao/.libs/adder.so"> </library> <entry name="add"> </entry> </plugin> <plugin name="suber"> <library path="/home/juntao/.libs/suber.so"> </library> <entry name="sub"> </entry> </plugin> <plugin name="muler"> <library path="/home/juntao/.libs/muler.so"> </library> <entry name="mul"> </entry> </plugin> <plugin name="diver"> <library path="/home/juntao/.libs/diver.so"> </library> <entry name="div"> </entry> </plugin> </plugins>
每个插件为一个plugin标签,plugin标签中包含library, entry两个字标签,分别定义动态库文件的路径及名称和插件函数的入口。为了简便,我们不重复设计list及xml解析,这里使用libxml2作为xml的分析器,GLIB中的GSList(单链表)来作为插件列表的链表对象。
每一个插件在C语言中的定义如下,非常简单(plugin.h)
C代码
#ifndef _PLUGIN_H_ #define _PLUGIN_H_ typedef struct{ char name[64]; char path[256]; char entry[128]; int version; }Plugin; #endif #ifndef _PLUGIN_H_ #define _PLUGIN_H_ typedef struct{ char name[64]; char path[256]; char entry[128]; int version; }Plugin; #endif
这里为了行文方便,Plugin结构中的字符串为静态尺寸。
计算器
计算器调用parseconf模块中的load_plugins将plugin.xml中定义的Plugin加载进一个GSList,以备后用:
C代码
#include "plugin.h" extern int load_plugins(char *config, GSList **list); #include "plugin.h" extern int load_plugins(char *config, GSList **list);
插件中的函数原型应该符合接口定义:
C代码
//pointer to function, which return a double, and get 2 double as input double (*pfunc)(double a, double b); //pointer to function, which return a double, and get 2 double as input double (*pfunc)(double a, double b);
计算器的主要代码如下:
C代码
int calc_test(double a, double b){ GSList *list = NULL, *it = NULL; Plugin *pl = NULL; //insert a null node into list at first list = g_slist_append(list, NULL); int code = 0; double result; //load plugin defined in plugin.xml into list load_plugins("plugin.xml", &list); for(it = list; it != NULL; it = it->next){ pl = (Plugin *)it->data; if(pl == NULL){ continue; }else{ //open the library flib = dlopen(pl->path, RTLD_LAZY); dlError = dlerror(); if(dlError){ fprintf(stderr, "open %s failed\n", pl->name); g_slist_free(list); return -1; } //get the entry *(void **)(&pfunc) = dlsym(flib, pl->entry); dlError = dlerror(); if(dlError){ fprintf(stderr, "find symbol %s failed\n", pl->entry); g_slist_free(list); return -1; } //call the function result = (*pfunc)(a, b); printf("%s(%f, %f) = %f\n", pl->entry, a, b, result); //then close it code = dlclose(flib); dlError = dlerror(); if(code){ fprintf(stderr, "close lib error\n"); g_slist_free(list); return -1; } } } g_slist_free(list); return 0; } int calc_test(double a, double b){ GSList *list = NULL, *it = NULL; Plugin *pl = NULL; //insert a null node into list at first list = g_slist_append(list, NULL); int code = 0; double result; //load plugin defined in plugin.xml into list load_plugins("plugin.xml", &list); for(it = list; it != NULL; it = it->next){ pl = (Plugin *)it->data; if(pl == NULL){ continue; }else{ //open the library flib = dlopen(pl->path, RTLD_LAZY); dlError = dlerror(); if(dlError){ fprintf(stderr, "open %s failed\n", pl->name); g_slist_free(list); return -1; } //get the entry *(void **)(&pfunc) = dlsym(flib, pl->entry); dlError = dlerror(); if(dlError){ fprintf(stderr, "find symbol %s failed\n", pl->entry); g_slist_free(list); return -1; } //call the function result = (*pfunc)(a, b); printf("%s(%f, %f) = %f\n", pl->entry, a, b, result); //then close it code = dlclose(flib); dlError = dlerror(); if(code){ fprintf(stderr, "close lib error\n"); g_slist_free(list); return -1; } } } g_slist_free(list); return 0; }
首先,定义一个GSList,然后将其传递给load_plugins,load_plugins解析plugin.xml,然后填充list返回,calc_test遍历插件列表,并调用每一个插件定义的entry.
除法器
我们来看一个具体的插件:做除法的模块
C代码
#include <stdio.h> double div(double a, double b){ if(b == 0){ fprintf(stderr, "div zero error\n"); return -1; }else{ return a / b; } } #include <stdio.h> double div(double a, double b){ if(b == 0){ fprintf(stderr, "div zero error\n"); return -1; }else{ return a / b; } }diver.c在编译之后,生成diver.so,将其置于plugin.xml定义的位置处即可。
运行结果如下图所示:
其他代码如xml的解析,GSList的使用等与插件机制关系不大,感兴趣的朋友可以在附件中查看。
- calc.rar (204.9 KB)
- 下载次数: 0
- calc.tar.gz (12.4 KB)
- 下载次数: 2
发表评论
-
深入理解dup和dup2的用法
2011-08-15 11:02 11954引用网上有很多资料详 ... -
Linux下进程绑定多CPU运行
2011-06-10 12:28 2035引用Published on 十二月 17, 2009 2,3 ... -
Visual Studio 2010 编译C及一个完整的c程序(可在windows与linux(用gcc编译)平台下使用)
2011-01-25 13:29 3230中科院分词linux版破解过程 中科院分词linux版破解 ... -
muduo 与 libevent2 吞吐量对比
2010-09-08 14:43 1722http://blog.csdn.net/Solstice/a ... -
C语言插件机制(上)
2010-09-06 14:08 981http://abruzzi.iteye.com/blog/7 ... -
Linux 网络编程 <1>
2010-07-05 17:37 1051环境 Cygwin+windows2003 说明: 服务 ... -
用程序生成swf(flash)文件: ming 和 swftools
2010-05-25 13:40 1797用程序生成swf(flash)文件: ming 和 swfto ... -
linux fork函数学习
2010-05-23 00:55 1448在编写socket ftp之前,我对fork函数进行了学习。 ... -
gdb 子进程 多进程 fork 调试
2010-05-21 17:28 2056标 题: [FAQ] 请问如何用gdb调试子进程 发信站 ...
相关推荐
它包含了完整的游戏逻辑和界面设计,可以帮助我们深入理解华容道的运行机制,以及如何在计算机程序中实现这种机制。这份资料包的内容丰富,包括了华容道游戏的初始化、方块的移动、判断游戏是否胜利等核心功能。同时...
同时,该系统可能还包括了错误处理机制,让用户能够更好地理解如何确保程序的健壮性和稳定性。对于正在学习C语言编程的学生来说,通过分析和运行这个图书借阅系统的源码,可以加深对C语言语法的理解,提升编程技巧,...
基于epoll机制的高并发聊天室,c语言实现 - 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! 1、该资源内...
此外,系统还考虑到了数据的安全性和完整性,通过适当的错误处理和验证机制,确保了数据的准确性和可靠性。 值得一提的是,这套C语言学生成绩管理系统源码资源不仅具有高度的实用性,还具备很强的可扩展性和可定制...
以下是对C语言条形码识别的描述,不包含具体的代码实现: 图像处理:条形码识别首先需要对输入的图像进行预处理。这包括图像的二值化、去噪和增强等操作,以提高条形码的边缘清晰度和对比度。 条形码定位:在...
吞噬成长机制:通过吞噬地图中的小颗粒使球球不断变大,以达成更高分数。 ai小球设置:地图内设有多个ai小球,它们可以根据自身的大小和与玩家的距离来选择追击玩家或者逃跑,增加游戏的趣味性。 积分系统:设立...
4. **游戏机制与玩法**: - 玩家需要定时给作物浇水,保持土壤湿润度。 - 可能包含升级系统,如改进灌溉设备以提高浇水效率。 - 游戏内可能设有任务系统,完成任务获得奖励或解锁新作物。 - 可能存在经济系统,...
游戏保留了经典推箱子游戏的核心玩法,即推动箱子到指定位置,但在此基础上加入了众多创新元素和机制,使得游戏更加丰富和有趣。 二、核心玩法与特色 多样化的关卡设计:每个关卡都有独特的布局和难度,需要玩家运用...
设计敌方坦克生成和控制机制,包括生成位置、难度递增等。 实现碰撞检测,包括坦克与子弹、坦克与障碍物等的碰撞判断。 关卡设计: 设计关卡地图,包括障碍物的位置、敌方坦克的生成等。 设计关卡目标和胜利条件,...
C语言实现基于Risc-V 的操作系统内核模拟设计与实现源代码,一个运行在RISC-V架构处理器上的玩具嵌入式操作系统 完成了操作系统的引导、UART 串口驱动、中断管理、动态内存管理、多任务调度、自旋锁、信号量、FAT32...
其特点包括清晰的代码结构、高效的数据库访问、安全的用户认证和授权机制、响应式布局以适应不同设备、友好的用户界面等。这些项目源码还提供了丰富的功能模块和插件,支持用户管理、权限控制、数据可视化、电子支付...
本课程为《C语言嵌入式Linux编程》第3期,主要对程序的编译、链接及运行机制进行分析。同时对静态库链接、动态链接的过程、插件原理、内核模块运行机进行探讨,后对嵌入式系统比较难理解的u-boot重定位、u-boot加载...
Lua 教程 lua Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用...扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统
健壮性:java的健壮性与自动垃圾回收机制有关,自动垃圾回收机制简称GC机制,java语言运行过程中产生的垃圾是自动回收的,不需要程序员关心。 可移植性:java程序可以做到一次编译,到处运行。在Windows操作系统上...
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。 FastDFS架构 FastDFS架构...
Ceedling还可以通过方便的插件机制进行扩展。 使用说明文件 文档和许可证信息存在 入门 首先,请确保Ruby已安装在您的系统上(如果尚未安装)。 然后,在命令提示符下: > gem install ceedling (为打算成为开发...
UML StateWizard for VS.NET/VC6/EVC4可为嵌入式系统或Win32/WinCE开发带来可视化、基于可移植C语言的UML状态机编程机制。同时,作为Visual C++的插件,它使得开发者可以在强大的Visual C++开发环境中进行嵌入式系统...
本书共分为55章,依次详细讲述了Tcl基础、Tcl高级特性、TK基础、TK组件、TK详解、C语言编程、各版本之间的差异等方面的知识,并通过大量实例,生动翔实地向读者介绍了Tcl/Tk编程,是读者掌握Tcl/Tt的必备参考书。...
emmt扩展加载机制优化;编辑器markdown多光标编辑,支持关联工具栏快捷功能;aero效果支持,登录界面优化;其他优化:文件名超出部分...表示;正在上传、远程下载关闭页面提醒。fix bug安全漏洞修复:文件越权读取...