如何将C++函数暴露给Lua脚本?

9

我刚刚成功创建了一个lua项目。(目前只是运行一个简单的lua脚本)
现在如何使一个C++函数和一个C++变量对Lua脚本可用呢?

例如:

int Add(int x, int y) {
    return x + y;
}

并且

float myFloatValue = 6.0

我对c++非常陌生,所以希望这不会太复杂。顺便说一下,这是我目前获得的代码:

#include "stdafx.h"
extern "C" {
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
}

using namespace System;

int main(array<System::String ^> ^args)
{
    lua_State* luaInt;
    luaInt = lua_open();
    luaL_openlibs (luaInt);
    luaL_dofile (luaInt, "abc.lua");
    lua_close(luaInt);
    return 0;
}

1
请查看此链接:http://lua-users.org/wiki/BindingCodeToLua。 - user1095108
2个回答

13

从我的经验来看,单独使用Lua很麻烦,因此我赞同John Zwinck的回答。但是,如果你想知道答案,请继续阅读。

要注册C/C++函数,需要先将函数转换为Lua提供的标准C函数格式:

extern "C" int MyFunc(lua_State* L)
{
  int a = lua_tointeger(L, 1); // First argument
  int b = lua_tointeger(L, 2); // Second argument
  int result = a + b;

  lua_pushinteger(L, result);

  return 1; // Count of returned values
}

每个需要在Lua中注册的函数都应该遵循这个模式。返回类型是int,单一参数是lua_State* L。以及返回值数量。

然后,您需要将其注册到Lua的注册表中,以便可以将其公开到脚本的上下文中:

lua_register(L, "MyFunc", MyFunc);

要注册简单变量,您可以编写以下内容:

lua_pushinteger(L, 10);
lua_setglobal(L, "MyVar");

完成上述步骤后,您可以从Lua脚本中调用函数。请注意,在使用注册过的Lua状态运行任何脚本之前,应该先注册所有对象。

Lua中:

print(MyFunc(10, MyVar))

结果:

20


MyFunc 需要加上 extern "C" - Simple
@Simple 是的,我假设Lua已经包含在“extern"C"”中,所以我没有提到它。 - MahanGM
3
这就是为什么MyFunc需要加上extern "C"的原因。 lua_CFunction是一个具有C语言链接的函数指针类型,而MyFunc具有C++语言链接。 标准规定这两种类型是不同的,所以不应该编译(尽管大多数主流编译器错误地接受了它)。 - Simple
非常感谢你的帮助!这太有帮助了。 我想知道为什么会有大约30个警告? http://pastebin.com/KpTYvPDZ - Forivin
@Forivin 你正在使用托管 C++,我认为这就是原因。我没有使用过 C++ CLI,也不知道 Lua 是否与托管 C++ 兼容。创建一个空的 Win32 项目,然后测试你的代码。 - MahanGM
显示剩余2条评论

3

建议使用Luabind而不是使用Lua C API。Luabind是一个相当高级的库,专门将C++类和函数暴露给Lua。无需使用Lua C API函数,无需操作Lua栈等。它受到Boost Python的启发,因此如果您学会了其中一种语言,您基本上也会理解另一种语言。


如果作者不想使用Boost,可以考虑使用LuaBridge(http://vinniefalco.com/LuaBridge/Manual.html)。 - Dmitry Ledentsov
2
@DmitryLedentsov 那个网站现在已经失效了,看起来现在在 https://github.com/vinniefalco/LuaBridge。 - TankorSmash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接