[NAME] ALL.daovm.interface.embedding [TITLE] Embedding Dao VM [DESCRIPTION] 1 A Simple Example 1.1 Initializing Dao Runtime Before doing anything with Dao as a library, one must call DaoInit() to initialize it first: 1 // Initialize Dao: 2 DaoVmSpace *vmspace = DaoInit( NULL ); This function will return a DaoVmSpace object, which can be used to load Dao scripts or modules. It can optionally take a char* parameter, which is assumed to be the path and name of the application, and is used to add additional searching paths. 1.2 Load A Script File Once you have a DaoVmSpace object, you can start to run Dao scripts or load Dao modules using this object. If you have a main script file and all you need to do is to run the file, you can simply call: 1 // Load "myscript.dao": 2 DaoVmSpace_Load( vmspace, "myscript.dao" ); 1.3 Finalize Dao Runtime After you are done with Dao, you may call the following function to make sure, Dao is properly finalized (waiting for unjoined threads to finish and the garbage collector to finish, and deallocating some internal data structures etc.). 1 // Finalize (or Quit) Dao: 2 DaoQuit(); 1.4 Putting These Codes Together Putting these codes together, embedding Dao can be as simple as, 1 // Initialize Dao: 2 DaoVmSpace *vmspace = DaoInit( NULL ); 3 // Load "myscript.dao": 4 DaoVmSpace_Load( vmspace, "myscript.dao" ); 5 // Finalize (or Quit) Dao: 6 DaoQuit(); 2 A Slightly More Advanced Example In Dao, each single script file is represented by one namespace object. And each namespace object has access to the public global constants and variables defined in the files that this file has loaded. To do anything interesting, one must obtain the namespace object for the file of interest. 2.1 Obtaining The Namespace Object Following the above example, if you want to call a function defined in "myscript.dao"(or in the files it has loaded), you can simple store the returned namespace object in a variable, 1 // Load "myscript.dao" and obtain the namespace object: 2 DaoNamespace *nspace = DaoVmSpace_Load( vmspace, "myscript.dao" ); 2.2 Obtaining The Function Object To find the function you want to call, 1 // Find an object named "myfunction": 2 DaoValue *value = DaoNamespace_FindData( nspace, "myfunction" ); 3 // Try to cast it to a function object: 4 DaoRoutine *myfunc = DaoValue_CastRoutine( value ); If "myfunction" is indeed a function, myfunc will not be NULL. 2.3 Obtaining A Process Object Now to call the function, you will need another type of object: DaoProcess, which represents a virtual machine process and is responsible for executing scripts. You can directly call DaoProcess_New() to create a new process object, but normally the better to get a process object is to acquire it from a DaoVmSpace object: 1 // Acquire a process object: 2 DaoProcess *proc = DaoVmSpace_AcquireProcess( vmspace ); 2.4 Prepare Parameter Values Now suppose the function "myfunction" needs to take an integer as its first parameter and a string as the second. To call it, we will need to prepare parameters that can be passed to this function. The simplest way to do this is to use the data "factory" methods that are associated with the process type DaoProcess. Such methods are normally begin with DaoProcess_New. For example, to prepare an integer value and a string value, one can do, 1 // Prepare an integer and a string: 2 DaoInteger *ivalue = DaoProcess_NewInteger( proc, 123 ); 3 DaoString *svalue = DaoProcess_NewMBString( proc, "abc", -1 ); The third parameter of DaoProcess_NewMBString() is the number of bytes in the C string, and a negative value can be used to indicate the C string is NULL terminated. To use these two new values in the parameter list to call "myfunction", you can do, 1 DaoValue *params[2]; 2 params[0] = (DaoValue*) ivalue; 3 params[1] = (DaoValue*) svalue; Or you can simply do, 1 // Get the last two values: 2 DaoValue **params = DaoProcess_GetLastValues( proc, 2 ); which will return last created two values in an array. 2.5 Call The Function Now we are ready to call the function we obtained before with the prepared values, 1 // Call the function: 2 DaoProcess_Call( proc, myfunc, NULL, params, 2 ); For class methods, a class instance object can be passed to this function as the third parameter, or it can be passed as the first value of params. Please note that, this function can handle overloaded functions automatically! So you do not need to do anything for that. This function will return zero on success, or other values with errors. 2.6 Retrieve The Returned Value If the function returns a value, you can obtain it by, 1 // Obtain the returned value: 2 DaoValue *retvalue = DaoProcess_GetReturned( proc ); If the returned value is supposed to be of certain type, you can cast it to that type by using one of the DaoValue_CastXXX() functions, or directly convert it to a proper C type by using one of the DaoValue_TryGetXXX() functions. For example, if "myfunction" returns an integer, you can get it by, 1 // Get the integer return value 2 daoint retint = DaoValue_TryGetInteger( retvalue ); 2.7 Release The Process Object After you have done with the process object, you can release it back the DaoVmSpace object, 1 // Release the process: 2 DaoVmSpace_ReleaseProcess( vmspace, proc ); But if you want to use a process object frequently, you may simply retain it until you no longer need it. Then you may also need to the follow function to release the cached values 1 // Pop the cached values: 2 DaoProcess_PopValues( proc, 2 ); 2.8 Putting These Codes Together 1 // Load "myscript.dao" and obtain the namespace object: 2 DaoNamespace *nspace = DaoVmSpace_Load( vmspace, "myscript.dao" ); 3 // Find an object named "myfunction": 4 DaoValue *value = DaoNamespace_FindData( nspace, "myfunction" ); 5 // Try to cast it to a function object: 6 DaoRoutine *myfunc = DaoValue_CastRoutine( value ); 7 8 // Acquire a process object: 9 DaoProcess *proc = DaoVmSpace_AcquireProcess( vmspace ); 10 11 // Prepare an integer and a string: 12 DaoInteger *ivalue = DaoProcess_NewInteger( proc, 123 ); 13 DaoString *svalue = DaoProcess_NewMBString( proc, "abc", -1 ); 14 // Get the last two values: 15 DaoValue **params = DaoProcess_GetLastValues( proc, 2 ); 16 17 // Call the function: 18 DaoProcess_Call( proc, myfunc, NULL, params, 2 ); 19 20 // Obtain the returned value: 21 DaoValue *retvalue = DaoProcess_GetReturned( proc ); 22 // Get the integer return value 23 daoint retint = DaoValue_TryGetInteger( retvalue ); 24 25 // Release the process: 26 DaoVmSpace_ReleaseProcess( vmspace, proc );