I'm new to Lua, and trying to understand some of the fundamentals. Something I want to understand is binding Lua to C++ instances.
I am not interested in third party libraries, I want to understand this at a more fundamental level - thanks :)
Here are my questions:
My assumption based on what I have read, is that Lua can only bind to static C functions. Is this correct?
Does that mean that to bind an instance of a C++ class, I'd first need to write static functions for each method and property getter/setter I want, accepting an instance pointer as a paramter.
I'd register these functions with Lua.
I'd pass Lua a pointer to the instance of the C++ class.
From Lua I'd call one of the registered functions, passing the C++ instance pointer.
The static function dereferences the pointer, calling the equivalent method.
Does this make sense? Or have I gotten something wrong?
Thanks for reading this far.
This is right up my ally.
1) Lua ... it doesn't really bind to stuff, what you need to do is "play nice with Lua" and that requires knowing a bit about how Lua works.
I REALLY suggest reading http://luaforge.net/docman/83/98/ANoFrillsIntroToLua51VMInstructions.pdf that.
That tells you about EVERYTHING Lua is actually able to do. So the functions Lua gives you let you manipulate just those structures.
After that everything makes a lot more sense.
Why this answer should end here
Your questions after 1 are all wrong. and 1 is semantically wrong, a static function just has internal/weak linkage. I guess you mean "not a method"
2) Not really, remember you have that nice "self"/"this" identity with objects (and lua with tables/meta-tables) - you don't bind to methods.
You want Lua to call some function of yours with a "self" argument, that "self" (whatever it may be, a simple integer ID, or a void* if you're feeling dangerous) should tell you what ojbect you are working with.
3/4/5/6 don't really make sense, read that document :) Comment in reply to this if you need more or have something more specific, it's not a bad question btw it's just naive
Related
I am tryintg to cast const FB::variant& sample into SampleJS* in C++.
like this:
SampleJS* info = sample.cast<SampleJS*>();
i do not know what is going wrong here.
this gives me error of:
boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >
Thank you in advance.
You need to understand that FB::variant just stores whatever type is put into it. Your code will absolutely work... if what is inside happens to be a MouseInfoJS*. However, you'd have to go through a lot of work to put something like that inside, since the FB::variant class is designed to make it difficult, but not impossible, to store inside it types that it doesn't know.
So basically, what you're trying to do probably doesn't make any sense, so you can't do it.
Depending on what type MouseInfoJS is, it might sorta make sense. Does MouseInfoJS inherit from JSAPI? (or JSAPIAuto?) If so, then it would somewhat make sense to try what you're doing, except that you'd never have a MouseInfoJS*, you'd have a MouseInfoJSPtr, which would be a typedef for boost::shared_ptr, since it would then be partially owned by the page and thus dangerous to store a raw pointer there.
Even in this case, which you'd need to use .convert_cast<MouseInfoJSPtr>, not .cast, it won't work on most modern browsers because they wrap the NPObject returned by FireBreath in another object which doesn't allow us to get the original object back; I believe this is a security feature. For more information, see A firebreath JSAPI will not be recognized in firefox
So here's the situation: I'm using C++, SDL and GLConsole in conjunction. I have a class, SDLGame, which has the Init(), Loop(), Render() etc - essentially, it holds the logic for my game class.
GLConsole is a nice library so far - it lets me define CVars and such, even inside my SDL class. However, when defining commands, I have to specify a ConsoleFunc, which is typedef'd as
typedef bool (*ConsoleFunc)( std::vector<std::string> *args);
Simple enough. However, like I said, my functions are all in my class, and I know I can't pass pointer-to-class-functions as pointer-to-function arguments. I can't define static functions or make functions outside my class because some of these ConsoleFuncs must access class data members to be useful. I'd like to keep it OOP, since - well, OOP is nice.
Well, I actually have this problem "solved" - but it's extremely ugly. I just have an instance of SDLGame declared as an extern variable, and use that in my ConsoleFuncs/main class.
So, the question is: Is there a way to do this that isn't stupid and dumb like the way I am doing it? (Alternatively: is there a console library like GLConsole that supports SDL and can do what I'm describing?)
If the only interface you have is that function pointer, then you're screwed.
A member function needs a this pointer to be called, and if you have no way of passing that, you're out of luck (I guess the std::vector<std::string>* args pointer is what you get passed from the library).
In other words, even though that library uses C++ containers, it's not a good C++ library, because it relies on free functions for callbacks. A good C++ library would use boost::function or something similar, or would at the very least let you pass a void* user_data pointer that gets passed through to your callback. If you had that, you could pass the this pointer of your class, cast it back inside the callback, and call the appropriate member function.
I'd like some advice on how to check for the correctness of the parameters I receive.
The checking is going to be done in C++, so if there's a good solution using Boost.Python (preferably) or the C API, please tell me about that. Otherwise, tell me what attributes the object should have to ensure that it meets the criteria.
So...
How do you check that an object is a function?
How do you check that an object is a bound method?
How do you check that an object is a class object?
How do you check that a class object is a child of another class?
When in doubt just work out how you would get the required effect by calling the usual Python builtins and translate it to C/C++. I'll just answer for Python, for C you would look up the global such as 'callable' and then call it like any other Python function.
Why would you care about it being a function rather than any other sort of callable? If you want you can find out if it is callable by using the builtin callable(f) but of course that won't tell you which arguments you need to pass when calling it. The best thing here is usually just to call it and see what happens.
isinstance(f, types.MethodType) but that won't help if it's a method of a builtin. Since there's no difference in how you call a function or a bound method you probably just want to check if it is callable as above.
isinstance(someclass, type) Note that this will include builtin types.
issubclass(someclass, baseclass)
I have two unconventional recommendations for you:
1) Don't check. The Python culture is to simply use objects as you need to, and if it doesn't work, then an exception will occur. Checking ahead of time adds overhead, and potentially limits how people can use your code because you're checking more strictly than you need to.
2) Don't check in C++. When combining Python and C (or C++), I recommend only doing things in C++ that need to be done there. Everything else should be done in Python. So check your parameters in a Python wrapper function, and then call an unchecked C++ entry point.
in C++, I can easily create a function pointer by taking the address of a member function. However, is it possible to change the address of that local function?
I.e. say I have funcA() and funcB() in the same class, defined differently. I'm looking to change the address of funcA() to that of funcB(), such that at run time calling funcA() actually results in a call to funcB(). I know this is ugly, but I need to do this, thanks!
EDIT----------
Background on what I'm trying to do:
I'm hoping to implement unit tests for an existing code base, some of the methods in the base class which all of my modules are inheriting from are non-virtual. I'm not allowed to edit any production code. I can fiddle with the build process and substitute in a base class with the relevant methods set to virtual but I thought I'd rather use a hack like this (which I thought was possible).
Also, I'm interested in the topic out of technical curiosity, as through the process of trying to hack around this problem I'm learning quite a bit about how things such as code generation & function look-up work under the hood, which I haven't had a chance to learn in school having just finished 2nd year of university. I'm not sure as to I'll ever be taught such things in school as I'm in a computer engineering program rather than CS.
Back on topic
The the method funcA() and funcB() do indeed have the same signature, so the problem is that I can only get the address of a function using the & operator? Would I be correct in saying that I can't change the address of the function, or swap out the contents at that address without corrupting portions of memory? Would DLL injection be a good approach for a situation like this if the functions are exported to a dll?
No. Functions are compiled into the executable, and their address is fixed throughout the life-time of the program.
The closest thing is virtual functions. Give us an example of what you're trying to accomplish, I promise there's a better way.
It cannot be done the way you describe it. The only way to change the target for a statically bound call is by modifying the actual executable code of your program. C++ language has no features that could accomplish that.
If you want function calls to be resolved at run-time you have to either use explicitly indirect calls (call through function pointers), or use language features that are based on run-time call resolution (like virtual functions), or you can use plain branching with good-old if or switch. Which is more appropriate in your case depends on your specific problem.
Technically it might be possible for virtual functions by modifying the vtable of the type, but you most certainly cannot do it without violating the standard (causing Undefined Behavior) and it would require knowledge of how your specific compiler handles vtables.
For other functions it is not possible because the addresses of the functions are directly written to program code, which is generally on a read-only memory area.
I am fairly sure this is impossible in pure C++. C++ is not a dynamic language.
What you want is a pointer to a function, you can point it to FuncA or FuncB assuming that they have the same signature.
You cannot do what you want to do directly. However, you can achieve a similar result with some slightly different criteria, using something you are already familiar with -- function pointers. Consider:
// This type could be whatever you need, including a member function pointer type.
typedef void (*FunctionPointer)();
struct T {
FunctionPointer Function;
};
Now you can set the Function member on any given T instance, and call it. This is about as close as you can reasonably get, and I presume that since you are already aware of function pointers you're already aware of this solution.
Why don't you edit your question with a more complete description of the problem you're trying to solve? As it stands it really sounds like you're trying to do something horrible.
Its simple!
For
at run time calling funcA() actually results in a call to funcB().
write funcA() similar to following:
int funcA( int a, int b) {
return funcB( a, b );
}
:-)
What is mean by delegates in c++, does sort function in c/c++ which takes a compare function/functor as last parameter is a form of delegate?
"delegate" is not really a part of the C++ terminology. In C# it's something like a glorified function pointer which can store the address of an object as well to invoke member functions. You can certainly write something like this in C++ as a small library feature. Or even more generic: Combine boost::bind<> with boost::function<>.
In C++ we use the term "function object". A function object is anything (including function pointers) that is "callable" via the function call operator().
std::sort takes a "predicate" which is a special function object that doesn't modify its arguments and returns a boolean value.
Callback functions in C++ can be (loosely) referred as a form of delegates ( though delegate term is not used for this). The callback functions use Pointers to Functions to pass them as parameters to other functions.
But delegates in C# is more advanced compared to callback functions in C++.
To delegate work means to share the work load with others. In real life, if you were to delegate your task, ie if you are a manager, you would be sharing your work expecting others to complete a task without you having to know how.
The concept is the same in C++ and any other languages having the capability of delegates. In C you could see this as a delegate:
int calculate(int (*func)(int c), int a, int b)
Because you are expected to send a pointer, to another function which will compute some work for you. I recently wrote a blog post on function pointers in Python and C, check it out, you might find it helpfull. This might not be the "traditional" way to delegate work in C or C++, but then again, the termonoligy says i am a bit right.
Delegation is mostly used as a way to pass functions to functionality embedded in a class (pimpl, aggregation, private inheritance). They are mainly (inlined) functions of one line, calling functions of member-classes. As far as I know, it has nothing to do with C#'s delegates.
In this sense, a function-pointer as used in qsort is not a delegate, but a callback in which framework modules can be extended by user-software as in the Hollywood principle.
Delegate: An object that acts like a multi-function pointer with a subscription system. It really simplifies the use of static or 'object' member function pointers for callback notifications and event handling.
This link explains Delegates in a lucid manner or you may also refer to the MSDN link.