To bind a C function to the scripting language we must first define what each C function must look like. We we'll need a way to access parameter data sent by the scripting language - let's just call it an SL from now on. Also we'll need a way to return a value to the SL from the C language.
We will use the SL_Object class to bind functions and return data to the SL.
About the C functions...
C function parameters will be sent using a class named SL_To_C_Parameter_List. This class contains a vector list of Variable_Object_Data_s structs which will contain one of several possible data type's data. This parameter data is accessed through interface functions like int Get_SL_Integer(unsigned int Parameter_Index); All C functions will be of type void. So each function that is to be bound to SL will take the form:
void Function_Name ( SL_To_C_Parameter_List p );
The SL_Object will be used to return a particular value if the C function is not declared as type void. Wait... I hear you thinking, "I thought all bound C function's were of type void" and you're right according to C syntax but the SL brains will see each bound C function as having a return type value which is set at bind-time. A C function returns values to the SL using a function such as SL_Object.C_To_SL_Return_Integer( int Data); or a similar function that may send a string, float, or vector. These functions push the returned value onto a stack which can be accessed by the SL brains after the C function finishes execution.
So a typical C function might look like this:
void Switch_Camera (SL_To_C_Parameter_List Parameters)
{
// We kow that there is only one parameter and it an integer
int Camera_Index = Parameters. Get_SL_Integer(0);
// Set the new camera
// Return 0 to SL on fail then exit
if(FAILED(Set_Camera_By_Index(Camera_Index)))
{
SL_Object.C_To_SL_Return_Integer(0);
return;
}
else
SL_Object.C_To_SL_Return_Integer(1);
}
The binding function...
We will need to bind this C function to the SL using the Bind_C_Function(void (*Function_Pointer) (SL_To_C_Parameter_List), vector Parameter_Type_List, SLC_Parameter_Type Return_Type); member function of SL_Object.
The first parameter of this function is a pointer to any function of type void with a single parameter of type SL_To_C_Parameter_List. The second parameter is a vector list of each parameter expected by the C function. The SLC_Parameter_Type is just an enumerated type defined in the SL header. The third parameter defines the return type of the C function. With this knowledge Bind_C_Function() can add the C function to an internal function map which the SL accesses each time it is looking for a particular function to call. Within each map entry can be found a pointer to a C function that looks like this: void (*Function_Pointer) (SL_To_C_Parameter_List).
Now when the internal workings of SL want to call a C function it needs only to build a SL_To_C_Parameter_List P and call the function Function_Pointer(P); Then if the function is not of type void we pop the return value off of the return stack and use it in whatever expression the C function was called from within the SL script.
This is what I'll be implementing tomorrow. What do ya think?
Interesting [smile]
Although I'm no expert on the finer points of correct software architecture it does seem to have a couple of odd things.
The first one I noticed, which is quite possibly a non-issue, is type-safety (I think thats the correct name).
Your example for Switch_Camera() seems to rely on the presence of a single integer. For general purpose usage (where you personally might not be the author of the script/c-code) it seems like it could be easy to abuse/mis-use.
What happens if they request a non-existant element or element of a different type (element 0 is a float not an int)...?
The second one that looked odd was the return mechanism. Why not have the C-Func return the SL_Object? Having an automagically existing SL_Object that must be configured before a return just looks a little bit prone to programmer-error...
I'm sure it'll work fine though, and it's quite possible I've just misinterpretted what you wrote [smile]
Good luck!
Jack