C/C++脚本化: 探索篇
本文来源:Zero’s Donkey Den
原文地址:7-0.cc/cpp_scripting_exploration_1
转载许可:未经授权,禁止转载
使用C/C++等系统级语言开发业务逻辑效率太低? 这个功能用脚本写最多只要三天?我们对执行速度和资源又没啥要求…… 不知道过去你是否也有过这样的想法?
随着软件工程与计算机硬件的飞速发展,对于一些开发场景来说,系统级语言多少显得有点“大材小用”了,这迫使我们需要结合一门脚本语言相互配合,快速迭代产品。
本文主要描述通过脚本语言来扩展C/C++,而非以脚本语言为主的应用场景。
1 为什么要脚本化
我们知道C/C++是一种高效且功能强大的系统级编程语言, 被广泛用于操作系统、服务器、游戏引擎及客户端应用程序的开发。然而随着计算机硬件性能的飞速提升,在许多对性能要求不高的场景下,相比其所带来的复杂度与开发成本,其他方面的优势已经不再显著。许多开发者转向了脚本语言,利用其与生俱来的灵活性、丰富的生态,快速迭代产品,达到降本增效的目的,而需要性能的场景又可以反过来结合C/C++,这样即保证了程序的高效运行又兼顾了开发速度。
比如近些年流行的 Electron
, 它将WEB技术应用到了桌面端应用程序, 即用JavaScript写业务逻辑, 以HTML、CSS渲染用户界面。
另外一些开发者期望将程序的相关功能,通过脚本语言的接口暴露给用户,以便用户可以通过这些接口来扩展程序的功能,提高灵活性以及适应性。如IDA
静态分析工具就使用Python
来扩展软件功能,这样用户可以通过Python编写插件、执行一些自定义任务。此外还有Microsoft Office
与Visual Basi
、《魔兽世界》与Lua
等等。
2 现有项目的脚本化及方式
尽管与脚本语言结合有诸多优势,但现有大部分的项目仍然是通过传统C/C++实现。因此针对这部分现有项目,我们可以在其版本迭代、新功能开发、维护期间,通过脚本化部分功能模块或业务逻辑,达到简化开发与维护的工作,即某项独立的任务通过调用脚本语言编写的模块来完成。
这里我们主要探讨脚本语言扩展C/C++的场景,目前主要有如下两种扩展方式:
- 直接嵌入脚本语言的解释器
- 通过子程序的方式调用脚本模块(不适用于Lua)
2.1 嵌入解释器
将脚本语言解释器作为一个模块集成到C/C++项目中,然后以调用函数的方式运行脚本模块,通常需要等待脚本运行结束之后才会返回。执行结果通过解释器API获取,通常包含:返回值
及上下文对象
。
2.1.1 优点
- 灵活性高
通过解释器提供的API,开发人员可以轻松修改和扩展解释器的功能。 - 交互简单
脚本与宿主程序运行在同一进程内,两者之间可以通过暴露接口的方式直接交互,而无需编写进程通讯方面的代码。 - 资源共享
由于在同一进程内,资源可以相互共享(通过接口访问)。
2.1.2 缺点
- 兼容性风险
不同发行版的解释器提供的API可能并不兼容,切换解释器版本困难。 - 并行执行差
大部分脚本语言解释器是单线程设计,不能提供真正意义上的多核并行,且这种机制不能通过在多个逻辑线程上运行解释器解决,如CPython
的全局解释器锁(GIL)[1]。
2.1.3 例子
下面是通过Boost.Python
嵌入Python解释器[2],并执行了一个简单的脚本文件的例子
script.py:
print</