Zookeeper
Welcome to Lu Program Design
C/C ++ uses the dynamic object Lu in the lu script
1 Description
To demonstrate this example, you must download the Lu32 script system. The example in this article requires lu32.dll, lu32.lib, and lu32.h header files. I believe you will find and use these files correctly.
Use the C/C ++ compiler to create a console application. Copy the sample code in this article and compile and run it.
2. About dynamic objects and lu Dynamic Objects
At the beginning of this tutorial series, we introduced the basic data structure of the Lu script (For details, refer to the Lu Programming Guide), that is:
Struct LuData {// basic data structure of the Lu.
LuIFOR x; // luIFOR is defined as a 64-bit integer _ int64 to store data. For dynamic data types, object pointers are stored in the first four bytes of x.
LuIFOR y; // store data.
LuIFOR z; // store data.
LuKEY VType; // luKEY is defined as a 32-bit integer _ int32. The data type is extended, and the overload function is determined, thus the data operation method is determined.
LuKEY BType; // The basic data type, which determines the structure of the Lu data.
};
The basic data type BType determines the actual data structure. Static data can store up to 24 bytes of data, similar to strings, arrays, and other data that occupies up to 24 bytes, lu scripts are called Dynamic Data Types (or dynamic objects ). For dynamic objects, only the pointer of the dynamic object is saved in LuData, the basic data structure of Lu. The 32-bit pointer of the object is saved in the first 32-bit of LuData: x. This section uses dynamic object lu as an example to describe how to use dynamic objects.
The Dynamic Object lu is a linear table (Lu table for short, which can store any data, including any number of lu tables). It is the basic data type of the Lu script. See the header file lu32.h in C format, the structure of the Dynamic Object lu is defined as follows:
// Dynamic Lu table
Typedef struct luLu
{
LuData * Lu; // NULL allowed
LuVOID Len; // Lu data buffer Length
} LuLu;
The Lu table's key value (that is, the basic data type BType) in the Lu system key tree is luDynData_lu. Refer to the definition in the header file lu32.h:
# Define ludyndata_lu- 255 // dynamic Lu data
The Lu dynamic object is saved in the Lu string key tree (both dynamic data and any data can be saved). The Lu key tree saves the data in the following format:
KeyStr: key name (char * KeyStr ). It is case sensitive and can contain any character, including NULL ('\ 0 ').
ByteNum: the length of the key (luINT ByteNum ). ByteNum> 0.
KeyType: the type of the key (luKEY KeyType ).
That is to say, the data corresponds to the key name, length, and type one by one. If the pointer plu points to an luLu type pointer object, the object is saved in the Lu key tree in the following format (other dynamic objects have similar formats ):
KeyStr :( char *) & plu // convert the pointer to a string
ByteNum: sizeof (luVOID) // obtains the pointer size. The 32-bit platform contains 4 bytes, and the key length of a dynamic object is always 4 bytes.
KeyType: luDynData_lu // key type
So how can we use a dynamic object? Because only the pointer of the dynamic object is saved in the basic data structure of the Lu, whether the pointer is actually valid (for example, the pointer is invalid due to many reasons, for example, the object has been destroyed, or modify the pointer responsibly. Unlike other scripts, the Lu script allows you to use delete to destroy an object immediately. The function for verifying dynamic objects (that is, finding a key in the Lu System) is SearchKey, which is easy to use:
Void * _ stdcall SearchKey (char * KeyStr, luINT ByteNum, luKEY KeyType); // The parameter meaning is as described above. A pointer to a key value (Dynamic Object) is returned, or NULL is returned.
By the way, when Lu interacts with C/C ++, Or Lu interacts with Script users, dynamic object management is flexible and convenient. C/C ++ can register an object with the Lu system or easily destroy the object. The script user can generate dynamic objects at any time or immediately destroy dynamic objects. There are no restrictions on the use of dynamic objects by the script user, but the C/C ++ program should pay attention to two points: (1) in multi-threaded programming, in most cases, each thread needs to access the Lu system mutually; (2) Before using a dynamic object, use the SearchKey function or other dedicated functions to verify the dynamic object. We will provide examples in this regard in the future.
In the Lu system with thousands of dynamic objects, if you have doubts about the efficiency of the SearchKey function, you can test it by yourself.
3Code
# Include
# Include "lu32.h" # pragma comment (lib, "lu32.lib") void PrintLu (LuData * pVal) // output the lu object value, only integer, real number, and lu object {luLu * plu; // lu Object Pointer static luLu * pmainlu = NULL; // remember the original lu object, avoid the infinite recursion call of this function static int k; int j; luVOID I; if (pVal-> BType! = LuDynData_lu) return; // verify whether the lu object is valid. plu = (luLu *) SearchKey (char *) & (pVal-> x), sizeof (luVOID), luDynData_lu ); if (NULL = plu) {printf ("invalid lu object pointer! \ N "); return;} if (plu = pmainlu) {printf (" this is a recursive nested lu object! \ N "); return;} if (pmainlu = NULL) pmainlu = plu; // remember the original lu object k ++; for (I = 0; I
Len; I ++) {for (j = 0; j
Lu [I]. BType = luStaData_int64) {printf ("% I64d \ n", plu-> Lu [I]. x);} else if (plu-> Lu [I]. BType = luStaData_double) {printf ("% f \ n", * (double *) & (plu-> Lu [I]. x);} else if (plu-> Lu [I]. BType = luDynData_lu) {printf (">>\ n"); PrintLu (plu-> Lu + I); // recursive call for (j = 0; j
Lu [I]. x) ;}} k --;} void main (void) {void * hFor; // expression handle luINT nPara; // number of independent variables in the expression LuData * pPara; // The array pointer luINT ErrBegin and ErrEnd that stores the input independent variables; // The initial and end positions of the expression compilation error int ErrCode; // The error code LuData Val; // Lu basic data type wchar_t ForStr [] = L "global (true), lu {1, lu [-2.2, lu (3, lu (-4, 4.4 ), 33),-22], 11.0, lu [-2, 22.2], 111} "; // string expression if (! InitLu () return; // initialize LuErrCode = LuCom (ForStr, 0, 0, & hFor, & nPara, & pPara, & ErrBegin, & ErrEnd ); // The compilation expression if (ErrCode) {printf ("the expression has an error! Error code: % d \ n ", ErrCode);} else {Val = LuCal (hFor, pPara); // calculate the expression value if (Val. BType = luDynData_lu) PrintLu (& Val); // output lu object Value} FreeLu (); // release Lu}
Running result:
Lu: 1
Lu:>
Lu:-2.200000
Lu:>
Lu: 3
Lu:>
Lu:-4
Lu: 4.400000
Lu: <
Lu: 33
Lu: <
Lu:-22
Lu: <
Lu: 11.000000
Lu:>
Lu:-2
Lu: 22.200000.
Lu: <
Lu: 111
4Function Description
In this example, five output functions of Lu are used: the Lu initialization function InitLu, And the Lu function FreeLu is released, compile the expression function LuCom, calculate the expression function LuCal, and search for the key-value function SearchKey. For more information about these functions, see the Lu programming guide.
5Difficulties
In this example, a function PrintLu is specially designed to output the value of the Lu object, which uses the deep-priority recursive call method.
According to the regulations, dynamic objects generated in the Lu script function are all local objects, which will be automatically destroyed after the function is executed (will be temporarily stored in the junk Object Buffer ), to make the dynamic object still valid after the function is executed, the function global (true) is used in the Lu string expression. The function usage is as follows:
Global (p) converts a local dynamic object p to a global dynamic object. In addition, dynamic objects generated between global (true),... and global (false) are all global dynamic objects.
In addition, local (p) converts Global Dynamic Object p to a local dynamic object.
A better string expression that implements similar functions is defined as: lu {1, lu [-2.2, lu (3, lu (-4, 4.4), 33),-22], 11.0, lu [-2, 22.2], 111 }. yield ()
The yield function indicates that the expression is a coroutine. The coroutine is suspended during the first running, and local objects are not released, so the same effect is achieved. The advantage of coroutine is that when the coroutine operation ends or the expression is destroyed, local dynamic objects in the coroutine are automatically destroyed.
For simplicity, the lu object in this example only contains three objects: integer, real number, and lu object. In fact, the lu table can contain any data.
6 others
You may have noticed that my contact information is below. If you have any questions or suggestions, please feel free to contact me.
Copyright?Lu Program Design2002-2013, retain all rights
E-mail: forcal@sina.com QQ: 630715621
Last Updated: December 1, December 29, 2013