windows下编译出doubango的RTP封装模块

我的需求是得到一个包含其内部所有相关函数定义的tinyRTP.lib,起因是我要在tinyrtp模块添加几个接口,并在其上封装一层,构造一个上层应用调用的RTP功能库,对于它不多表,因为一直在踩坑所以折腾了三四天才搞定,本文将大致说一下tinyRTP.lib的构造流程和注意点。

tinyRTP是doubango下负责RTP传输工作的模块,按照五层网络的层级标准看它属于传输层,它是基于另一个模块tinyNET定义的,tinyNET模块则属于网络层,另外它内部几个接口还需要tinyMEDIA的函数定义,然后他们共同基于doubango的工具模块tinySAK,知道了这个包含关系工作就可以大致顺利开展了,我的编译平台是visual studio 2008(vs9.0),解决方案平台Win32。

 

① tinySAK的编译

首先在属性->配置属性->常规中的配置类型设置为.lib,zhengchangshy之后配置头文件的路径:

xxxx\vs2008\VC\include 
../thirdparties\win32\include\pthread 
../thirdparties\win32\include

之所以配置pthread路径是为了在生成tsk_debug.obj的过程中编译器提示“警告被视为错误,没有生成object文件”,查看原因是未找到localtime_r的函数定义,因此在源文件tsk_debug.c头部添加了头文件pthread.h的包含,问题消失。

之后查看属性->配置属性->C/C++->预处理器定义,几个项保持不变就好,我这里是:

WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0X0501;TINYSAK_EXPORTS

之后添加附加依赖项,属性->配置属性->管理员->常规->附加依赖项,添加“winmm.lib”。

最后直接生成即可。

 

② tinyNET的编译

前面步骤有重合之处不谈,额外在C/C++->常规->附加包含目录中添加tinySAK头文件的目录,然后注意,一定要在C/C++->常规->预处理器中定义宏--“TINYSAK_IMPORTS_IGNORE”,具体原因可以看tinySAK的配置头文件tinysak_config.h,其路径是“tinySAK/include”有部分代码为:

#if !defined(__GNUC__) && defined(TINYSAK_EXPORTS) 
# define TINYSAK_API __declspec(dllexport) 
# define TINYSAK_GEXTERN extern __declspec(dllexport) 
#elif !defined(__GNUC__) && !defined(TINYSAK_IMPORTS_IGNORE) 
# define TINYSAK_API __declspec(dllimport) 
# define TINYSAK_GEXTERN extern __declspec(dllimport) 
#else 
# define TINYSAK_API 
# define TINYSAK_GEXTERN

TINYSAK_API是定义在每个tinySAK导出函数名前的关键字,因为tinyNET代码包含了tinySAK的头文件,那么这些函数声明也被携带到了当前(tinyNET)代码,编译器就会按照TINYSAK_API的宏定义去理解tinySAK中的函数符号,举个栗子,比如:

SAK模块有函数tsk_object_new,在静态库tinySAK.lib中的符号表现是“_tsk_object_new”,因为在函数名前+“_”是C语言的标准,现在tinyNET中将调用该函数,而此时该函数是存在声明的,编译器将试图根据已经声明的函数符号去tinySAK.lib中寻找函数定义,那么问题来了,当前该函数的声明的符号是什么呢,这就取决于预处理器的定义了,参考上述代码即可,如果没有定义宏TINYSAK_IMPORTS_IGNORE,那将有--“# define TINYSAK_API __declspec(dllimport)”,编译器则会将函数tsk_object_new符号标示为__imp__tsk_object_new,链接器通过该符号名称去tinySAK.lib中寻找,自然是找不到的,将会报错:“无法解析的外部符号__imp__tsk_object_new”,要避免这个问题,就需要上述的预定义了。

然后右键项目直接生成即可,注意此时不必将tinySAK.lib作为附加依赖项静态添加到库中,因为后面还需要将tinySAK.lib作为依赖项提供给tinyRTP,静态库的生成不要求内部函数完全可实现(存在函数多层级调用)。

 

③ tinyMEDIA的编译没啥可说的,直接编就行

④ tinyRTP的编译

首先将tinySAK、tinyNET、tinyMEDIA的头文件目录附加进来;预处理器定义同理添加如下几项:

TINYSAK_IMPORTS_IGNORE;TINYNET_IMPORTS_IGNORE;TINYMEDIA_IMPORTS_IGNORE;

然后,配置属性->管理员->常规->附加依赖项:

ws2_32.lib;iphlpapi.lib;libeay32.lib;ssleay32.lib;libsrtp.a;xxx\tinySAK.lib;xxx\tinyNET.lib;xxx\tinyMEDIA.lib;

"xxx"更改为那几个库的实际目录。

重新生成,即可。

 

tips:

这里有一个小方法,当需要对静态库进行多层次封装和编译的时候,为了保证高层库包含了底层库的函数定义,可以先以编译高层动态库为目标,因为当编译动态库时,链接器是以函数能否运行为标准去“工作”,链接器将会去寻找库内每个.obj文件内的函数定义,如果不存在(或者函数符号存在问题)则会报错,但是静态库就会将这部分“错误”隐藏,即便编译出了静态库,虽然静态库内包含有完整的函数定义,但是高层定义的函数能否正常调用底层函数还是不一定的!因此可以先编译出动态库,无误后再更改项目的配置属性为.lib,再编译出的静态库即可保证可正常使用。

启动测试函数tinyRTP\test\test.c,测试tinyRTP.lib运行正常。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值