Lua C:我该如何使用Lua源代码创建一个Lua解释器,以便执行给定的Lua代码块?
2019-12-10 18:19:24
收藏:0
阅读:219
评论:2
我想要一个详细的解释。
如何使用 Lua 源代码创建一个 Lua 解释器,可以执行给定的 Lua 代码块?这些 Lua 代码块将以 char
的形式发送。
原文链接 https://stackoverflow.com/questions/4271857
点赞
stackoverflow用户65696
你需要调用 lua_load
来编译代码块,然后调用 lua_call
来运行它。如果想要一个很好的实例来学习如何实现,可以查看这里的示例。
任何 Lua API 函数的第一个参数始终是解释器状态,即 lua_open()
的返回值。
该示例实际上使用 luaL_loadbuffer
来封装对 lua_load
的调用,使 C 字符串的编译变得更容易。您可以在参考手册中的辅助库章节中了解如何使用它。这会在 lua 堆栈的顶部留下一个 lua _chunk_,然后可以用 lua_call
来调用它,但示例使用 lua_pcall
,它提供一些错误处理。由于你刚刚编译的 chunk 不带任何参数(它是一个 chunk 而不是函数)并且没有任何你感兴趣的返回值,而且你想看到完整的错误信息,因此除了第一个参数(始终是 lua 解释器状态)之外的所有参数都可以是零。
2010-11-24 22:02:38
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
调用Lua从C
这篇文档解释了如何在C代码中调用Lua,以及如何将值从Lua传递到C中。
如果您对Lua和C的交互感到困惑或者在忙于写一些需要使用绑定的代码,本文可以为您提供很大的帮助。
这篇文档是关于使用Lua 4.0的,但是随着版本的更新,整体的逻辑并没有变化。
湾区Lua用户组邮件列表中的范例
以下是使用Lua 4.0的范例代码,其中最关键的部分是将信息从Lua堆栈中提取并使用它们。
//Including Lua's sources #include "lua/src/lua.h" #include "lua/src/lualib.h" #include "lua/src/lauxlib.h" int main (void) { lua_State *L = lua_open(); //Load the Lua code chunk into the lua_State struct luaL_loadstring(L, "function testme(x) return x * 2 end"); //Call the function testme with the argument 9 lua_pushnumber(L, 9); lua_call(L, 1, 1); printf("%d ", (int)lua_tonumber(L,-1)); lua_pop(L, 1); /* pop returned value */ lua_close(L); return 0; }
关于c++的同类型事情
以下是一个简单的例子,显示如何将一个table从Lua中传递到C++。
该例子通过在Lua中调用一个函数并将其返回值存储在C++的变量中来展示。
struct LuaRef { lua_State *ref; int stackPos; LuaRef(lua_State *L, int index) : ref(L), stackPos(lua_gettop(L)) { // Push the element at index onto the stack (adds a lua reference) lua_pushvalue(L, index); } // Copy constructor LuaRef(const LuaRef& ref) : ref(ref.ref), stackPos(ref.stackPos) { // Duplicate the stack position to keep this reference alive lua_pushvalue(ref.ref, ref.stackPos); } // Destructor ~LuaRef() { // remove the ref from the stack lua_pop(ref, 1); } // Implicit const char* conversion operator (for getting string references) operator const char* () const { return lua_tostring(ref, stackPos); } // Explicit bool conversion operator (for checking if the reference is not nil) explicit operator bool () const { return !lua_isnil(ref, stackPos); } // Return a reference to a specific field of the table LuaRef operator [] (const char* key) const { // Push the key on the stack followed by the table lua_pushstring(ref, key); lua_gettable(ref, stackPos); return LuaRef(ref, -1); } // Call the Lua function with the provided arguments template<typename ...Args> LuaRef operator () (Args&&... args) const { // Push the function onto the stack lua_pushvalue(ref, stackPos); // Push each argument onto the stack int n = sizeof...(Args); int result = push_args(ref, std::forward<Args>(args)...); if (result != LUA_OK) throw_lua_error(ref, result); // Call the function with the given arguments result = lua_pcall(ref, sizeof...(Args), LUA_MULTRET, 0); if (result != LUA_OK) throw_lua_error(ref, result); // Return a reference to the result(s) return LuaRef(ref, -1); } // Push an object onto the Lua stack template<typename T> void push(T&& value) const { push_value(ref, std::forward<T>(value)); } }; // Custom exception class for Lua errors class LuaError : public std::runtime_error { public: LuaError(const std::string& error = "") : std::runtime_error(error) {} }; // Helper function for pushing arguments onto the stack template<typename T> int push_value(lua_State *L, T&& arg) { stack<T, pusher<T>>::push(L, std::forward<T>(arg)); return 1; } // Specialization for const char* strings template<> int push_value<const char*>(lua_State *L, const char* const &arg) { lua_pushstring(L, arg); return 1; } // Specialization for returning multiple values template<typename ...Args> class stack<return_type<Args...>, returner<Args...>> { public: static return_type<Args...> get(lua_State *L, int index, int& results) { // Push the function arguments onto the stack (and ignore any extra values) int size = push_args(L, std::forward<Args>(Args)..., const char*()); index -= size; // Call the function with the given arguments int result = lua_pcall(L, size, LUA_MULTRET, 0); if (result != LUA_OK) throw_lua_error(L, result); // Retrieve the results from the Lua stack results = lua_gettop(L) - index + 1; return get_return_values<return_type<Args...>>::get(L, index, results); } }; // Main application loop int main() { try { // Start the LuaVM lua_State* L = luaL_newstate(); luaL_openlibs(L); // Load the script luaL_dostring(L, R"( function createTable() return { name = "Bob", age = 30, occupation = "plumber", } end )"); // Call the Lua function and store the result as a LuaRef LuaRef table = LuaRef(L)()["createTable"](); // Get the contents of the table (by key) and print them to the console std::cout << "Name: " << table["name"] << ", Age: " << table["age"] << ", Occupation: " << table["occupation"] << std::endl; } catch (const std::exception &e) { // Handle any Lua errors (syntax errors, runtime exceptions, etc.) std::cerr << "Error: " << e.what() << std::endl; } return 0; }
在这个例子中,我们向Lua注册了一个函数,返回一个名为“ Bob”的对象。
C++代码使用LuaRef结构来获取该对象并输出其内容。