我从事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 中捕获对未定义函数的调用以引发足够的错误。
其他陷阱
也许还有更多我不知道的陷阱?
最佳答案
要使用 Lua 运行调用 C 函数的脚本,您需要:
- 使用 Lua 协议(protocol)编写每个要导出到 Lua 的 C 函数,以获取参数和返回值。
- 将这些 C 函数作为全局变量或表中的字段导出到 Lua。
- 运行您的用户脚本以捕获语法错误和执行错误, 使用 protected 调用。
- 可选择为用户脚本提供解析全局变量的环境。
C API 提供的函数无需太多工作即可完成所有这些工作。
查看包含在 Lua 源代码中的标准 C 库。从最简单的开始,例如 math
或 os
。
另请阅读本书 Programming in Lua .
关于c - 以防弹方式处理 C 中的 Lua 调用和错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28607878/