而不是在 lua 中创建一个对象,如何让 lua 直接高C++对象来启动方法?
Rather then create a object in lua, how let lua directly tall the C++ object to launch a method?
我正在使用Luabind。
我的标题可能有点不清楚,我会尽力解释我想问的问题。
我的问题是:
我如何直接高C++对象的方法可以访问对象的值(尤其是指针),而不是在 Luabid 中创建另一个对象。
如果你不知道我在问什么,你可以继续阅读。
例如,我有三个类:Main
、Test_Stage
、Test_Class
Lua 仅在Test_class
中创建。
我有一个变量x
,仅用于测试目的。它由其构造函数从Main
一直传递到Test_Stage
再到Test_Class
。这样Test_Class
和Test_Stage
都具有全局价值,当我实际制作游戏时,我需要这个价值。
更重要的是Test_Class
持有Test_Stage
指针,这样我就可以做create_a_bullet
或create_damage
之类的事情。
从本教程中学到的,我试图使Test_Class
中创建的luaobject
调用该方法shoot_a_bullet
该方法将高"Test_Stage"对象打印"运行"<<"全局值"。而且C++没有语法错误,IT 部门没有打印任何内容。我该如何解决这个问题?
代码在这里(实际上我在使用包括使用类在内的转发方面遇到了麻烦,所以"运行"<<x 在Test_Class
中。至少我可以测试它是否会读取此处传递的全局值。
编辑:在几个小时无所事事之后,我遇到了另一种解决方案。有没有办法传递可以在 lua 中创建的对象中使用的指针,或者在构造函数中使用?
代码(如果您来回答问题,您可能会考虑跳过主要和Test_Stage:
主文件启动程序:
#include <iostream>
#include "test_stage.h"
using namespace std;
int x;
int main() {
cin >> x;
Test_Stage stage = Test_Stage(x);
}
和Test_Stage
的标题:
#ifndef TEST_STAGE_H
#define TEST_STAGE_H
#include <iostream>
class Test_Class;// to avoid circular include error, i used forward referancing
// i will include the file in the CPP file
// a class Test_Class which define the class is enough in header
using namespace std;
class Test_Stage
{
public:
int x;
Test_Stage(int num);
void create_bullet(int damage, string name, int x); /*This is currently useless
before i have understand how to include each other using foward referance*/
void create_class(int num);
Test_Class t_class;
~Test_Stage();
private:
};
#endif
Test_Stage的 cpp 文件:
#include"test_stage.h"
#include "test_class.h"// and as you see i included both files(i just learned it few secs ago)
Test_Stage::Test_Stage()
{
}
Test_Stage::Test_Stage(int num)
{
create_class(num);
}
void Test_Stage::create_bullet(int damage, string name, int x)
{
cout << "created damage: " << damage << "to" << x ;
}
void Test_Stage::create_class(int num)
{
Test_Class t_class = Test_Class(num, this);
}
Test_Stage::~Test_Stage()
{
}
Test_Class的标头:
#ifndef TEST_CLASS_H
#define TEST_CLASS_H
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include ".luabindluabind.hpp"
#include <iostream>
using namespace std;
class Test_Stage;
class Test_Class
{
public:
int x;
Test_Class();
Test_Class(int num, Test_Stage* stage);
void shoot_a_bullet(Test_Class* o, int damage);
Test_Stage *stage;
~Test_Class();
private:
};
#endif TEST_CLASS_H
最后是Test_Class的cpp(给我带来了很多麻烦):
#include "test_class.h"
#include"test_stage.h"
void Test_Class::shoot_a_bullet(Test_Class* o, int damage)
{
cout << "Runned";
stage->create_bullet(damage, "wowo", x);
}
Test_Class::Test_Class()
{
}
Test_Class::Test_Class(int num, Test_Stage* stg)
{
stage = stg;
x = num;
// Create a new lua state
lua_State *myLuaState = luaL_newstate();
// Connect LuaBind to this lua state
luabind::open(myLuaState);
luaL_openlibs(myLuaState);
luabind::module(myLuaState)[
luabind::class_<Test_Class>("Test_Class")
.def("shoot_a_bullet", &Test_Class::shoot_a_bullet)
];
/*followed the tutorial codes
class_<A>("A")
.def("plus", &plus)*/
cout << "im here";//just to check how far did the program go
luaL_dostring(
myLuaState,
"shoot_a_bullet(134)n"
);
cout << "I passed it";
cin.get();
cin.get();//To pause the program before it closes
// if you have the time, can you also explain
// why do i need two cin.get() to pause the program.
}
Test_Class::~Test_Class()
{
}
经过大量的研究,我终于找到了一个解决方案,尽管我不确定它的效率如何,但它实际上正在按照我想要的方式工作。
所以最终的解决方案是,注册一个从我需要的指针转换为lua的intptr_t
,(有关intptr_t
的更多信息,请单击此处(主要出于安全原因,您可以将其视为一种仅用于指针的int设计))并在我使用它时将其传递给静态函数
以下是修改后的代码:
在Test_Class.cpp
,之后:
luabind::module(myLuaState)[
.def("shoot_a_bullet", &shoot_a_bullet)
];// since the functions are static now it will not need the namespace
我已经注册了指针的intptr_t
版本:
//first convert pointer to intptr_t
intptr_t stage = (intptr_t)stg;//stg is the pointer
//then register it to lua
//if you try to register a pointer it will give you runtime error
luabind::globals(myLuaState)["stage"] = stage;
我们还需要稍微改变一下函数:首先,我们需要让函数静态,所以在头文件中:
//change the line defined the function to
void static shoot_a_bullet(intptr_t stg, int damage);
现在我们必须用它自己的函数做一些事情:
void Test_Class::shoot_a_bullet(intptr_t stg, int damage)
{
//we need to convert it back to pointer first, so
Test_Stage* stage = (Test_Stage*)stg;//this is the part I'm not sure about efficiency
stage->create_bullet(damage, "wowo");
}
所以现在使用 lua 的代码将非常简单: shoot_a_bullet(舞台,134);
我们完成了!生活是美好的!这些东西花了我 3 周的时间。
你可能不明白我说的话,这是我写的完整测试代码:
main
.cpp:
#include <iostream>
#include "test_stage.h"
using namespace std;
int x;
int main() {
cin >> x;
cin.get();// clean the n(when you press enter) after the number
Test_Stage stage = Test_Stage(x);
}
Test_Stage
.h:
class Test_Class;
#ifndef TEST_STAGE_H
#define TEST_STAGE_H
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include ".luabindluabind.hpp"
#include <iostream>
#include "test_class.h"
using namespace std;
class Test_Stage
{
public:
int x;
Test_Stage();
Test_Stage(int num);
void create_bullet(int damage, string name); /*This is currently useless
before i have understand how to include each other using foward referance*/
void create_class(int num);
Test_Class t_class;
~Test_Stage();
private:
};
#endif
Test_Stage
CPP:
#include"test_stage.h"
#include "test_class.h"// and as you see i included both files
Test_Stage::Test_Stage()
{
}
Test_Stage::Test_Stage(int num)
{
x = num;// a variable specific in this object(to test pointer)
create_class(num);
}
void Test_Stage::create_bullet(int damage, string name)
{
cout << "created damage: " << damage << " to " << x << endl;/*using the value
created in this object to see if pointer is actually working*/
}
void Test_Stage::create_class(int num)
{
Test_Class t_class = Test_Class(this, num);
}
Test_Stage::~Test_Stage()
{
}
Test_Class
.h:
#ifndef TEST_CLASS_H
#define TEST_CLASS_H
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include ".luabindluabind.hpp"
#include <iostream>
using namespace std;
class Test_Stage;
class Test_Class
{
public:
int x;
Test_Class();
Test_Class(Test_Stage* stage, int num);
void static shoot_a_bullet(intptr_t stg, int damage);
~Test_Class();
private:
};
#endif TEST_CLASS_H
最后,Test_Class
.cpp:
#include "test_class.h"
#include"test_stage.h"
void Test_Class::shoot_a_bullet(intptr_t stg, int damage)
{
Test_Stage* stage = (Test_Stage*)stg; // intptr_t back to pointer
stage->create_bullet(damage, "wowo"); // use pointer
}
Test_Class::Test_Class()
{
}
Test_Class::Test_Class(Test_Stage* stg, int num)
{
intptr_t stage = (intptr_t)stg;
// Create a new lua state
lua_State *myLuaState = luaL_newstate();
// Connect LuaBind to this lua state
luabind::open(myLuaState);
luaL_openlibs(myLuaState);
luabind::module(myLuaState)[
luabind::def("shoot_a_bullet", &shoot_a_bullet)//again this is static now
];
luabind::globals(myLuaState)["stage"] = stage;
cout << "I'm here " << endl;//just to check how far did the program go
luaL_dostring(
myLuaState,
"shoot_a_bullet(stage, 134)n"
);
cout << "I passed it"<< endl;
cin.get();
}
Test_Class::~Test_Class()
{
}
玩得愉快!
我知道这很晚了,但你为什么不简单地这样做
luabind::module(myLuaState)[
luabind::class_<Test_Class>("Test_Class")
.def("shoot_a_bullet", &Test_Class::shoot_a_bullet)
];
luabind::globals(myLuaState)["stage"] = stage;
luaL_dostring(
myLuaState,
"stage::shoot_a_bullet(134)n"
);
你做的一切都对了,如果你想调用一个公开的C++对象的成员函数,你首先需要绑定它(你做到了),然后你把你的对象放到某个lua作用域(你使用了全局),然后你简单地引用对象阶段并使用::myfunction调用一个函数
- C++Lua用户数据扰乱了Mathfu浮点值
- 使用 LuaBridge 或 Lua 将对象传递给 Lua 函数C++
- 将 Lua 函数块转换为 C 字符串
- 我可以从 lua 5.0.2 加载用 c++ 编写的 lua 5.3.5 dll 吗?
- 使用 lua 协程 API 和lua_close时出现分段错误
- 使用 C++ 自动 Lua 绑定
- 调用 lua 函数的地址为 C/C++?
- lua 5.0.2 模块和 5.3.5 有什么区别?
- 如何将 Lua 添加到C++项目
- 使用 Lua 中的C++库对象
- 如何在C++中将用户数据从一个 Lua 块传递到另一个块
- 如何使用重新定义的打印函数打印Lua表?
- Lua table in C++ dll
- 在运行时环境中使用 C++ w/ Lua
- 将shared_ptr传递给Lua
- luaL_len is missing in Lua 5.1
- 将向量传递给<struct> Lua 表
- 将 Lua 与 C++ DLL 结合使用
- Lua C API - 从C++分配和使用类的对象成员
- C++中最接近 Lua 表操作的东西是什么?