Advertisement

Luabind C++ function issue

Started by April 25, 2011 01:15 AM
3 comments, last by Roots 13 years, 7 months ago
I am new to integrating Lua into C++, so I set up Luabind because many people had recommended it as one of the better libraries used to facilitate the usage of Lua in conjunction with C++. I read a helpful tutorial here: Quick Introduction to LuaBind that detailed on how I could integrate the two. My main problem is the section: Making C++ functions callable from Lua. The code that they provided worked, so I decided to setup LuaBind in one of my game projects to use it to script the loading of some resources.

However, the problem was that the functions that I was trying to make available from C++ to Lua weren't being made available, and consequently nothing happened. I decided to go back to a simpler program in order to discover the heart of the problem. Unlike the example given in the aforementioned link, the function that I was trying to export to Lua was also a member of a class. I have a suspicion that that might be the cause of the issue. My guess is that there is a way of exporting functions in a class that I do not fully understand. Naturally, I wrapped my Lua functionality within a class, so I would do something like



luabind::def("print_hello", &hellos::print_hello)


... instead of the...


luabind::def("print_hello", print_hello)

... that was given in the example code. I have tried replacing print_hello with a function pointer, but nothing happens still. Does anybody with experience with LuaBind know what I might be doing wrong? Below is my complete code.




#include "stdafx.h"

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

#include "luabind/luabind.hpp"
#include <luabind/function.hpp>

using namespace std;

class hellos {
protected:
lua_State *myLuaState;
void print_hello();
public:
hellos();
~hellos();

int hi;
void run();
};


void hellos::print_hello() {
cout << "Hello!";
}


void hellos::run() {
myLuaState = lua_open();
luaL_openlibs(myLuaState);
luabind::open(myLuaState);
luaL_loadfile(myLuaState, "factorial.lua");

luabind::module(myLuaState) [
luabind::def("print_hello", &hellos::print_hello)
];

luaL_dostring(myLuaState,"print_hello()\n");

lua_close(myLuaState);

int wait; cin >> wait;
}

int main() {
hellos *h = new hellos();
h->run();
delete h;
}



Thank you for your assistance. I am also using Lua 5.1 with LuaBind 0.9.
When binding a member function, you need to bind it as part of a class_ in luabind. You can't call a member function without something to call it on, remember.

[size=1]Visit my website, rawrrawr.com

Advertisement

When binding a member function, you need to bind it as part of a class_ in luabind. You can't call a member function without something to call it on, remember.


Thanks for your answer. I reworked my code and managed to make the function callable by Lua by simply making making an instance of the class in Lua.



module(myLuaState)
[
class_<hellos>("hellos")
.def(constructor<>())
.def("print_hello", &hellos::print_hello)
];


Then, I was able to run print_hello() by substantiating the class and using its member functions.



speaker = hellos()
speaker:print_hello()


Are we forced to always use this approach when we call C++ functions from Lua using the member functions of some class, or is there a way to avoid having to declare a hellos() class and just register print_hello()?
Is there any reason is has to be a member function? You could make it a free function, or a static member function.
If you really do want it to be a member, then like Rrawwrr said, you have to have a class instance to call the member function. However, there's no reason you can't create the object on the C++ side, and make it a Lua global or something.
I use many more member functions than free functions in my code. Most of our Lua functions accept class objects as parameters and then call bound methods on those objects to achieve the results that we want. For example, here's a Lua function that executes a battle action:


skills[3] = {
name = hoa_system.Translate("Stun Strike"),
description = hoa_system.Translate("A blow which targets vital areas and temporarily stun its target."),
sp_required = 5,
warmup_time = 1200,
cooldown_time = 0,
target_type = hoa_global.GameGlobal.GLOBAL_TARGET_FOE,

BattleExecute = function(user, target)
user:ChangeSpriteAnimation("attack");
target_actor = target:GetActor();

if (hoa_battle.CalculateStandardEvasionAdder(target, 5.5) == false) then
target_actor:RegisterDamage(hoa_battle.CalculatePhysicalDamage(user, target));
target_actor:RegisterStatusChange(hoa_global.GameGlobal.GLOBAL_STATUS_PARALYSIS, hoa_global.GameGlobal.GLOBAL_INTENSITY_POS_LESSER);
AudioManager:PlaySound("snd/swordslice1.wav");
else
target_actor:RegisterMiss();
AudioManager:PlaySound("snd/sword_swipe.wav");
end
end
}


The {BattleExecute} Lua function is fed two arguments: a pointer to the actor that is using this skill, and a pointer to the target the skill is intended to affect. Both {user} and {target} are class objects. Then we begin calling bound methods of both the user and target classes to change their state, as well as playing sound effects from our global AudioManager class object (the interface to our AudioEngine). Note that {CalculatePhysicalDamage} is actually a standard function not a part of a C++ class, but is contained within one of our bound Lua namespaces instead.


If you want to see more examples the code for my game is open source and has a lot of Lua bindings and Lua scripts written, if you think that would help you gain a better understanding of how this all works. We have examples of multiple functions with the same name bound by defining their unique signatures as well.

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement

This topic is closed to new replies.

Advertisement