开源库的选择和驾驭

开源库的选择和驾驭

C/C++的开源库大部分还是比较好的,体现在:

1、开源,意味着可以使用lib或源码,这点很灵活。

2、功能现成,意味着我们不需要再重复劳动。

3、一般较符合标准国际,通用性好。

4、一般免费,license较宽松,具体见GPL LGPL BSD等license,然而我们是天朝的特殊情况,你懂的。。

然而好的库,其实未必好用,有很多坑,甚至不明显,甚至坑很深:

1、即便成熟的库(尤其是C的),一般都是需要初始化。

例如pjsip里的pjlib pjutil pjnath等基本都有个xxx_init(),而上来就用或者忘记使用这些init的代码就会带来问题。

2、函数功能的坑,比如pj_str_t pj_str(char * str)这个函数,不翻源码,你能知道这是个浅拷贝函数吗?

假如你给它传了个临时变量的str,那你就给自己挖了个坑,什么时候掉进去是未知的。

2、异常的崩溃问题,即便你定位到该位置,缺发现原本很正常的代码却崩溃了。

注释掉几行代码,发现崩溃延后了,这说明是其他问题引起的堆栈崩溃,而不是该几行代码的问题。

而这种问题的解决基本是无迹可寻的,只有个“0x0000005”不可访问之类的异常。

这样的问题很可能是该库或者该接口有依赖:

比如,使用pjlib库的外部线程必须被注册给pjlib库,本人使用pjnath库就遇到了这样的问题。

vs2012 编译的pjnath icedemo例子没问题,自己改来用在dll里 结果 出现 堆栈被破坏

#  define PJ_CHECK_STACK()// pj_thread_check_stack(__FILE__, __LINE__)
把该宏空置失效,可以解决,但是百思不得其解。

后来终于发现是外部使用线程并未注册给pjlib,还是尼玛翻源码发现的。

pj_thread_register的说明:

This function must be called in the context of the thread being registered.
 * When the thread is created by external function or API call,
 * it must be 'registered' to PJLIB using pj_thread_register(), so that it can
 * cooperate with PJLIB's framework.

这引起了我的怀疑,在外部线程函数优先调用下边的函数来尝试

[cpp]  view plain copy
  1. bool ice_register_thread()  
  2. {  
  3.     if(!pj_thread_is_registered())   
  4.     {  
  5.         pj_thread_desc desc;  
  6.         pj_thread_t* thed;  
  7.         if (pj_thread_register(NULL,desc,&thed) == PJ_SUCCESS)  
  8.         {  
  9.             return true;  
  10.         }  
  11.     }  
  12.     return false;  
  13. }  

原来存在的正常位置代码堆栈崩溃问题消失了。
这个现象里是pjnath依赖pjlib和pjutil,而pjlib依赖“调用pjlib库的外部线程必须注册给它”这个条件。

而这个条件在pjnath的文档或wiki里并未体现,所以有时候要调查清楚所有的依赖问题来定位异常。

3、使用源码和lib或dll的经常有区别。

比如pthread for win32的版本使用静态库的时候,必须使用成对的初始化和销毁函数。而用dll就没这问题。

4、跨平台问题。

越成熟的库跨平台性能越好,linux和windows下的编译和使用文档健全,用的人多,出了问题,度娘、谷哥一般能解决问题。

最后,谈下自己的经验:

选库条件:1、出的早2、用的人多3、依赖其他库少4、各个平台开发使用文档详细5、最好用c++的库(c库有些回调函数是满天飞的)6、能满足自己需要,其他功能越少越好。

用库方法:1、涉及的文档务必仔细看2、遇到问题不要轻易放弃,可选用排除法定位问题类型3、务必多尝试4、搞不定的,先变通实现最好

最后,驾驭开源库是一个时间未知的工作,但是我们尽量缩短时间。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当涉及到使用Makefile来编译和构建项目时,以下是一些常用的命令和技巧: 1. 编写Makefile:创建一个名为`Makefile`(或者`makefile`)的文件,并使用特定的语法编写规则。 2. 基本规则:每个规则由一个目标、一个或多个依赖和要执行的命令组成。例如: ``` target: dependency1 dependency2 command1 command2 ``` 3. 默认目标:可以指定一个默认目标,在没有明确指定目标时将会执行该目标。例如: ``` all: target ``` 4. 变量:可以定义变量来存储命令、编译器选项等。例如: ``` CC = gcc CFLAGS = -Wall -O2 ``` 5. 模式规则:可以使用通配符和模式匹配来定义一组类似规则。例如: ``` %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ ``` 6. 依赖关系:Makefile会自动检测源文件和头文件之间的依赖关系,并根据需要重新编译。你可以使用`gcc -M`命令生成依赖关系。 7. 命令前缀:在命令行中,可以使用`@`前缀来隐藏命令的输出。例如:`@echo "Hello, world!"`。 8. 常用命令: - `make`:使用默认Makefile编译项目。 - `make target`:编译指定的目标。 - `make clean`:删除生成的目标文件和可执行文件。 - `make -n`:显示将要执行的命令,但不实际执行。 - `make -f Makefile2`:使用指定的Makefile进行编译。 以上只是一些基本的概念和命令,Makefile还有更多高级的功能和技巧。希望这些信息对你有所帮助!如果你有任何具体的问题或需要更多帮助,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值