从 Lua 中提取 Wx 类

lua-users home
wiki

本教程/示例旨在帮助您了解如何在 lua_CFunction 中从 Lua 堆栈中提取 [wxLua] 用户数据对象。

这里使用的基本过程是从 wxWidgets 类的 wxLuaState 对象中获取一个称为类标签的值,并使用该标签在 C++ 中获取实际的 wxLua 对象。

类标签是一个整数 ID,用于标识 wxWidgets 类类型(wxDCwxWindowwxCheckBox 等),并在 wxLuaBindClass 结构中找到。该标签还存储在 wxLua 推送到 Lua 的所有用户数据对象的元表中,以标识用户数据是什么,另请参见“int wxlua_ttag(lua_State* L, int stack_idx)”。

wxLuaBindClass 结构是 wxWidget 类的 C++ 版本的描述,wxLua 绑定使用它来将该类绑定到 Lua。

struct wxLuaBindClass // defines a LUA C++ class interface
{
    const char      *name;          // name of the class
    wxLuaBindMethod *methods;       // pointer to methods for this class
    int              methods_n;     // number of methods
    wxClassInfo     *classInfo;     // pointer to the wxClassInfo associated with this class
    int             *class_tag;     // lua tag for user data allocated by ourselves
    const char      *baseclassName; // name of base class
    wxLuaBindClass  *baseclass;     // Pointer to the base class or NULL for none.
                                    // This member is set after all the bindings are
                                    // registered since the base class may be from
                                    // a different module (a library perhaps).
                                    // See wxLuaBinding::SetBaseClass

    wxLuaBindDefine* enums;         // Class member enums (if any)
    int              enums_n;       // number of enums
};
(您可以在 wxlbind.h 中找到 wxLuaBindClass 的定义)

class_tag 成员是您想要的。它是一个指向在启动时定义的常量的指针。(这些结构在 modules/wxbind/src/wxXXX_bind.cpp 中初始化)现在如何获取特定 wxWidget 类的类描述?

wxLuaBindClass* wxLuaState::GetLuaClass(const char* class_name)

此方法返回指向 wxLuaBindClass 结构的指针,该结构将包含您可以用来检索实际对象的类标签。class_name 应该指定 wxWidgets 类的 C++ 名称,例如 "wxPaintDC""wxFrame"

void* wxLuaState::GetUserDataType(int index, int tag)

index 是您用来访问堆栈中任何其他元素的正常堆栈索引。tag 是从 wxLuaBindClass::class_tag 返回的值(请记住,此成员是指向 int 的指针)GetUserDataType 将返回请求的对象。

在 modules/wxbind/src/*.cpp 文件中有很多关于 wxLua 如何从 Lua 获取和推送到 Lua 的对象的示例,这些文件是从 bindings/wxwidgets/*.i 中的接口文件生成的。这些使用实际的整数变量,如果您包含声明它们的标头或将它们自己声明为 extern 变量,您也可以使用它们。

示例

int Paint(lua_State* L)
{
	wxLuaState wxlState(L);
	wxPaintDC *dc;

	unsigned int tag;
	wxLuaBindClass* wxl_class;

	wxl_class = wxlState.GetLuaClass("wxPaintDC");     // get the WXLUACLASS
	tag = *wxl_class->class_tag;                       // remember to dereference the class_tag member!
	dc = (wxPaintDC*)wxlState.GetUserDataType(1, tag); // get the actual object

	  // ///////////////////////// //
	 //    Paint code goes here   //
	// ///////////////////////// //

	return 0;
}

注释:wxLuaBindClass:在 modules/wxlua/include/wxlbind.h 中定义

讨论

我实际上是在一段时间之前开始研究这个的,当时我使用 wxLua 尝试编写一个快速且肮脏的地图编辑器,并希望确保我可以优化绘制处理程序。我花了一段时间才弄明白,并希望确保它有文档记录,这样其他人想要做同样的事情就不必像我一样深入研究并尝试破译源代码。--Nick

最近更改 · 偏好设置
编辑 · 历史
最后编辑于 2007 年 7 月 26 日凌晨 2:01 GMT (差异)