近为了总结Lua绑定C/C++对象的各种方法、第三方库和原理,学习了LuaBridge库为Lua绑定C/C++对象,下面是学习笔记,实质是对该库的Reference Manual基本上翻译了一遍,学习过程中测试代码,放在我的github上。
  LuaBridge的主要特点
  源码只有头文件,没有.cpp文件,没有MakeFile,使用时只需一个#include即可。
  支持不同的对象生命周期管理模式。
  对Lua栈访问方便并且是类型安全的(type-safe)。
  Automatic function parameter type binding.
  Easy access to Lua objects like tables and functions.
  LuaBridge的API是基于C++模板元编程(template metaprogramming)的。在编译时这些模板自动生成各种Lua API调用,从而可以再Lua脚本中使用C++程序中的类和函数。为了能在C++中使用Lua的数据,比如number,string,table以及方便调用Lua的函数,使用LuaBridge中的LuaRef类,可以方便做到。
  LuaBridge设计原则
  由于LuaBridge的设计目标尽可能方便使用,比如只有头文件、没有用到高级C++的语法、不需要配置。因此LuaBridge性能虽足够好,但并不是好的,比如OOLua(https://code.google.com/p/oolua/)执行效率比它好,并且它也不像LuaBind(http://www.rasterbar.com/products/luabind.html)那样功能全面。LuaBridge不支持下面特性:
  枚举型常量
  不支持8个以上的函数或方法的调用
  重载函数、方法和构造函数(Overloaded functions, methods, or constructors)
  全局变量(变量必须被包装在命名空间里)
  自动地转换STL容器类型和Table
  在Lua中继承C++类(Inheriting Lua classes from C++ classes)。
  Passing nil to a C++ function that expects a pointer or reference
  Standard containers like std::shared_ptr
  在Lua访问C++
  为了在Lua中使用C++中的数据和函数,LuaBridge要求任何需要使用的数据的都需要注册。LuaBridge可以注册下面五种类型数据:
  Namespaces  一个Lua table包含了其他注册信息
  Data  全局变量或静态变量、数据成员或静态数据成员
  Functions  一般函数、成员函数或静态成员函数
  CFunctions  A regular function, member function, or static member function that uses the lua_CFunction calling convention
  Properties  Global properties, property members, and static property members. These appear like data to Lua,but are implemented in C++ using functions to get and set the values.
  Data和Properties在注册时被标记为只读(read-only)。这不同于const,这些对象的值能在C++中修改,但不能在Lua脚本中修改。
  Namespaces
  LuaBridge索引的注册都是在一个namespace中,namespace是从lua角度来看的,它实质上是table,注意这里的namespace不是C++中的namespace,C++的namespace不是一定需要的。LuaBridge的namespace是对Lua脚本来说的,它们被作为逻辑组合工具(logical grouping tool)。为了访问Lua的全局命名空间(global namespace),可以在C++中,这样调用:
  <span style="font-size:14px;">getGlobalNamespace (L);</span>
  上面的调用会返回一个对象(实质是table)可用来进一步注册,比如:
  <span style="font-size:14px;">     getGlobalNamespace (L)
  .beginNamespace ("test");</span>
  上面的调用会在Lua的_G中创建一个名为"test"的table,现在这个table还是空的。LuaBridge保留所有以双下划线开头命名的标识,因此__test是无效的命名,尽管这样命名LuaBridge不会报错。我们可以进一步扩展上面的注册:
<span style="font-size:14px;">    getGlobalNamespace (L)
.beginNamespace ("test")
.beginNamespace ("detail")
.endNamespace ()
.beginNamespace ("utility")
.endNamespace ()
.endNamespace ();</span>