如何在Lua中注册C++函数?

我正在尝试在Lua中注册一个C++函数。

但是出现了以下错误:

CScript.cpp|39|error: argument of type 'int (CScript::)(lua_State*)' does not match 'int (*)(lua_State*)'|

编辑:

int CApp::SetDisplayMode(int Width, int Height, int Depth)
{
    this->Screen_Width = Width;
    this->Screen_Height = Height;
    this->Screen_Depth = Depth;

    return 0;
}

int CScript::Lua_SetDisplayMode(lua_State* L)
{
  // 我们至少需要一个参数
  int n = lua_gettop(L);
  if(n < 0)
  {
    lua_pushstring(L, "Not enough parameter.");
    lua_error(L);
  }

  int width = lua_tointeger(L, 1);
  int height = lua_tointeger(L, 2);
  int depth = lua_tointeger(L, 3);

  lua_pushinteger(L, App->SetDisplayMode(width, height, depth));

  return 0;
}

在主程序中:

lua_register(L, "setDisplayMode", Lua_SetDisplayMode);
点赞
用户440558
用户440558

你不能将类的方法用作普通函数,除非它被声明为 static。你必须定义一个普通函数,找出你想要调用该方法的对象,然后调用这个方法。

无法将类方法作为 C 函数的回调使用的主要原因(记住 Lua API 是一个纯 C 库),是因为计算机不知道应该在哪个对象上调用该方法。

2011-11-11 14:05:55
用户264712
用户264712

你可以通过将活动的this指针存储在静态变量中来避免这个限制。这引入了一个问题,即无法同时运行两个这样的类,但它是有效的。

static CScript *luaThis; // 这是CScript内的私有变量。

然后,在你的CScript构造函数(或某种“激活”函数)中,你可以指定:

luaThis = this; 

然后,当调用静态函数时(甚至如果它们是从类内部注册的私有函数),你可以通过luaThis指针访问所有成员信息。

如果你需要多个活动实例,你可以使用传入的 `lua_State*`作为键来构建一些查找机制。

std :: map <lua_State*, CScript*> lookups; // 这只是一个想法,如果需要。

```

希望这能帮到你!

2011-11-11 15:34:57
用户734069
用户734069

你不能仅仅使用基本的 Lua C API 直接注册 C++ 非静态成员函数到 Lua 中。

然而,各种现存的机制可以很容易地使 C++ 代码和 Lua 结合在一起从而实现此功能,例如 toLua++SWIGLuabind 等等。如果你像我一样想要充分利用 C++ 对象在 Lua 中的优势,建议选择其中之一并使用它,而不是编写自己的版本。我个人大多使用 Luabind(当然,SWIG 也有它的用武之地),因为它是不需要进行某种形式的代码生成的。所有操作都是在 C++ 中完成,因此没有预处理步骤生成 C++ 源文件。

2011-11-11 18:39:53
用户599192
用户599192

答案实际上非常简单;如果您使用 lua_pushcclosure 而不是 lua_pushcfunction,则可以将参数传递给被调用的函数:

lua_pushlightuserdata(_state, this);
lua_pushcclosure(_state, &MyClass::lua_static_helper, 1);

int MyClass::lua_static_helper(lua_State *state) {
    MyClass *klass = (MyClass *) lua_touserdata(state, lua_upvalueindex(1));
    return klass->lua_member_method(state);
}
2014-01-24 06:50:18