Lua script to C code. Ask Question Asked 10 years, 4 months ago. Active 7 years, 10 months ago. Viewed 13k times 3. I am writing C functions for Lua. I have many calls like luagettable, luatouserdata, etc. My C function may receive complex structures like table with tables as fields. It is hard for me to program stacked machine. Using Lua with.Net C# part II In the previous post I showed how the Lua source code can be built for use by.Net, and how to make a very simple hello Lua script, and execute it from.Net code. Putting Lua to real use To actually do something interesting Lua must be able to call into.Net functions that is registered with Lua.
Using Lua with .Net C# part II
In the previous post I showed how the Lua source code can be built for use by .Net, and how to make a very simple hello Lua script, and execute it from .Net code.
Putting Lua to real use
To actually do something interesting Lua must be able to call into .Net functions that is registered with Lua.
This enables all sorts of exciting features, such as exposing your business / game objects to Lua and create Lua scripts for AI, custom business processing etc.
.Net function signature for Lua callbacks
Every .Net function that Lua should be able to call must match a specific function signature, and must also be registered with Lua.
This is how the function signature should look in .Net: C lua script.
Every .Net function exposed to Lua must return an int and takes a pointer to the Lua state as its single argument.
The Lua state object is used to get the parameters for the function along with any other variable values you need for your logic to work.
Communicating with Lua and the Lua stack
You do not operate on the Lua state itself, instead you call Lua C library functions which all takes the Lua state as parameter.
Lua uses a stack for all communication from .Net to Lua (and from any other language to Lua)If you want to create a new object in Lua (called a Lua table) you use the stack available from the Lua state to create it and set values of any desired fields.
In short, you will need wrapper functions in .Net to operate on the Lua stack, and Lua exports a whole bunch of functions that operates on this stack, which I will show later.
A complete guide for the lua stack can be found in the Lua documentation, section 3 at http://www.lua.org/manual/5.1/manual.html
Lua wrappers and the Lua.h source code file
Lua has an API function for registering a function from another language, its quite simple and when wrapped in .Net I created one that looks like this:
Dont worry too much about the m_refs.Add(func); call.
When I first started out creating a Lua wrapper I learned the hard way (debugging debugging debugging) that .Net garbage collects delegates, in use for Lua callbacks, before I intended .Net to do so.
When Lua calls back into .Net, the function pointer is suddenly no more valid, and a runtime exception occurs.
By maintaining a list of references to registered Lua callbacks in .Net, I make sure that the garbage collector wont collect the functions pointers before I want it to. The list Im using in my wrapper is defined as this:
When I close Lua I just empty the list of refs and they will be collected and I will be happy.
The wrapper for the register function looks like this:
You might wonder why theres no DLLImport Attribute.
Take a look at the definition from lua.h, its actually a macro using two other Lua API functions. These two functions must be wrapped as well. Lua uses macro definitions here and there, actually lua_pushcclosure and lua_setglobal is also just macros:
The lua_pushcclosure and lua_setfield functions is actual C API function and is lua.h defined and wrapped like this:
This is getting a bit boring I hope I did not lose you completely there, if I did Im sorry ?
The point is to show how Lua API functions can be put in a .Net wrapper that emulates the complete Lua API.
Registering a .Net callback funtion with Lua
Lets imagine that we have created a game and in that game we have created a class in .Net which contains methods for manipulating a “NPC player” object. Now we want to be able to create combat scripts, task scripts, AI scripts etc.
Furthermore we want users of the game to be able to create their own levels and define behaviour for NPC characters in that level.
Most users can learn to write a Lua script and we choose to expose some functionality from the “NPC player” class. We fire up an instance of Lua by creating a Lua state, and then we register some .Net functions with Lua.
Somewhere in our ScriptEngine we have defined:
Lua C++ Api
And open Lua:
Our NPCPlayer class definition:
None of our methods match the Lua signature so we have to create Lua ‘trampolines’ for them and handle the Lua communication specifics in them. We register a Lua function callback for the NPCPlayer class like this:
Calling the registered C# method from Lua
The Lua_InCombat method can now be used in a Lua script, Lua will pass the string parameter on its stack structure.
The Lua script could look something like this:
characterName = ‘Winnie the pooh’ winnieFighting = InCombat(characterName)
Its perfectly possible to mess up by calling the Lua function without any parameters or a parameter of a wrong type, there is no type checking, other than the defensive code you can and should implement in your .Net methods.
This concludes the post about registering and using c# methods from Lua.
Hope you found it usefull, please feel free to comment.
Thue Tuxen
Tags: .Net, C#, embedding, integrating, Integration, Lua, Lua C API, Lua source code, Lua.org, register c# function, script, scripting, Thue Tuxen, tuxen consulting
This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores. By buying the book, you also help to support the Lua project.
24.1 – A First Example
Free clash of clans download for windows 7. We will start this overview with a simple example of anapplication program:a stand-alone Lua interpreter.We can write a primitive stand-alone interpreter as follows:
WARNING: this code is for Lua 5.0.To run it in Lua 5.1,you must change the five calls
luaopen_*(L) to a single call to luaL_openlibs(L) .The header file lua.h defines the basic functions provided by Lua.That includes functions to create a new Lua environment(such as lua_open ),to invoke Lua functions (such as lua_pcall ),to read and write global variables in the Lua environment,to register new functions to be called by Lua, and so on.Everything defined in lua.h has the lua_ prefix.
The header file
lauxlib.h defines the functions providedby the auxiliary library (auxlib).All its definitions start with luaL_ (e.g., luaL_loadbuffer ).The auxiliary library uses the basic API provided by lua.h to provide a higher abstraction level;all Lua standard libraries use the auxlib.The basic API strives for economy and orthogonality,whereas auxlib strives for practicality for common tasks.Of course, it is very easy for your program to create otherabstractions that it needs, too.Keep in mind that the auxlib has no access to the internals of Lua.It does its entire job through the official basic API.
The Lua library defines no global variables at all.It keeps all its state in the dynamic structure
lua_State and a pointer to this structure is passed as an argumentto all functions inside Lua.This implementation makes Lua reentrantand ready to be used in multithreaded code.
The
lua_open function creates a new environment (or state).When lua_open creates a fresh environment,this environment contains no predefined functions,not even print .To keep Lua small, all standard librariesare provided as separate packages,so that you do not have to use them if you do not need to.The header file lualib.h defines functions to open the libraries.The call to luaopen_io , for instance, creates the io table and registers the I/O functions(io.read , io.write , etc.) inside it.
After creating a state and populating it with the standard libraries,it is time to interpret the user input.For each line the user enters,the program first calls
luaL_loadbuffer to compile the code.If there are no errors, the call returns zeroand pushes the resulting chunk on the stack.(Remember that we will discuss this 'magic' stack indetail in the next section.)Then the program calls lua_pcall ,which pops the chunk from the stack and runs it in protected mode.Like luaL_loadbuffer ,lua_pcall returns zero if there are no errors.In case of errors,both functions push an error message on the stack;we get this message with lua_tostring and,after printing it, we remove it from the stackwith lua_pop .
Notice that, in case of errors,this program simply prints the error message to the standard error stream.Real error handling can be quite complex in Cand how to do it depends on the nature of your application.The Lua core never writes anything directly to any output stream;it signals errors by returning error codes and error messages.Each application can handle these signals in away most appropriate for its needs.To simplify our discussions,we will assume for now a simpleerror handler like the following one,which prints an error message,closes the Lua state, and exits from the whole application:Later we will discuss more about error handling in theapplication code.
Lua C++ Class
Because you can compile Lua both as C and as C++ code,
lua.h does not include this typical adjustment codethat is present in several other C libraries:Therefore, if you have compiled Lua as C code(the most common case)and are using it in C++,you must include lua.h as follows:A common trick is to create a header file lua.hpp with the above code and to include this new file in yourC++ programs.
Download Lua
Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |