Luainterface User Guide

Source: Internet
Author: User

[Translation because of learning !]

 

1. Introduction

Luainterface is an integrated library between the Lua language and the Microsoft. NET platform Common Language Runtime (CLR. Many languages already have CLR-oriented compilers and CLR implementations. They already have Microsoft Windows, BSD, and Linux operating systems.

Lua is a programming language designed for extended applications. It implements interpretation and is easy to embed in a library. For more information, see lua' sreference manual.

The following section describes how to compile and install luainterface. Part 1 includes using it in CLR applications, and Part 2 describes the use of Lua scripts.

2. Install luainterface

Luainterface requires the Lua interpreter to work. A lua5.0 interpreter is included in the luainterface release package, including the luainterface binary file and. netclr (luainterface. dll and luanet. dll) in Mircrosoft windows ). You need to copy luainterface. DLL to your path directory to your global assembly cache. Luainterface uses Compat-5.1, So copy luanet. DLL to your package. cpath.
It is not difficult to compile luainterface from source code. The release package contains an engineering file used to compile luanet. It is under Visual Studio. NET 2003 and the compilation script used to compile is under Visual Studio 6. You can compile all src/luainte to get luainterface. dll.

3. Use Lua in CLR

The CLR application uses the Lua interpreter through the luainterface. Lua class. Instantiate this class and create a new Lua interpreter. Different instances are directly independent. Create, read, and modify all variables by the name of the variable, as shown in the following example (

The er always returns an object and must be forcibly converted to the correct type ):
Code:

// Start a Lua interpreterLua lua = new Lua();// Create global variables "num" and "str"lua["num"] = 2;lua["str"] = "a string";// Create an empty tablelua.NewTable("tab");// Read global variables "num" and "str"double num = (double)lua["num"];string str = (string)lua["str"];


Run the Lua script in the dostring and dofile methods. When the script returns a value, this method returns an array, as shown in figure
Code:

// Execute a Lua script filelua.DoFile("script.lua");// Execute chunks of Lua codelua.DoString("num=2");lua.DoString("str=’a string’");// Lua code returning valuesobject[] retVals = lua.DoString("return num,str");

 

Luainterface automatically converts Lua's nil to CLR's null, strings to system. string, numbers to system. double, booleans to system. boolean, tables to luainterface. luatable, functions to luainterface. luatable, and vice versa. Userdata is a special case: clrobjects does not have a matched Lua type, and userdata is converted back to the original type when passed to CLR. Luainterface converts other userdata to luainterface. luauserdata.
Luatable and luauserdata objects have indexes to read and modify fields and use strings or numbers for indexing. Luafunction and luauserdata objects contain a call method to execute functions, including the number of parameters,

The returned value is in an array.
Finally, the Lua class has a registerfunction to register the CLR function as a global Lua function. Its Parameters include the function name, target function, and methodinfo indicating the method, such as Lua. registerfunction ("foo", OBJ, obj. getType (). getmethod ("foo") registers the foo method of object OBJ as the foo function.

 

4. Use CLR in Lua

This part is included in the Lua script initialization and the use of CLR objects, or execution through the Lua interpreter, or in the CLR application. All the examples below are in the Lua language.


4.1 load CLR type and instantiate object

In order to instantiate the object, the script needs to reference the type. You also need to reference the static field static fields and call the static method static methods. To obtain the type reference, you must first add

Load an Assembly that contains the specified type. Use the load_assembly function. Use the import_type function to obtain the reference. The following example shows how to use these two functions:
Code:

require"luanet"-- Loads the System.Windows.Forms and System.Drawing assembliesluanet.load_assembly("System.Windows.Forms")luanet.load_assembly("System.Drawing")Form = luanet.import_type("System.Windows.Forms.Form")Point = luanet.import_type("System.Drawing.Point") -- structure-- Loading an enumerationStartPosition = luanet.import_type("System.Windows.Forms.FormStartPosition")

 

Call the type reference of the instantiated object. Luainterface uses the first constructor that satisfies the number and type of parameters. Due to the existence of overload constructor, the matching process converts the number string to the number, number to the character

String. If necessary, the numeric parameters in Lua are also converted to the corresponding CLR numeric type. Get constructor bysig returns the constructor of a given type and the signa-ture of the constructor (referenced by the type of the constructor's form parameter type. Call to return the object instantiated by the constructor. The following example demonstrates how to instantiate a CLR object:
Code:

-- SomeType is a reference to a type with the following constructors-- 1. SomeType(string)-- 2. SomeType(int)-- 3. SomeType(int,int)obj1 = SomeType(2,3) -- instantiates SomeType with constructor 3obj2 = SomeType("x") -- instantiates SomeType with constructor 1obj3 = SomeType(3) -- instantiates SomeType with constructor 1Int32 = import_type("System.Int32")-- Gets the SomeType constructor with signature (Int32)SomeType_cons2 = get_constructor_bysig(SomeType,Int32)obj3 = SomeType_cons2(3) -- instantiates SomeType with constructor 2
4.2 Use fields and Methods

The CLR object fields can be used in the script, and the syntax is the same as indexing data from the table. The data written into the field is converted to the corresponding field type, and the number assigned to the int32 field is converted to int32.

Is also used as a field.

Luainterface has a simple way to index one-dimensional arrays, such as arr [3]. Multi-dimensional arrays require the array class method.

The script can call the object method. The syntax is the same as the method used to call the table. It passes the first parameter of the object and uses the ':' operator. you can use the get and set methods to use the index attributes (usually get propertyname and set propertyname )..
Code:

-- button1, button2 and form1 are CLR objectsbutton1.Text = "OK";button2.Text = "Cancel";form1.Controls:Add(button1);form1.Controls:Add(button2);form1:ShowDialog();


Lua only calls a function based on the value parameter. Therefore, when the script calls a method that uses the out or ref parameters, luainterface returns the output values of these parameters together with the return values of the methods. Out parameter in method call

The number should be omitted, as shown in the following example:
Code:

-- calling int obj::OutMethod1(int,out int,out int)retVal,out1,out2 = obj:OutMethod1(inVal)-- calling void obj::OutMethod2(int,out int)retVal,out1 = obj:OutMethod2(inVal) -- retVal será nil-- calling int obj::RefMethod(int,ref int)retVal,ref1 = obj:RefMethod(inVal,ref1)


If a method is overloaded, the number and type of the First Matching parameter are called, ignoring the out parameter. The following example shows how a script calls the heavy load somemethod method of sometype of different versions.
Code:

-- Versions of SomeType.SomeMethod:-- 1. void SomeMethod(int)-- 2. void SomeMethod(string)-- 3. void SomeMethod(OtherType)-- 4. void SomeMethod(string,OtherType)-- 5. void SomeMethod(int,OtherType)-- 6. void SomeMethod(int,OtherTypeSubtype)-- obj1 is instance of SomeType-- obj2 is instance of OtherType-- obj3 is instance of OtherTypeSubtypeobj1:SomeMethod(2) -- version 1obj1:SomeMethod(2.5) -- version 1, round downobj1:SomeMethod("2") -- version 1, converts to intobj1:SomeMethod("x") -- version 2obj1:SomeMethod(obj2) -- version 3obj1:SomeMethod("x",obj2) -- version 4obj1:SomeMethod(2,obj2) -- version 4obj1:SomeMethod(2.5,obj2) -- version 4, round downobj1:SomeMethod(2,obj3) -- version 4, cast-- versions 5 and 6 never get called


In the case of the get_method_bysig function, one method has a version that will never be called. Given an object or type reference and method signature (method name and type), this function will return with this signature, as shown in the following example:
Code:

-- Versions of SomeType.SomeMethod:-- 5. void SomeMethod(int,OtherType)-- obj1 is instance of SomeType-- obj2 is instance of OtherTypeInt32 = luanet.import_type(’System.Int32’)SomeMethod_sig5 = luanet.get_method_bysig(obj1,’SomeMethod’,Int32,obj2:GetType())SomeMethod_sig5(obj1,2,obj2) -- calls version 5

If a method or field name is a reserved keyword of Lua, scripts can still use them using the OBJ ["name"] syntax. If an object has two methods that use the same signature but belong to different interfaces, such as ifoo. method () and Ibar. method (), Mark OBJ ["ifoo. method "] (OBJ) calls the first version.
When a method execution error occurs, luainterface throws an exception to an exception object with an error message. To capture errors, use pcall to call all methods.

 

4.3 handle events


The event in luainterface has an add and a remove method, which are used to register and cancel registration event processing respectively. Add uses the Lua method as the parameter and converts it to the Delegate-managed method corresponding to CLR and returns it. Remove takes event processing delegate hosting as the parameter and removes the processor as follows:
Code:

function handle_mouseup(sender,args)print(sender:ToString() .. ’ MouseUp!’)button.MouseUp:Remove(handler)endhandler = button.MouseUp:Add(handle_mouseup)


The script can also use the add and remove methods of the event object to register event processing (usually add eventname and remove eventname), but add does not return delegate hosted objects, therefore, functions cannot be deregistered after being registered in this way.

 

4.4 hosting delegates and subclass subtyping


Luainterface provides methods for dynamically creating types in 3 to extend CLR.
First, we have discussed in the context of the event processing program: Where is the Lua function delegate expected? luainterface creates a new delegate type and passes it to CLR.
The second method is to pass a Lua table, which implements the interface. Luainterface creates a new interface Implementation type. The object methods of this type are hosted on the table, as shown below:
Code:

-- interface ISample { int DoTask(int x, int y); }-- SomeType.SomeMethod signature: int SomeMethod(ISample i)-- obj is instance of SomeTypesum = {}function sum:DoTask(x,y)return x+yend-- sum is converted to instance of ISampleres = obj:SomeMethod(sum)


If there are overload functions in the interface, all versions of the function will host a Lua function, which determines which version of the function is called Based on the parameter type. Luainterface cannot pass out parameters to the function, but the function must return these values together with the output values of the ref parameter, as shown below:
Code:

-- interface ISample2 { void DoTask1(ref int x, out int y);-- int DoTask2(int x, out int y); }-- SomeType.SomeMethod signature: int SomeMethod(ISample i)-- obj is instance of SomeTypeinc = {}function inc:DoTask1(x)return x+1,xendfunction inc:DoTask2(x)return x+1,xendres = obj:SomeMethod(sum)


The last method to create a new CLR type is to subclass existing classes, use the Lua table function to override some or all of its virtual methods (if the Lua table does not override the method, luainterface uses the original version ). The table function calls the function of the parent class through a field named base.

To convert a table into a subclass instance, the script must call the make_object function and reference the class type of the subclass created as a parameter. The following example shows how to create a subclass:
Code:

-- class SomeObject {-- public virtual int SomeMethod(int x, int y) { return x+y; } }-- SomeType.SomeMethod signature: int SomeMethod(SomeObject o)-- obj is instance of SomeTypesome_obj = { const = 4 }function some_obj:SomeMethod(x,y)local z = self.base:SomeMethod(x,y)return z * self.constendSomeObject = luanet.import_type(’SomeObject’)luanet.make_object(some_obj,SomeObject)res = some_obj:SomeMethod(2,3) -- returns 20res = some_obj:ToString() -- calls base methodres = obj:SomeMethod(some_obj) -- passing as argument


During the subclass process of implementing interface applications, there are the same problems with overload and out/Ref parameters. Finally, the table parameter called by make_object In Front Of The free_object function serves the connection between the service table and the CLR subclass instance. The script must use this method before dropping table references. Otherwise, memory leakage may occur.
[End]

 

Application:

[Usage]
Import the resource package and copy the plugins folder under the 'ulua/plugins/'path to assets. Add the luainterface namespace to your script to view some basic usage in examples. The main code is very readable (Lua. CS) and luainterface manual.

[Lua 'require 'or 'dofile ']
To import a file, you must have the text asset in the 'Assets/resources' directory of your project root, which must be named * .lua.txt '.
For example:
'Assets/resources/mydir/myscript.lua.txt'

In your Lua code, you can request:
'Require ("mydir/myscript. Lua ")'

 

1]Download to the resource package of ulua, import the package to the project, and copy the contents in the plugins folder to the plugins folder of the project according to the instructions;

(The DLL cannot be found in this step. Restart unity here)

The root directory of the imported project contains the following:

2]Write some Lua scripts in the. txt file, for example:

(Note: The suffix of the TXT script is ". txt ")

3]Load the TXT file with Lua script to the game. The resource type is "textasset ":

Optional methods, such:

① Put it in the resources folder, and resources. Load () to load;

② Place it anywhere in the project and load it using resoueces. loadatpath;

③ Compress into assetbundle and place it on the file server. Use WWW for asynchronous loading.

(If ③ is used, it is recommended that a Virtual File Server tool named "HFS" be very convenient. Just click it to simulate a file server:

, Very easy to use)

4]Parsing Lua script:

1 luastate ls = new luastate (); 2 ls. dostring (luastring); // luastring is the character in the loaded document, type: string3 luafunction LF = ls. getfunction ("luafunc"); // luafunc is the method name 4 object [] r = lf. call ("2"); // "2" in parentheses is the value of 5 return R [0] to be passed to the method in Lua. tostring (); // R [0] is the value returned after the operation. The type is object. You need to change the type before using it.

It is very simple. In summary, the connection between Lua and C # In unity3d, and the mutual transmission of methods and parameters will be OK. You will see that there is really external logic that plays a role in a running game.

 

 

Luainterface User Guide

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.