开源库的选择和驾驭

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.

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

bool ice_register_thread()
{
	if(!pj_thread_is_registered()) 
	{
		pj_thread_desc desc;
		pj_thread_t* thed;
		if (pj_thread_register(NULL,desc,&thed) == PJ_SUCCESS)
		{
			return true;
		}
	}
	return false;
}

原来存在的正常位置代码堆栈崩溃问题消失了。
这个现象里是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、搞不定的,先变通实现最好

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

开源库的调用通常需要经过以下几个关键步骤:首先明确项目所需的具体功能并挑选合适的开源工具,然后获取该软件包或框架,最后将其整合至自身的工作流之中完成初始化设置以便正常使用其中提供的各项特性。 ### 步骤详解 #### 第一步:确定需求与选型 开发者应先分析当前项目的特定技术诉求是什么样的。比如对于Web开发来说如果追求快速搭建RESTful API服务可以选择FastAPI;而对于数据科学领域则更多考虑NumPy、Pandas这样的数据分析利器等等。通过对比多个候选方案的功能列表、活跃度以及文档质量等方面最终敲定最贴合实际情况的目标开源库。 #### 第二步:安装获取资源 一旦决定了要使用的开源库之后就要着手把它引入进来。这一步取决于所处平台及语言生态系统的差异可能会采取不同手段达成目标。以下是几个典型场景的操作指南: - **Python** 环境下推荐使用pip命令行工具直接在线搜索指定名称即可自动解析依赖关系同步拉取最新稳定版到本地缓存区等待后续引用。 示例代码如下: ```bash pip install requests # 这里以HTTP请求处理为例演示如何添加requests这个简单又好用的小插件 ``` - Java 开发者们习惯借助Maven Central Repository托管中心寻找心仪的构件坐标信息填入build.gradle文件内由Gradle构建系统负责协调一切事宜包括但不限于下载jar包解压归档生成classpath供IDE读取索引等功能。 Maven样例配置段落: ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.0</version> </dependency> ``` #### 第三步:集成与实例化 当所有准备工作都绪接下来便是正式开启编码之旅的时候了。一般而言官方维护人员都会贴心地提供详尽的新手引导教程帮助初次接触的朋友迅速上手掌握基本语法格式学会怎样声明变量创建对象传递参数调用成员函数之类的常识点。 假设我们现在想利用BeautifulSoup来做HTML网页抓取工作,那么大致流程应该是下面这样子的样子: ```python from bs4 import BeautifulSoup as soup # 导入库起个别名方便书写简洁明了 html_doc = """<html><head><title>Test Page</title></head><body><p id='para'>Hello World!</p></body></html>""" soup_obj = soup(html_doc,'lxml') # 初始化beautifulsoup传参设定解析器类型 lxml速度较快效果佳 content=soup_obj.find("p",id="para").text # 查询标签属性筛选文本内容存储结果返回给用户端展示出来看一眼成果咯~ print(content) 输出"Hello World!" ``` 此外值得一提的是有些复杂的大型跨组件协作型开源项目也许还涉及到额外的服务启动监听机制或者是分布式集群部署考量因素此时就需要参考专业书籍深入研究其背后的原理架构图示等内容才能真正驾驭自如发挥最大功效啦!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值