luabind:如何从C++;通过引用来定义函数? C++编程时,可以做到以下几点: void byReference(int &y) { y = 5; } int main() { int x = 2; // x = 2 byReference(x); // x = 5 }

luabind:如何从C++;通过引用来定义函数? C++编程时,可以做到以下几点: void byReference(int &y) { y = 5; } int main() { int x = 2; // x = 2 byReference(x); // x = 5 },c++,boost,lua,pass-by-reference,luabind,C++,Boost,Lua,Pass By Reference,Luabind,如何使用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" #in

如何使用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);
}
我的程序在运行时崩溃,出现以下错误:

LuaScripting.exe
中的
0x76B5C42D
处出现未处理的异常:Microsoft C++异常:<代码> STD::运行时错误<代码>内存位置>代码> 0x00 17F61C < /代码> ./P> <> P>如何通过引用将C++的值传递给Lua函数,这样我就可以在脚本内部改变它,并且在C++程序中也会改变它。我用的是Boost1.55.0,Lua5.1,Luabind0.9.1

编辑:

当我试图抓住

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

“尝试使用未注册的类”
错误消失。但是在
test()
中调用
print(x)
,仍然会导致
“lua运行时错误”
,并且程序仍然没有执行我希望它执行的操作。

我已经设法使这件事正常工作。嗯,与问题中的情况不完全一样:我传递了我的自定义类型
GameObject
,而不是
int

但由于某些原因,我仍然无法使它与简单类型(如
int
float
等)一起工作。

所以,首先我决定自己构建luabind和lua,只是为了确保它们在VS2012中能够正常工作。我按照这本书的指示去做

然后我编写了这个测试程序:

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

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

#include <luabind\luabind.hpp>
#include <luabind\adopt_policy.hpp>

using namespace std;
using namespace luabind;

struct Vector2
{
    float x, y;
};

class Transform
{
public:
    Transform()
    {
        pos.x = 0;
        pos.y = 0;
    }

public:
    Vector2 pos;
};

class Movement
{
public:
    Movement(){}

public:
    Vector2 vel;
};

class GameObject
{
public:
    GameObject(){}

    Transform& getTransform()
    {
        return _transform;
    }

    Movement& getMovement()
    {
        return _movement;
    }

private:
    Transform _transform;
    Movement  _movement;
};

int main()
{
    lua_State *myLuaState = luaL_newstate();

    open(myLuaState);

    module(myLuaState) [
      class_<Vector2>("Vector2")
          .def(constructor<>())
          .def_readwrite("x", &Vector2::x)
          .def_readwrite("y", &Vector2::y),

      class_<Transform>("Transform")
          .def(constructor<>())
          .def_readwrite("pos", &Transform::pos),

      class_<Movement>("Movement")
          .def(constructor<>())
          .def_readwrite("vel", &Movement::vel),

      class_<GameObject>("GameObject")
          .def(constructor<>())
          .def("getTransform", &GameObject::getTransform)
          .def("getMovement", &GameObject::getMovement)
    ];

    GameObject _testGO;

    _testGO.getMovement().vel.x = 2;
    _testGO.getMovement().vel.y = 3;

    do
    {
        cout<<"_testGO.pos.x before = "<< _testGO.getTransform().pos.x <<endl;
        cout<<"_testGO.pos.y before = "<< _testGO.getTransform().pos.y <<endl;

        try 
        {
            luaL_dofile(myLuaState, "script.lua");

            call_function<void>(myLuaState, "testParams", boost::ref(_testGO), 0.3);
        }
        catch(const exception &TheError)
        {
            cerr << TheError.what() << endl;
        }

        cout<<"_testGO.pos.x after = "<< _testGO.getTransform().pos.x <<endl;
        cout<<"_testGO.pos.y after = "<< _testGO.getTransform().pos.y <<endl;
    }
    while(_getch() != 27);

    lua_close(myLuaState);

    return 0;
}
它成功了:

_testGO.pos.x before = 0
_testGO.pos.y before = 0
_testGO.pos.x after = 0.6
_testGO.pos.y after = 0.9
将尝试找出如何管理简单类型

更新:

这是同一个问题的答案,我在luabind邮件列表上看到:

'不可能通过引用传递在lua中使用内置类型建模的对象类型。在Lua中,不存在引用或值类型等类型的属性。类型可以是引用类型(表),也可以是值类型(内置类型,如number)。
但是,您可以做的是在lua端返回新值。可以建立一种策略,将引用的积分类型转换为解析的返回类型列表,因此在C++方面是透明的。不过,这会在lua端设置硬约束。“link:

通常在lua中,如果您想模拟引用变量/表,则需要将其声明为全局变量,然后在函数中使用它

-- global table t
t = {}
-- insert the value of val into t by index or by property
-- aGenericFunction1(val[, property])
function aGenericFunction1(val, property)
   if property then
       t[property] = val
   else
       table.insert(t, val)
   end
end
这不完全是一回事,但只是一个简单的解决办法

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

Example:
    aGenericFunction1("Barks!", "dog")
    print(t.dog)
    -- prints Barks!
同样的事情也可以在变量中实现

-- global variable x
x = 0
-- insert the value of val into x
function aGenericFunction2(val)
   x = val
end
同样,每次调用
aGenericFunction2
它都会覆盖x

 Example:
     aGenericFunction2(4)
     print(x)
     -- prints 4

因此,本质上,t或x将成为参考,具体取决于您想要完成的任务。:)

在这里做什么:
调用函数
?它是一个模板函数:
模板Ret调用函数(lua\u State*L,const char*name,…)
你必须指定返回类型如果你在test()中打印x并尝试在没有ref()的情况下调用它怎么办?@JohnZwinck
函数测试(x)
x=7
打印(x)
end
它给了我“lua运行时错误”。奇怪的是,我没有使用luabind,但通过引用传递参数似乎与Lua的设计相反。Lua按值传递参数(like);值是基本体或引用。即使我能做到,我也不会做。你的工作方案更自然。
Example:
    aGenericFunction1("Barks!", "dog")
    print(t.dog)
    -- prints Barks!
-- global variable x
x = 0
-- insert the value of val into x
function aGenericFunction2(val)
   x = val
end
 Example:
     aGenericFunction2(4)
     print(x)
     -- prints 4