Early, I struggled with one thing, if I in C + + exposed to the script interface, to use an object in C + +, and my program has a lot of different LUA virtual machines, each virtual machine associated with a C + + object, and this is multi-threaded, So how can we quickly use the Lua_state pointer to locate the object pointer?
I didn't have the ability to read Lua's source code, and I could say that I didn't know how to operate the key parts, and I did it by using critical areas and std::map to solve the problem, and it was obvious that the efficiency of this approach was very low.
Now the ability to read the LUA source code, of course, there is a more effective solution, because in the process of using LUA, lua_state This structure pointer is to go through all the places used in Lua, then I can extend this structure, so that it can save my data, only need to save a pointer.
Lua_state This structure, defined in lstate.h (Lua.h is simply an empty structure pointer defined by the author in order not to allow the user to actively access the struct members, the various open source scripting engines are like this, for security, you know)
Take lua5.2.3 as an example, the structure is originally defined as follows:
struct Lua_state {
Commonheader;
Lu_byte status;
Stkid top; /* First free slots in the stack */
Global_state *l_g;
Callinfo *ci; /* Call info for current function */
const instruction *OLDPC; /* Last PC traced */
Stkid Stack_last; /* Last free slots in the stack */
Stkid Stack; /* Stack base */
int stacksize;
unsigned short nny; /* Number of non-yieldable calls in stack */
unsigned short nccalls; /* Number of nested C calls */
Lu_byte Hookmask;
Lu_byte Allowhook;
int basehookcount;
int hookcount;
Lua_hook Hook;
Gcobject *openupval; /* List of open upvalues in this stack */
Gcobject *gclist;
struct LUA_LONGJMP *errorjmp; /* Current Error recover point */
ptrdiff_t Errfunc; /* Current error handling function (stack index) */
Callinfo Base_ci; /* Callinfo for First level (C calling Lua) */
};
Then the following is extended for this structure:
struct Lua_state {
Commonheader;
Lu_byte status;
Stkid top; /* First free slots in the stack */
Global_state *l_g;
Callinfo *ci; /* Call info for current function */
const instruction *OLDPC; /* Last PC traced */
Stkid Stack_last; /* Last free slots in the stack */
Stkid Stack; /* Stack base */
int stacksize;
unsigned short nny; /* Number of non-yieldable calls in stack */
unsigned short nccalls; /* Number of nested C calls */
Lu_byte Hookmask;
Lu_byte Allowhook;
int basehookcount;
int hookcount;
Lua_hook Hook;
Gcobject *openupval; /* List of open upvalues in this stack */
Gcobject *gclist;
struct LUA_LONGJMP *errorjmp; /* Current Error recover point */
ptrdiff_t Errfunc; /* Current error handling function (stack index) */
Callinfo Base_ci; /* Callinfo for First level (C calling Lua) */
int __mydata;//Here
};
At the same time, add two Lua interface, you can put the function interface into the LAPI.C, declare put into the lua.h can, or you are a fever to pursue limit efficiency don't care more extension and update friends, then you can use hard coded positioning, __mydata offset is 0x70.
Lua_api void Lua_setmydata (lua_state *l, int data) {
L->__mydata = data;
}
Lua_api int Lua_getmydata (lua_state *l) {
Return l->__mydata;
}
That's all there is to do, recompile Lua, and try the results:
A more abstract approach:
To locate using hard-coded: