http://sunxiunan.com/?p=1447
经常有人问到关于Lua的问题是“Lua如何能使用C++的成员变量?”“Lua如何调用C++类的成员函数?”“C++的复杂数据结构(如数组)如何传递进入Lua让Lua可以使用?”
这些问题之频繁,几乎每天都可以看到。问题的起源也很简单,这些提问者大多是C++程序员,公司需要使用Lua,他们就想如何能够“完美无缝”整合C++和Lua。
如果在谷歌中文(google.cn)搜索Lua关键字,第一页大概前五六个网址中会有云风的这篇文字《Lua 不是 C++》,里面的结论部分十分精彩:
对于那些新接触 lua 的 C/C++ 程序员来说,我的第一条建议通常是:看看 lisp/scheme 吧,可能 lua 的血统里,scheme 的成分比 C 更多一些。要不玩一下 Haskell ,增进对函数式编程的了解。C++ 借助 template 是可以玩玩函数式编程,但很少有人真的去用。进入 lua 的领域后,你得正正经经的理解一下了。
Lua与C++不是一种语言,Lua的产生也不是为了让C++这个大奶高兴,它的地位是独立的。
我在twitter上发了这样一些感慨:
感觉这里面有百分之五十的问题都是c++如何导出所有类型给lua,lua如何调用c++成员变量、类成员、内部函数。这些人太纠结了!思路不对,就跟把c++当做高级c来使用一样。展开一点说,这种用法的来源,首先是设计人员脑子不清楚了,lua与c++的边界完全混在一起,没有把接口最小化,以及适当简化,就是c++完全贴到lua上。清晰地api(通用意义上的),就是定义适当的操作,可以扩展,但是不过分耦合。lua和c++应该是哑铃状连接,而不是水桶。
为什么Lua与C++无缝整合有问题,原因很简单:任何一个有经验的程序员都知道,如果两个系统之间是紧密相连到成员函数成员变量都可以随便调用,那么这两个系统的耦合度一定是相当高,容易出现的问题就是难扩展、难修改、难维护。这两个系统不如直接整成一个系统算了。
如何正确使用Lua与C++?
首先第一个问题是,你的系统谁是主导?Lua还是C++?首先搞清楚这个问题。因为主导的部分代码将作为框架出现,负责调用或者响应事件、逻辑。如果Lua与C++的代码都做同样的工作,那么这个系统的设计是有问题的。
第二个问题是,你的系统里面,作为主导部分想开放那些接口?(我们姑且认为Lua与C++的中间连接部分为接口interface)。两个系统之间,不需要完全整合,只要开放必要的接口或者说是API即可。在著名的《Designing Qt-Style C++ APIs》中,作者Matt总结了下面6个优秀API的特点:
-
Be minimal: A minimal API is one that has as few public members per class and as few classes as possible. This makes it easier to understand, remember, debug, and change the API.
- 最小化: 一个最小化的借口是使用尽可能少的类以及尽可能少的类成员。这样使得理解、记忆、调试以及改变API更容易。
-
Be complete: A complete API means the expected functionality should be there. This can conflict with keeping it minimal. Also, if a member function is in the wrong class, many potential users of the function won’t find it.
- 完整: 一个完整的API意味着被期望的功能都包含在内。这与保持最小化有些冲突。而且,如果一个成员函数在一个错误的类中,很多有可能需要这个函数的用户没法找到它。
-
Have clear and simple semantics: As with other design work, you should apply the principle of least surprise. Make common tasks easy. Rare tasks should be possible but not the focus. Solve the specific problem; don’t make the solution overly general when this is not needed. (For example, QMimeSourceFactory in Qt 3 could have been called QImageLoader and have a different API.)
- 清楚简洁的语义: 像其他设计工作一样,你应该应用最小惊讶原则。这使得通用的任务更容易。不常用的任务可以存在但不是重点。API的目的是解决特定问题。没有必要的时候不要让解决方案互相重叠。
-
Be intuitive: As with anything else on a computer, an API should be intuitive. Different experience and background leads to different perceptions on what is intuitive and what isn’t. An API is intuitive if a semi-experienced user gets away without reading the documentation, and if a programmer who doesn’t know the API can understand code written using it.
-
直观:与计算机里面其他的事情一样,一个API应该是直观的。不同的经验以及背景导致对什么是直观什么不是直观有着不同的理解。如果一个有些经验的用户可以直接使用API而不需要阅读文档,或者一个程序员可以直接理解用这个API写的代码而不需要了解这个API,那么这个API就是直观的。
-
Be easy to memorize: To make the API easy to remember, choose a consistent and precise naming convention. Use recognizable patterns and concepts, and avoid abbreviations.
-
容易记忆:让API容易记忆,选择一个统一的简洁的命名规范。使用容易识别的模式或者概念,另外避免缩写。
-
Lead to readable code: Code is written once, but read (and debugged and changed) many times. Readable code may sometimes take longer to write, but saves time throughout the product’s life cycle.
-
产生可读性高的代码:代码是编写一次,但是要多次阅读(当你调试或者修改的时候)。可读性高的代码常常需要花费更长的时间去编写,但是从整个产品生存周期来看,时间还是节省的。
总而言之,Lua本身有它自身的特点,如函数式编程,尾调用,变量无类型等等,这些特点与C++是截然不同的,如果你非要把C++与Lua弄得无缝整合,将来一定会因为这个高耦合产生各种各样的问题。
就如我在twitter中说的那样:编程弄得这么纠结,何必呢?!
分享到:
- 2009-11-09 12:41
- 浏览 4988
- 评论(1)
- 论坛回复 / 浏览 (1 / 5297)
- 查看更多
相关推荐
标题 "toh-pt6_lua_C++_" 暗示了一个项目,其中可能涉及到使用 Lua 脚本语言与 C++ 代码的集成。这个项目可能是关于“Tour of Heroes”(英雄之旅)系列教程的一部分,这是一个常见的 AngularJS 示例应用,但这里的...
《Cocos2d-x实战_Lua卷_第2版》是一本专为游戏开发者准备的指南,主要聚焦于使用Cocos2d-x框架与Lua语言进行游戏开发。Cocos2d-x是一个开源的游戏开发框架,它允许开发者用C++、Lua或者JavaScript编写游戏,并且可以...
4. **在Lua中调用**:一旦C++类和方法被正确注册,你就可以在Lua脚本中自由地创建和使用`MyCustomClass`实例。例如: ```lua local myInstance = MyCustomClass:new() myInstance:doSomething() ``` 5. **错误处理...
Cocos2d-x原生是用C++编写的,但通过Lua绑定,开发者可以使用易于学习和阅读的Lua语言进行编程,这极大地减少了代码量,提高了开发速度。Lua是一种轻量级的脚本语言,语法简洁,适合嵌入式系统和游戏开发。在Cocos2d...
所有版本LUA源码 lua-5.3.5 lua-5.3.4 lua-5.3.3 lua-5.3.2 lua-5.3.1 lua-5.3.0 lua-5.2.4 lua-5.2.3 lua-5.2.2 lua-5.2.1 lua-5.2.0 lua-5.1.5 lua-5.1.4 lua-5.1.3 lua-5.1.2 lua-5.1.1 lua-5.1 lua-5.0.3 lua-...
标题中的"protoc-gen-lua-master proto生成lua"涉及到的是一个使用ProtoBuf(Protocol Buffers)与Lua结合的工具,具体来说,`protoc-gen-lua`是一个代码生成器,它扩展了Google的`protoc`编译器,用于将.proto文件...
内容可能包括Lua的基础语法、C++与Lua的接口使用、实例分析等,对于初学者来说是一份很好的参考资料。 总之,通过这份资料,C/C++开发者可以快速了解并掌握Lua脚本语言,利用其灵活性和性能优势提升项目开发效率。...
本示例中的"lua_test.rar"文件集是一个关于C++与Lua交互的实践案例,主要探讨了如何通过Lua脚本调用C++编写的函数。下面我们将详细探讨这个主题。 首先,Lua是一种轻量级的脚本语言,它简洁、易学,常被用于游戏...
标题中的“protoc-gen-lua-master 整合所需资源”涉及到的是一个与Protocol Buffers(protobuf)相关的项目,其中`protoc-gen-lua`是一个用于生成Lua语言代码的protobuf编译器插件。这个项目旨在将protobuf定义的...
《 luajava-1.1-x64-lua51:Lua与Java的桥梁》 在IT领域,尤其是在游戏开发和脚本编程中,Lua和Java两种语言常常被结合使用,以发挥各自的优势。"luajava-1.1-x64-lua51"是一个针对64位系统的版本,它提供了将Lua...
将LUA与C++结合,可以让开发者利用LUA的易读性和简洁性来编写业务逻辑,同时利用C++的高性能和复杂功能。本文将详细介绍如何在LUA中调用C++类,并在Linux环境下进行编译。 首先,要实现LUA调用C++类,我们需要一个...
在IT领域,有时候我们需要在不同的编程语言之间进行交互,例如使用脚本语言 Lua 调用 C++ 编写的动态链接库(DLL)。本示例是关于如何在 Lua 中调用由 Visual Studio 2010 编译的 C++ DLL 的教程。下面将详细介绍这...
obs-文本-脚本 date-and-time.lua
### Lua与C++交互的关键知识点 #### 一、Lua脚本语言的特点与优势 - **简介**: Lua是一种轻量级的脚本语言,基于标准C编写,因此可以在几乎所有操作系统上运行。 - **特点**: - 变量无类型:Lua中的变量无需预先...
5. 传递数据:C++与Lua之间可以传递不同类型的数据。使用`lua_pushnumber`、`lua_pushstring`等函数将C++数据推送到Lua栈,使用`lua_tonumber`、`lua_tostring`等函数从Lua栈获取数据。 6. 清理:调用`lua_settop(L...
这对于游戏开发尤其重要,因为游戏引擎通常用C/C++编写,而Lua则作为游戏逻辑和脚本语言。 学习Lua时,重点应该放在其灵活性和简洁性上。理解如何利用表构建复杂的数据结构,如何通过元编程实现动态行为,以及如何...
因为 ProtoBuf 的编译器通常用 C++ 编写,但也有 Python 接口,这个脚本可能用于下载和安装 protoc 的 Python 插件,以便在 Lua 环境中使用。 2. `ReadMe.txt`:这是标准的说明文件,很可能包含了关于如何使用这个...
2. **C++与Lua的绑定**:C++和Lua的交互主要依赖于luaBridge、tolua++或tolua等库,它们提供API让C++函数可以调用Lua脚本,反之亦然。在本项目中,我们可能会看到如何使用这些库注册C++函数到Lua环境,以及如何在Lua...
《32位与64位环境下的luajava-1.1-x64-lua51.zip:Lua与Java的无缝交互》 在信息技术领域,跨语言交互是常见且重要的需求, Lua 和 Java 作为两种广泛应用的编程语言,通过 luajava 框架实现了高效的数据交换和功能...
当Lua与C++结合时,可以实现快速的原型开发,同时利用C++的强大性能进行底层优化。 在Lua和C++的交互中,通常有两种主要的方式:一是通过C++调用Lua脚本,二是通过Lua调用C++编写的函数。这种方式使得开发者可以在...