以最可靠的方式在C中处理Lua调用和错误

我在 Lua 电子设备模拟插件上工作。

我希望设计和可用性都很好,因为很多用户可能远离 IT 和调试。

用户用 Lua 描述设备,插件通过 Lua C API 将其转换。

用户可能拼错函数名、变量类型和参数顺序。

好的手册很有帮助,但应用程序不应崩溃或提供坏的描述错误。我没有找到任何“最佳实践”,想请教经验丰富的用户,因为我对 Lua 还很新。

参数顺序和类型

目前,Lua 函数声明如下:

typedef struct lua_bind_func
{
    int32_t ( *lua_c_api ) ( lua_State* );
    const char* lua_func_name;
} lua_bind_func;

然后

{.lua_func_name="state_to_string", .lua_c_api=&lua_state_to_string},

为了检查是否正确传递了参数顺序和类型:

创建宏:

#define STRING (&lua_isstring)
#define INT (&lua_isinteger)
#define USER (&lua_islightuserdata)

将一个数组添加到列表中:

int ( *args[16] ) ( lua_State*, int index );

更改函数列表:

{.lua_func_name="set_callback", .lua_c_api=&lua_set_callback, .args={INT, INT}}

参数列表检查器:

static void
SAFE_EXECUTE ( lua_State* L, void* curfunc )
{
    int argnum = lua_gettop ( L );
    for ( int i=0; lua_c_api_list[i].lua_func_name; i++ )
    {
        if ( curfunc == lua_c_api_list[i].lua_c_api )
        {
            for ( int argcount=0; lua_c_api_list[i].args[argcount]; argcount++ )
            {
                if ( argnum < argcount+1 )
                {
                    IDSIMMODEL* model = ( IDSIMMODEL* ) lua_get_model_obj ( L );
                    print_error ( model, "Too few arguments passed to the function \"%s\"", lua_c_api_list[i].lua_func_name );
                }
                else if ( !lua_c_api_list[i].args[argcount] ( L, argcount+1 ) )
                {
                    IDSIMMODEL* model = ( IDSIMMODEL* ) lua_get_model_obj ( L );
                    print_error ( model, "Argument %d is of wrong type", argcount+1 );
                }
            }
        }
    }
}

然后我可以检查参数顺序、类型,并创建相应的错误消息以及小型帮助:

SAFE_EXECUTE ( L, &lua_set_callback );

代码还没有处理额外的参数,但很容易添加。

问题:这是一个好的方案,还是有更好的方案?

拼错函数名

例如,我有以下代码:

set_callback(time + 100 * MSEC, PC_EVENT)
set_calback(time + 200 * MSEC, PC_EVENT)
set_callback(time + 333 * MSEC, PC_EVENT)

第二个是错误拼写的,之后这部分代码不执行。

我不知道如何捕捉 C 中未定义功能的调用,以便引发充分的错误。

其他陷阱

也许还有更多我不知道的可能的陷阱?

点赞
用户107090
用户107090

要使用Lua运行调用C函数的脚本,您需要:

  • 使用Lua协议编写要导出到Lua的每个C函数,以获取参数和返回值。
  • 将这些C函数作为全局变量或表字段导出到Lua中。
  • 使用受保护的调用运行您的用户脚本,捕获语法错误和执行错误。
  • 可选地为用户脚本提供环境以解析全局变量。

C API提供了函数来完成这一切,而不需要太多工作。

请参阅包含在Lua源代码中的标准C库。从最简单的库开始,比如mathos

还请阅读书籍《Lua编程》

2015-02-19 22:41:47