C++ lua桥接存在函数指针问题。

我正在尝试创建一个简单的 C++ 包装器,用于 *lua_CFunction*,它的定义如下:

// header
typedef int (*lua_CFunction) (lua_State* lua);
...
lua_CFunction wrap (std::function <int (Game* game)> function);
// implementation
lua_CFunction ScriptingInterface::wrap (std::function <int (Game* game)> function)
{
    return [this, function] (lua_State* unused) -> int {
        int n_args = function (this->game);
        return n_args;
    };
}
void ScriptingInterface::registerFunction (std::string name, std::function <int (Game* game)> function)
{
    lua_register (lua, name.c_str (), wrap (function));
}

想法是创建像这样的公共函数:

int setTitle (Game* interface)
{
    const char* title = lua_tostring (interface->getScripts ()->getLuaState (), 1);

    SDL_WM_SetCaption (title, NULL);

    return 0;
}

然后像这样与 lua 共享它们:

scripts->registerFunction ("setTitle", setTitle);

scriptsScriptingInterface 的一个实例。

问题在于尝试编译游戏时出现了问题。

./scripting/scripting_interface.cc: In member functionint (* ScriptingInterface::wrap(std::function<int(Game*)>))(lua_State*)’:
./scripting/scripting_interface.cc:40:2: error: cannot convert ‘ScriptingInterface::wrap(std::function<int(Game*)>)::<lambda(lua_State*)>’ to ‘int (*)(lua_State*)’ in return
./scripting/scripting_interface.cc:41:1: warning: control reaches end of non-void function [-Wreturn-type]

有人可以告诉我这里出了什么问题吗?因为据我所知,该代码应该没有任何问题可以编译。

点赞
用户1932150
用户1932150

问题出在这里:

lua_CFunction ScriptingInterface::wrap(std::function<int(Game*)> function)
{
    return [this, function] (lua_State* unused) -> int {
        int n_args = function (this->game);
        return n_args;
    };
}

你试图返回一个 lambda 表达式,但是函数指针期望的是一个函数指针,而一个含有捕获的 lambda 表达式是不能转化成函数指针的,因为该 lambda 表达式同时捕获 thisfunction。根据 C++11 标准的第5.1.2/6段:

如果一个 lambda 表达式没有 lambda-capture,则该闭包类型具有一个公有的非虚拟的非显式转换函数,将其转换为具有与该闭包类型的函数调用运算符相同的参数和返回类型的函数指针。此转换函数返回的值应该是一个函数的地址,当调用时与调用闭包类型的函数调用运算符具有相同的效果。

不幸的是,除非您可以返回一个 std::function<int(lua_State*)>,否则您必须改变您的设计。

2013-04-07 10:06:50