概述

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. 网易云 微专业C++系统工程师

    网易云 微专业C++系统工程师 一.学前基础 1.曾经学过某种编程语言(C语言最佳) 2.了解基本的变量.类型.作用域.循环和控制流程:了解基本数据类型(整数.浮点.字符串.数组等) 3.知道如何编译 ...

  2. 带SD读卡的USB HUB方案芯片MA8621|用于带读卡的USB HUB拓展坞方案芯片MA8621

    MA8621是一款带SD读卡器控制器的USB 2.0高速3端口集线器方案芯片,主要用在USB TYPEC拓展坞或者USB typec扩展底座上面. 1. MA8621功能概述 MA8621是USB 2 ...

  3. ARTS Week 19

    Algorithm 本周的 LeetCode 题目为 5. 最长回文子串 给你一个字符串 s,找到 s 中最长的回文子串.例如输入:s = "babad",输出:"bab ...

  4. 元宇宙(metaverse)中文社区-工程实践

    欢迎访问元宇宙中文社区,在这里大家可以提问,回答,分享,诉说,一起构建一个元宇宙社区. 2021年"元宇宙"的这个词的火热程度在业内绝对不亚于疫情,趁着这个热度,本文记录了如何搭建 ...

  5. Log4j2完整XML参考(详细注释说明)

    1.说明 本文提供完整的log4j2.xml配置文件, 供开发中参考使用,可以作为模板, 配置对应实现如下常用的功能: 1.自动检测和重新加载配置,每10分钟(600s)检测一次 2.每个日志文件最大 ...

  6. .NetCore基于Jenkins和Gogs的自动化部署方案

    准备工作 Jenkins和gogs的安装配置可以看前两篇:Jenkins安装.配置与说明  和 gogs安装与说明(docker) 此外,因为还要安装.net core的SDK和Git工具: 安装.n ...

  7. MATLAB 错误之生成step图表出错

    m文件: step(Gi_close) hold on 错误示例: 使用step函数生成图表后,报错如下: Plots must be of the same type and size to be ...

  8. Springboot+Javamail实现邮件发送

    Springboot+Javamail实现邮件发送 使用的是spring-context-support-5.2.6.RELEASE.jar里的javamail javamail 官方文档:javam ...

  9. python @property用法(转载)

    偶然碰到一篇讲解 @property 比较清晰的文章 记录下来 日常复习 # @property'''@property是python的一种装饰器,是用来修饰方法的 作用:我们可以使用@propert ...

  10. vi中使用鼠标右键插入时进入(insert)visual模式

    使用vim插入外面复制的内容时,用右键点击后,并未将内容粘贴进去,而是进入了(insert)visual模式,解决方法:先shift+enter进入普通模式输入 set mouse-=a然后再i进入i ...