gpt4 book ai didi

c++ - luabind:如何通过引用将值从 C++ 传递给 lua 函数?

转载 作者:搜寻专家 更新时间:2023-10-31 01:43:28 25 4
gpt4 key购买 nike

在 C++ 上编程时,您可以执行以下操作:

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

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

如何使用 luabind 做同样的事情?

Luabind 文档 says :

If you want to pass a parameter as a reference, you have to wrap it with the Boost.Ref.

Like this:

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);
}

脚本.lua

function test(x)
x = 7
end

我的程序在运行时崩溃并出现以下错误:

Unhandled exception at at 0x76B5C42D in LuaScripting.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0017F61C.

那么,如何通过引用将值从 C++ 传递给 lua 函数,这样我就可以在脚本中更改它,它也会在 C++ 程序中更改?我正在使用 boost 1.55.0、lua 5.1、luabind 0.9.1

编辑:

当我尝试捕捉时

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”,并且程序仍然没有执行我想要的操作做。

最佳答案

我已经设法让这件事成功了。好吧,与问题中的不完全相同:我传递了自定义类型 GameObject 而不是 int

但出于某种原因,我仍然无法使用简单类型,如 intfloat 等。

所以,首先我决定自己构建 luabind 和 lua,只是为了确保它们可以在 VS2012 中工作。我按照此 question 中的说明进行操作.

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

#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;
}

脚本.lua:

function testParams(owner, dt)
owner:getTransform().pos.x = owner:getMovement().vel.x * dt;
owner:getTransform().pos.y = owner:getMovement().vel.y * dt;
end

成功了:

_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 中,不存在引用或值类型等类型的属性。类型要么是引用类型(表),要么是值类型(内置类型,如数字)。但是,您可以做的是在 lua 端返回新值。可以建立一个策略,将引用整数类型转换为已解析的返回类型列表,因此它在 C++ 端是透明的。不过,这会给 lua 方面带来严格的限制。” 链接:http://sourceforge.net/p/luabind/mailman/message/32692053/

关于c++ - luabind:如何通过引用将值从 C++ 传递给 lua 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25099437/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com