Jump to content
  • Advertisement
Sign in to follow this  
speciesUnknown

luabind - getting pointer to member function of lua class

This topic is 2895 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

HI,

I'm attempting to implement a system where I can register any function as a delegate; as a first step I'm setting up an environment where I can pass a function identifier to the c++ side and have it be called immediately. Once I have this working I'll store a list of luabind::object and call them, thus implementing a nice delegate system. The problem is, I cant

This is my code for the c++ side:



#include "common.h"
#include <luabind/object.hpp>

void callObject(luabind::object const& obj)
{
int stuff = luabind::call_function<int>(obj, 9001);

std::cout<<"function was called c++ side, return value was "<<stuff<<std::endl;
}

extern "C" DLLEXPORT int delegate(lua_State* L)
{
open(L);

module(L)
[
def("callObject",&callObject)
];

return 0;
}



This is the lua script I am using to call this; it gets as far as performing the test call, and then panics.



-- performing callObject on a plain old function
freeFunction = function(iValue)
print("function got called lua side, passed value was", iValue)
return 12
end

-- this is the function I have bound from the c++ side
callObject(freeFunction)



-- performing callObject on a member function
class "Lol"
function Lol:__init(sName)
self.name = sName
end

function Lol:butnFoo_onClick(iValue)
print("butnFoo_onClick got called with paramater", iValue, "on Lol with name", self.name)
return 1
end

-- instance the class and call the function to ensure it is correct
lol = Lol("fubar")
lol:butnFoo_onClick(99)

-- pass a function ptr to callObject (fails)
callObject(lol.butnFoo_onClick))



The last line fails silently. Why is lol.butnFoo_onClick fundamentally different to freeFunction?

- edit: apologies for using c++ syntax highlighting for lua code; the new bbcode doesnt allow attributes in the code tag; if you use them, it dumps it all as plain text

Share this post


Link to post
Share on other sites
Advertisement
The difference is that the free function expects just an int as it's first parameter but
Lol:butnFoo_onClick(iValue) [font="Arial"]is a syntactic sugar to this:[/font] Lol.butnFoo_onClick(self,iValue)
like in C++ the function needs the this pointer.

Hope this helps.

Share this post


Link to post
Share on other sites

The difference is that the free function expects just an int as it's first parameter but
Lol:butnFoo_onClick(iValue) [font="Arial"]is a syntactic sugar to this:[/font] Lol.butnFoo_onClick(self,iValue)
like in C++ the function needs the this pointer.

Hope this helps.




It explains the problem but doesnt help me with a solution. How can I bypass this problem? I need some way of passing around the member functions of a Lua class.

Share this post


Link to post
Share on other sites
This is not a problem.
A member function must have a pointer to the object it is operating on. I guess you can make your callObject function take as its first parameter the function to call and then a list of parameters to give to this function so calling a free function might look like this
callObject(freeFunction,9001)
and calling a member function will look like this:
callObject(lol.butnFoo_onClick,lol)

This will work since calling lol:butnFoo_onClick() is the same as lol.butnFoo_onClick(lol)

Share this post


Link to post
Share on other sites
It seems im trying to force one possible solution into this. What other ways are there of binding a member function of a Lua class into the c++ side? For example, if I wanted to implement callbacks for a GUI which work in the way JS callbacks do?

The only point of concern is that on the c++ side it needs to be transparent whether the function is a member of a class. I'm not terribly concerned if I have to use a different side in each case on the Lua side.

Share this post


Link to post
Share on other sites
Then why not create somthing like this:

class LuaFunction
{
object func;
object self;
bool isMember;
void Invoke()
{
if (isMember)
{
func.push();
self.push();
// push parameters
lua_call(state,argcount+1,whatever);
}
else
{
func.push();
// push parameters
lua_call(state,argcount,whatever);
}
}
};

Or am I getting you wrong?

Share this post


Link to post
Share on other sites
I actually found a solution entirely on the Lua side:




class "MemFunction"
function MemFunction:__init(callee, func)
self.callee = callee
self.func = func
end

function MemFunction:__call(...)
return self.func(self.callee, ...)
end


Since the difference between a normal and an overloaded Lua __call is transparent on the c++ side, nothing more needs to be done.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!