luabind - getting pointer to member function of lua class

Started by
5 comments, last by speciesUnknown 13 years, 3 months ago
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
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
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: Lol.butnFoo_onClick(self,iValue)
like in C++ the function needs the this pointer.

Hope this helps.


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: 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.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
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)
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.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
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?
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.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!

This topic is closed to new replies.

Advertisement