概述

freeswitch的外围模块是插件式的,可以动态的加载和卸载,使用起来非常的灵活和方便。

如果我们自己来设计一个开源的代码框架,相信这种插件式的模块结构是非常适合多人合作的模式。

本文对fs的模块加载接口进行一些分析和讨论,作为借鉴。

环境

centos:CentOS  release 7.0 (Final)或以上版本

freeswitch:v1.8.7

GCC:4.8.5

模块接口

freeswitch新增mod_task模块的介绍,见之前的文章。

在mod_task模块实现中,有3个最基本的宏定义。分别对应模块的加载,卸载和定义。

SWITCH_MODULE_LOAD_FUNCTION(mod_task_load);

SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_task_shutdown);

SWITCH_MODULE_DEFINITION(mod_task, mod_task_load, mod_task_shutdown, NULL);

宏定义展开后

switch_status_t mod_task_load (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool);

switch_status_t mod_task_shutdown (void);

static const char modname[] =  mod_task ;

switch_loadable_module_function_table_t mod_task_module_interface = {

5,

mod_task_load,

mod_task_shutdown,

NULL,

0

};

使用nm命令查看mod_task模块符号表

[root@localhost mod]# nm -s mod_task.so

00000000002020c8 B __bss_start

U bzero@@GLIBC_2.2.5

00000000002020c8 b completed.6355

w __cxa_finalize@@GLIBC_2.2.5

0000000000000b10 t deregister_tm_clones

0000000000000b80 t __do_global_dtors_aux

0000000000201cd0 t __do_global_dtors_aux_fini_array_entry

0000000000201ce0 d __dso_handle

0000000000201ce8 d _DYNAMIC

00000000002020c8 D _edata

00000000002020d0 B _end

0000000000001060 T _fini

0000000000000bc0 t frame_dummy

0000000000201cc8 t __frame_dummy_init_array_entry

00000000000014c0 r __FRAME_END__

U free@@GLIBC_2.2.5

00000000000012c0 r __func__.18215

0000000000001300 r __func__.18222

00000000000012e0 r __func__.18230

00000000000012d2 r __func__.18237

00000000000012a0 r __func__.18245

0000000000202000 d _GLOBAL_OFFSET_TABLE_

w __gmon_start__

000000000000132c r __GNU_EH_FRAME_HDR

00000000000009f8 T _init

w _ITM_deregisterTMCloneTable

w _ITM_registerTMCloneTable

0000000000201cd8 d __JCR_END__

0000000000201cd8 d __JCR_LIST__

w _Jv_RegisterClasses

0000000000001323 r modname

0000000000000c40 t mod_task_load

00000000002020a0 D mod_task_module_interface

0000000000000c00 t mod_task_shutdown

0000000000000b40 t register_tm_clones

U __strdup@@GLIBC_2.2.5

U switch_channel_export_variable_var_check

U switch_console_set_complete

U switch_core_session_get_channel

U switch_event_bind

U switch_event_get_header_idx

U switch_loadable_module_create_interface

U switch_loadable_module_create_module_interface

U switch_log_printf

U switch_separate_string

0000000000000d80 t task_api_function

0000000000000ee0 t task_app_function

0000000000000f70 t task_event_channel_hangup_complete

0000000000001010 t task_event_handler

00000000002020c8 d __TMC_END__

模块加载

freeswitch启动过程中,会根据配置文件“/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml”的内容,顺序加载所有模块。

对某一个模块的加载过程参考“src\switch_loadable_module.c”文件中的“switch_loadable_module_load_file”函数。

函数中主要使用了“dlopen”,“dlsym”等系统接口,来打开“mod_task.so”动态库文件和查找到”mod_task_module_interface”结构数据。

再调用”mod_task_module_interface->load”函数(指向“mod_task_load”),初始化mod_task模块。

模块卸载

模块卸载的流程参考”src\switch_loadable_module.c”文件中的“do_shutdown”函数。

在全局数据中查找到mod_task模块结构体,调用“module->switch_module_shutdown”函数(指向“mod_task_shutdown”),清理模块,回收资源。

总结

freeswitch使用了系统的动态库管理接口,来动态的加载和卸载外围模块,灵活方便。

空空如常

求真得真

freeswitch插件式模块接口实现方式的更多相关文章

  1. Orchard源码分析(1):插件式的支持——模块和主题

    在Orchard,模块和主题都是可以插拔式的,在源码处理时,用类型(参考:DefaultExtensionTypes)区分,都没太大的本质区别,以下都称做模块. 插件的支持,实现分以下几步: 搜集模块 ...

  2. Javascript的一种代码结构方式——插件式

    上几周一直在做公司的webos的前端代码的重构,之中对javascript的代码进行了重构(之前的代码耦合严重.拓展.修改起来比较困难),这里总结一下当中使用的一种代码结构——插件式(听起来怎么像独孤 ...

  3. C++中模块(Dll)对外暴露接口的方式

    总结下C++中模块(Dll)对外暴露接口的方式: (1)导出API函数的方式这种方式是Windows中调用DLL接口的最基本方式,GDI32.dll, User32.dll都是用这种方式对外暴露系统A ...

  4. C#实现接口的两种方式:显示实现和隐式实现接口

    本示例声明一个接口IDimensions 和一个类 Box,显式实现了接口成员 GetLength 和 GetWidth. 通过接口实例 dimensions 访问这些成员. interface ID ...

  5. 使用 SailingEase WinForm 框架构建复合式应用程序(插件式应用程序)

    对于一些较小的项目,具备一定经验的开发人员应该能够设计和构建出便于进行维护和扩展的应用程序.但是,随着功能模块数量(以及开发维护这些部件的人员)的不断增加,对项目实施控制的难度开始呈指数级增长. Sa ...

  6. Android应用插件式开发解决方法

    转自:http://blog.csdn.net/arui319/article/details/8109650 一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来 ...

  7. Android应用插件式开发解决方法[转]

    一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来越多,APK安装包也越来越大,用户在使用过程中也没有办法选择性的加载自己需要的功能模块.此时可能就需要考虑如何分 ...

  8. MEF 插件式开发之 DotNetCore 初体验

    背景叙述 在传统的基于 .Net Framework 框架下进行的 MEF 开发,大多是使用 MEF 1,对应的命名空间是 System.ComponentModel.Composition.在 Do ...

  9. MEF 插件式开发之 WPF 初体验

    MEF 在 WPF 中的简单应用 MEF 的开发模式主要适用于插件化的业务场景中,C/S 和 B/S 中都有相应的使用场景,其中包括但不限于 ASP.NET MVC .ASP WebForms.WPF ...

随机推荐

  1. anaconda安装PIL

    PIL仅支持到python2.7: Pillow支持Python 3.x: conda install pillow 参考文献: 使用anaconda安装python3版本的PIL_不行不至-CSDN ...

  2. CSS实现水平垂直居中的方式有哪些?

    CSS实现水平垂直居中的方式有哪些? 基本结构样式: .box { width: 400px; height: 400px; background-color: red; } .inner { wid ...

  3. C# RabbitMQ的使用

    本文目的如题. 安装 先说一下RabbitMQ的安装,建议使用Docker镜像安装,Docker安装的好处是不管Windows系统还是Linux,安装步骤少,安装方法相同,不容易出错.使用下面的命令就 ...

  4. SOA 和微服务

    ====>场景 不可能让客户端与6个不同的应用/系统都一一去通信来去完成数据的展示.而是6个应用/系统之间进行彼此通信来完成调用,最后客户端只需要调用一个接口来获取数据即可. SOA架构 SOA ...

  5. 「Codeforces 468C」Hack it!

    Description 定义 \(f(x)\) 表示 \(x\) 的各个数位之和.现在要求 \(\sum_{i=l}^rf(i)\bmod a\). 显然 ans=solve(l,r)%a; if(a ...

  6. 定义制造业操作(定义 MES/MOM 系统)

    定义制造业操作(定义 MES/MOM 系统) 制造业操作包含众多工厂级活动,涉及设备(定义.使用.时间表和维护).材料(识别.属性.位置和状态).人员(资格.可用性和时间表),以及这些资源与包含其信息 ...

  7. [炼丹术]UNet图像分割模型相关总结

    UNet图像分割模型相关总结 1.制作图像分割数据集 1.1使用labelme进行标注 (注:labelme与labelImg类似,都属于对图像数据集进行标注的软件.但不同的是,labelme更关心对 ...

  8. 单芯片替代PS176 DP转HDMI 4K60HZ DP转HDMI2.0转换芯片CS5263

    PS176是一个显示端口 (DP)至HDMI 2.0视频接口转换器适用于需要视频协议转换的电缆适配器.电视接收器.监视器和其他应用.它将接受任何显示端口输入格式,包括DP 1.1a.dp1.2a.dp ...

  9. CS5218|DP转HDMI4K30HZ方案|CS5218应用方案

    Capstone CS5218是一款单端口HDMI/DVI电平移位器/中继器,具有重新定时功能.它支持交流和直流耦合信号高达3.0-Gbps的操作与可编程均衡和抖动清洗.它包括2路双模DP电缆适配器寄 ...

  10. MySQL8.0.20安装详解

    https://blog.csdn.net/yeb112233/article/details/106042867/ alter user root@localhost identified by ' ...