而不是在lua中创建一个对象,如何让lua直接高举C ++对象来启动一个方法?

时间:2014-01-19 05:18:14

标签: c++ lua luabind

我正在使用Luabind。

我的头衔可能有点不清楚,我会尽力解释我想问的问题。

我的问题是:
  我如何直接高举C ++对象的方法,可以访问对象的值(尤其是指针),而不是在Luabind中创建另一个对象。

如果你不知道我在问什么,你可以继续阅读。

例如,我有三个类:MainTest_StageTest_Class

Lua仅在Test_class中创建。

我有一个变量x,仅用于测试目的。它的构造函数从Main一直传递到Test_StageTest_Class。因此Test_ClassTest_Stage都有一个全局值,在我实际制作游戏时我需要这个值。
更重要的是,Test_Class拥有Test_Stage的指针,因此我可以执行create_a_bulletcreate_damage之类的操作。

从这个Tutorial中了解到,我曾试图让luaobject中创建的Test_Class调用方法shoot_a_bullet,该方法将高“Test_Stage”对象打印“Runned” << '全球价值'。在C ++中没有语法错误,IT没有打印任何东西。我该如何解决这个问题?

代码在这里(实际上我在使用转发时遇到了麻烦,包括使用类,所以“Runned”<< x在Test_Class。至少我可以测试它是否会读取已传递的全局值。)

编辑:几个小时后什么都不做,我有另外一个解决方案。有没有办法可以传递可以在lua中创建的对象中使用的指针,或者可以在constructer中使用?

代码(如果你来回答这个问题,你可以考虑跳过main和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 ".\luabind\luabind.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()
{

}    

2 个答案:

答案 0 :(得分:0)

经过大量的研究和研究,我终于想出了一个解决方案,虽然我不确定它的效率如何,它实际上是按照我希望的方式工作。
因此,最终的解决方案是,注册从我需要的指针转换为intptr_t,以获取有关intptr_tclick here的更多信息(主要出于安全原因,您可以将其视为一种用于指针的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;

我们还需要稍微改变一下这个功能:
首先,我们需要将函数设置为static,所以在头文件中:

//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 ".\luabind\luabind.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 ".\luabind\luabind.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()
{

}    

玩得开心!

答案 1 :(得分:0)

我知道这已经晚了,但为什么你这么简单呢

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

调用函数