跳转至

Lua export

C++对象导出

1. 基础类型导出

// 辅助函数
UINT rgb(int r, int g, int b)
{
    return RGBA(r,g,b,255);
}

BOOL ExpLua_Basic(lua_State *L)
{
    try {
        // 导出全局函数
        lua_tinker::def(L, "RGB", rgb);

        // 导出基本结构体
        lua_tinker::class_add<POINT>(L, "POINT");
        lua_tinker::class_mem<POINT>(L, "x", &POINT::x);
        lua_tinker::class_mem<POINT>(L, "y", &POINT::y);

        // 导出CRect类
        lua_tinker::class_add<CRect>(L, "CRect");
        lua_tinker::class_inh<CRect, RECT>(L);
        lua_tinker::class_con<CRect>(L,
            lua_tinker::constructor<CRect,LONG,LONG,LONG,LONG>);
        lua_tinker::class_def<CRect>(L, "Width", &CRect::Width);

        return TRUE;
    } catch(...) {
        return FALSE;
    }
}

2. 窗口对象导出

// SWindow对象导出
BOOL ExpLua_Window(lua_State *L)
{
    try {
        // 导出类
        lua_tinker::class_add<SWindow>(L, "SWindow");
        lua_tinker::class_inh<SWindow, SObject>(L);

        // 导出构造函数
        lua_tinker::class_con<SWindow>(L,
            lua_tinker::constructor<SWindow>);

        // 导出成员函数
        lua_tinker::class_def<SWindow>(L, "GetParent",
            &SWindow::GetParent);
        lua_tinker::class_def<SWindow>(L, "FindChildByID",
            &SWindow::FindChildByID);

        return TRUE;
    } catch(...) {
        return FALSE;
    }
}

3. 静态成员导出

BOOL ExpLua_App(lua_State *L)
{
    try {
        // 导出应用程序类
        lua_tinker::class_add<SApplication>(L, "SApplication");

        // 导出静态函数(作为全局函数)
        lua_tinker::def(L, "theApp",
            &SApplication::getSingletonPtr);

        return TRUE;
    } catch(...) {
        return FALSE;
    }
}

在Lua中使用C++对象

1. 基本使用

-- 创建对象
local rect = CRect(0, 0, 100, 100)

-- 访问成员变量
local left = rect.left
local top = rect.top

-- 调用成员函数
local width = rect:Width()
local height = rect:Height()

2. 窗口操作

-- 获取窗口对象
local win = toSWindow(args.sender)

-- 查找子窗口
local child = win:FindChildByNameA("button1", -1)

-- 设置属性
child:SetVisible(1, 1)
child:EnableWindow(1, 1)

-- 获取窗口属性
local text = child:GetWindowText()
local rect = child:GetWindowRect2()

3. 注意事项

  1. 多继承限制

    // 只能导出第一个基类
    class SWindow : public SObject, public IWindow // 其他基类
    {
        // 只能导出SObject
        lua_tinker::class_inh<SWindow, SObject>(L);
    };
    

  2. 静态成员访问

    -- 静态函数作为全局函数访问
    local app = theApp()  -- 而不是 SApplication.getSingletonPtr()
    

  3. 内存管理

    -- C++对象的生命周期由C++管理
    local win = ... -- 获取窗口对象
    -- 不需要手动释放win
    

高级用法

1. 类型转换

-- 基础对象转换
local win = toSWindow(args.sender)
local host = toHostWnd(win:GetTopLevelParent())

-- 安全检查
if win then
    -- 使用对象
end

2. 事件处理

-- 事件回调函数
function on_button_click(args)
    local sender = toSWindow(args.sender)
    -- 处理点击事件
    return 1
end

-- 订阅事件
win:GetScriptModule():subscribeEvent(button, 
    EVT_CMD, "on_button_click")

3. 自定义类导出

// C++代码
class MyClass
{
public:
    void MyMethod() { /* ... */ }
};

// 导出代码
BOOL ExpLua_MyClass(lua_State *L)
{
    lua_tinker::class_add<MyClass>(L, "MyClass");
    lua_tinker::class_def<MyClass>(L, "MyMethod",
        &MyClass::MyMethod);
    return TRUE;
}
-- Lua使用
local obj = MyClass()
obj:MyMethod()

调试技巧

1. 脚本调试

-- 添加调试信息
function debug_info(...)
    print(string.format(...))
end

-- 检查对象
function check_object(obj)
    if not obj then
        debug_info("对象为空")
        return false
    end
    return true
end

2. 错误处理

-- 安全调用
function safe_call(func, ...)
    local status, result = pcall(func, ...)
    if not status then
        debug_info("错误: %s", result)
        return nil
    end
    return result
end

3. 性能优化

-- 缓存频繁使用的对象
local cached_objects = {}

function get_object(name)
    if not cached_objects[name] then
        cached_objects[name] = find_object(name)
    end
    return cached_objects[name]
end

最佳实践

1. 模块化

-- config.lua
local config = {
    VERSION = "1.0",
    DEBUG = true
}
return config

-- ui.lua
local ui = {
    init = function()
        -- UI初始化
    end
}
return ui

-- main.lua
local config = require "config"
local ui = require "ui"

2. 命名规范

-- 常量使用大写
local MAX_COUNT = 100

-- 函数使用动词前缀
function create_window()
end

function update_ui()
end

-- 私有函数使用下划线前缀
local function _internal_function()
end

3. 代码组织

-- 相关功能放在同一个table中
local window_manager = {
    windows = {},

    create = function(name)
        -- 创建窗口
    end,

    destroy = function(name)
        -- 销毁窗口
    end
}

-- 使用
window_manager.create("main")