Question

Basically, I just want to be able to have a clean Lua instance made inside of my Manager class, then export the functions in the class to Lua, so that I can call functions on the already created C++ class inside of Lua.

This is the current way I am looking at solving the issue. It compiles but nothing happens in Lua.

Does anyone know what I am doing wrong, or does anyone have any other suggestions?

Manager.lua

newObject("Object", 1234)
printAll()

Manager.h

#ifndef MANAGER_H
#define MANAGER_H
#include <iostream>
#include <vector>
#include <string>

extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include "luabind/luabind.hpp"
#include "Object.h"


class Manager
{
private :
    lua_State *L;
    std::vector<Object> obj;


public :
    Manager();
    void newObject(std::string t, int nm);
    void printAll();

};

#endif

Manager.cpp

#include "Manager.h"
Manager::Manager()
{
luabind::open(L);

luabind::module(L) [
    luabind::class_<Manager>("Manager")
        .def(luabind::constructor<>())
        .def("newObject", &Manager::newObject)
    ];

luaL_dofile(L, "Manager.lua");
}   

void Manager::newObject(std::string t, int nm)
{
    if(t == "Object")
    {
        Object object(nm);
        obj.push_back(object);
    }
}

void Manager::printAll()
{
    for(unsigned int i = 0; i < obj.size(); i++)
        std::cout << obj[i].getNum() << std::endl;
}
Was it helpful?

Solution

so that I can call functions on the already created C++ class inside of Lua.

If you use Luabind to create a class, and then provide members of that class, then Luabind will do exactly that. It will expose a class to Lua that has members.

You cannot call a member function in C++ without an object of that class's type. And therefore, when you expose a class and its members through Luabind, you will not be able to call member functions in Lua without an object of that class's type.

Therefore, if you have some global Manager object, the proper way to expose this to Lua is to expose the object itself to Lua. Use Luabind to get the global table, then put a pointer to your Manager object in it. Alternatively, you can pass the Manager object instance as a parameter when you execute the script.

The second method would work something like this:

//Load the script as a Lua chunk.
//This pushes the chunk onto the Lua stack as a function.
int errCode = luaL_loadfile(L, "Manager.lua");
//Check for errors.

//Get the function from the top of the stack as a Luabind object.
luabind::object compiledScript(luabind::from_stack(L, -1));

//Call the function through Luabind, passing the manager as the parameter.
luabind::call_function<void>(compiledScript, this);

//The function is still on the stack from the load call. Pop it.
lua_pop(L, 1);

Your Lua script can get an instance with Lua's varargs mechanism:

local manager = ...
manager:newObject("Object", 1234)
manager:printAll()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top