luabind:如何通过引用将值从C++传递给lua函数
luabind: How to pass value from C++ to lua function by reference?
在C++上编程时,可以执行以下操作:
void byReference(int &y)
{
y = 5;
}
int main()
{
int x = 2; // x = 2
byReference(x); // x = 5
}
如何使用luabind进行同样的操作?
Luabind医生说:
如果要将参数作为引用传递,则必须对其进行包装与CCD_ 1。
像这样:
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 <luabindluabind.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.loa
function test(x)
x = 7
end
我的程序在运行时崩溃,出现以下错误:
LuaScripting.exe
中0x76B5C42D
处的未处理异常:MicrosoftC++异常:内存位置0x0017F61C
处的std::runtime_error
。
那么,如何通过引用将值从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&")
];
CCD_ 10错误消失。但是在Boost.Ref
2中调用print(x)
仍然会导致"lua runtime error"
,并且程序仍然不能执行我想从中执行的操作。
我已经设法让这件事成功了。嗯,与问题中的不完全一样:我传递了自定义类型GameObject
,而不是int
。
但由于某些原因,我仍然无法使它与int
、float
等简单类型一起工作。
所以,首先我决定自己构建luabid和lua,只是为了确保它们能在VS2012中工作。我遵循了这个问题的指示。
然后我写了这个测试程序:
#include <iostream>
#include <conio.h>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <luabindluabind.hpp>
#include <luabindadopt_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;
}
script.loa:
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++方面是透明的。不过,这将对卢阿方面施加严格限制链接:http://sourceforge.net/p/luabind/mailman/message/32692053/
在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将成为参考,这取决于你想要实现的目标。:(
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗