luabind:如何通过引用从C++传递值到lua函数?

在使用 C++ 编程时,您可以进行以下操作:

void byReference(int &y)
{
    y = 5;
}

int main()
{
   int x = 2;      // x = 2
   byReference(x); // x = 5
}

如何使用 luabind 实现相同的效果?

Luabind 文档 说道

如果要将参数作为引用传递,则必须使用 Boost.Ref 封装它。

示例如下:

int ret = call_function(L, "fun", boost::ref(val));

但是当我尝试执行以下操作时:

#include <iostream>
#include <conio.h>

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

#include <luabind\luabind.hpp>

using namespace std;
using namespace luabind;

int main()
{
  lua_State *myLuaState = luaL_newstate();
  open(myLuaState);
  int x = 2;
  do
  {
    luaL_dofile(myLuaState, "script.lua");
    cout<<"x before = "<< x <<endl;
    call_function<void>(myLuaState, "test", boost::ref(x));
    cout<<"x after = "<< x <<endl;
  } while(_getch() != 27);
  lua_close(myLuaState);
}

script.lua

function test(x)
    x = 7
end

我的程序在运行时崩溃,显示以下错误:

位于 0x76B5C42D 处的未处理异常,位于 LuaScripting.exe 中:Microsoft C++ 异常:std::runtime_error,内存位置为 0x0017F61C

那么,如何通过引用从 C++ 传递值到 lua 函数,以便我可以在脚本中更改它,程序中也会发生更改?我使用的是 boost 1.55.0,lua 5.1,luabind 0.9.1

编辑:

当我使用 try-catch 捕获时:

try {
call_function<void>(myLuaState, "test", boost::ref(x));
}catch(const std::exception &TheError) {
cerr << TheError.what() << endl;

它给出了一个 "Trying to use unregistered class" 错误。

编辑2:

经过一番调查,我发现 "Trying to use unregistered class" 错误是由 boost::ref(x) 引起的。我注册了一个 int& 类(猜测):

  module(myLuaState)
      [
          class_<int&>("int&")
      ];

"Trying to use unregistered class" 错误消失了。但在 test() 中调用 print(x) 仍然导致 "lua runtime error",而程序仍然不能按照我所要求的那样运行。

点赞
用户6672727
用户6672727

在 Lua 中,如果要模拟引用变量/表,通常会将其声明为全局变量,然后在函数中使用。

-- 全局表 t
t = {}
-- 按索引或属性将 val 的值插入 t 中
-- 一个泛型函数 aGenericFunction1(val[, property])
function aGenericFunction1(val, property)
   if property then
       t[property] = val
   else
       table.insert(t, val)
   end
end

这不完全相同,但是它是一个简单的解决方法。

现在每次调用 aGenericFunction1 都会按属性或索引更新 t 表。

例如:
    aGenericFunction1("Barks!", "dog")
    print(t.dog)
    -- 输出 Barks!

同样的方式也适用于变量...

-- 全局变量 x
x = 0
-- 将 val 的值插入 x 中
function aGenericFunction2(val)
   x = val
end

同样的方式,每次调用 aGenericFunction2 都会覆盖 x。

例如:
     aGenericFunction2(4)
     print(x)
     -- 输出 4

因此,本质上 t 或 x 都将成为引用,具体取决于你想要实现的目标。 :)

2016-08-20 19:47:33