自己做Cpp Binding

来源:互联网 发布:淘宝企业店铺流量扶持 编辑:程序博客网 时间:2024/05/22 12:37

英文原文在:http://lua-users.org/wiki/DoItYourselfCppBinding

当制作自己的游戏引擎时,特别是结合lua,我考虑过很多绑定库,如SWIG, tolua,SimplerCppBinding,等等。没有一个非常适合我的需求:

  • 我想要更多精细控制对象在lua中的处理。
  • 我不喜欢额外的间接指针。
  • 我想尽可能的通过inline代码帮助编译器。

这有一些我找到的窍门,大部分是代码:

创建 metatables

    Lauxlib拥有很实用的函数来操作userdata metatables。他们充分隐藏在LauxLibDocumentation.我建议给每个metatable一个名字在同一个classname;这会使函数预处理程序可用。对不熟悉的操作符:#在#define声明中会导致当宏展开时跟随的参数被放到引用。

检查参数类型

    一个有用的宏简单的检查所给栈中的对象是否有一个所给的userdata种类(用luaL_newmetatable已经注册):

#define lua_userdata_cast(L, pos, T) reinterpret_cast<T*>(luaL_checkudata((L), (pos), #T))

我用如下材料在我的metamethods

if(const MyClass* myclass = lua_userdata_cast(L, 1, MyClass))

{

    MyClass->SomeMethod();

    return 0;

}

放置new来避免装入的指针

  来看:

void* operator new(size_t size, lua_State* L, const char* metatableName)

{

    void* ptr = lua_newuserdata(L, size);

    luaL_getmetatable(L, metatableName);

    // assert(lua_istable(L, -1)) if you're paranoid

    lua_setmetatable(L, -2);

    return ptr;

}

 

#define lua_pushobject(L, T) new(L, #T) T

    现在,代替使用boxpointer的命运,把一个使用luaL_newmetatable创建了的metatable类型的对象压进栈中,象下面:

lua_pushobject(L, MyClass)(arg1, arg2, arg3);

……这些允许你构造一个新的MyClass直接到内存区域可以被使用!

模板化 __gc 方法

看这个:

template<typename T>

int GCMethod(lua_State* L)

{

    reinterpret_cast<T*>(lua_touserdata(L, 1))->~T();

    return 0;

}

这个模板方法做了一个完美的__gc方法。象下面:

lua_pushstring(L, "__gc");

lua_pushcfunction(L, GCMethod<MyClass>);

lua_settable(L, 1);

 

转载:点击打开链接

原创粉丝点击