Calling Real Functions from a Script

Started by
8 comments, last by Nik02 19 years, 7 months ago
Is it possible to do this? Lets say I have some random C/C++ function in code, like this.. INT MakeTheBallFly(INT vel, FLOAT angle, CHAR *name); Then, I have this in my script text.. MakeTheBallFly(5, 0.45, "Big"); Is it possible to call that function and pass the parameters by the script text interpreter? Do the real functions need to be created specifically for use in the script? How can I hand the script-compiler a function pointer, and allow it to call this function? The only way I know of handling this is to make INT MakeTheBallFly(ScriptArgs *args); type functions. Which I really, really don't wanna do. Thanks for any help
Advertisement
Hmm. You can use a script-funtion callback. Perhaps it would look something like this:

int MakeTheBallFlyScript(const int iArgCount, const std::vector<std::string> vstrkArgs){   // Convert the arguments.   std::stringstream kStream;      kStream << vstrkArgs.at(0);   int iVel;   kStream >> iVel;   float fAngle;   kStream << vstrkArgs.at(1);   kStream >> fAngle;   const char *pkName = vstrkArgs.at(2).c_str();   // Now call the function.   return MakeTheBallFly(iVel, fAngle, pkName);}

But wouldn't this require the interpreter to know and have predifined every function that can be called from within it?
Quote:But wouldn't this require the interpreter to know and have predifined every function that can be called from within it?


I suppose so. Though I'm not quite sure what you're trying to accomplish. I don't see any way to automatically export functions from the host app into the script's context.

Not too much help, I'm afraid :-/
You could make and maintain a paired list of function names and their pointers (along with type info about the parameters and such), and when a script function is invoked, seek that list for the function pointer given the name.

This is essentially how "professional" vtables work, albeit usually they use numeric indices in the function list for speed instead of string compares in a symbol-based approach.

Note that this is not automatical - you'd still have to "export" the scriptable functions yourself - but when you define a function in the script, you can append it to the symbol list (of course, you need to compile the function first somehow).

Niko Suni

Yes, that's what I do. But I'm not sure how to keep details about the function parameters, or how to call them with those details. When I want to call a function from within the script text, I can have a pointer to the function, and a list of all variables and their types that need to be passed to it. But I'm not sure how to actually call that function with the variables as parameters.

If this is possible, I'm just missing some C/C++ feature? Or I'm being totally stupid.

Thanks again
Variable type info can be as simple as an array of enumeration values. The enumeration would consist of type flags, for example VT_INT, VT_FLOAT, VT_ZTSTRING, VT_POINTER and so on, with which each parameter in the vtable would be flagged. The enumeration could have an extra value, VT_VOID, to denote the parameter list end (or void, if used as the only parameter or return value of a function).

You might want to extend the type info structure a bit from that, to store metadata and such, as .net does. However, that may not be necessary, depending on the desired robustness of the system.

A good script-side approach would be to use only variants in the script (a'la JScript, VBScript, php...), and determine their types and counts at the script compile time.

EDIT: After you have the parameter types (and parameter count derived from the position of the VT_VOID flag), it is only a matter of copying the parameters to your virtual stack - that is, the script callback function - and executing the correct function from the vtable saved previously.

EDIT2: I just realized your problem :)
The script callback's parameters would include the pointer to the parameter list of the currently executed function. That enables the script engine to call the callback generically with all functions, as the callback enumerates the parameter lists in any case.

[Edited by - Nik02 on August 28, 2004 2:51:45 AM]

Niko Suni

So it's impossible to give the parameters names? I guess this was my real question all along. I knew I could pass all parameters as a list, and that list can describe each parameter's type. But I was hoping to avoid stuff like Ball.Velocity.x = Args[0].GetValue();

I was hoping for something magical, like the parameters having lables (other than a define or enum).

If it's not possible, then no problem. I can do the enum thing. But that makes it impossible to just call a random C++ function without providing a wrapper for it. Oh well :)

Thanks for the help!
You could, of course, replace the simple array of enumeration values to something more complex, like a name/value map or even a small database. It's only more work, but you do get additional robustness in return.

The simple array as a parameter list I talked about was just an example. You do need a some kind symbol export/import system anyway, and that is the easiest (if not by far the most complete) way of implementing one.

C++ itself doesn't call random functions, actually; the linking procedure binds symbols very precisely, conceptually similar to the system we've discussed here, but a bit more low-level. You do need to explicitly export from c++ also, if you want to use the functions from outside of the module - and the linker will construct the export table with the symbolic info just like you're about to do in your project, only with your own linker logic.

Niko Suni

I just wanted to add, that while you cannot call "random" functions (that is, not exported from the c++ core system), you can of course write your own functions in the script and then call them from c++ - I see this as much more powerful ability [smile]

And while you're at it, you could add LoadLibrary* and FindProcAddress wrappers to your script's symbol table, and you'd have dll loading capabilities in your script. Do notice that this is potentially a huge security risk if you actually publish the code in your app, and let the users write scripts.

Niko Suni

This topic is closed to new replies.

Advertisement