Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize the mutual call between C # and Lua

2025-01-20 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces the relevant knowledge of "how to realize the mutual call between C# and Lua". The editor shows you the operation process through the actual case. The operation method is simple, fast and practical. I hope this article "how to realize the mutual call between C# and Lua" can help you solve the problem.

First, compile Lua dynamic link library 1. Compile the DLL file used under Windows

Use VS2015 to create an empty dynamic link library project, delete several files created by default (if you want to customize the extension available to retain), and then copy the source code of Lua to add to the project project. You need to configure LUA_BUILD_AS_DLL and _ CRT_SECURE_NO_WARNINGS to compile macros. DLL dynamic libraries for x86 and x64 can then be compiled, and the overall steps are simple and easy to operate.

two。 Compile the SO file used under Android

Compile the so dynamic library needed for Android through NDK, so you need to write two mk files, Application.mk and Android.mk, by hand. Here are the contents of the two files I used. Just create them and put them in the project above VS. The path is in the directory above the lua source code src.

# Application.mkAPP_PLATFORM = android-23APP_ABI: = armeabi-v7a arm64-v8aAPP_STL: = stlport_shared# Android.mkLOCAL_PATH: = $(call my-dir) include $(CLEAR_VARS) MY_FILES_PATH: = $(LOCAL_PATH) / srcMY_FILES_SUFFIX: =% .cMY_UN_INCLUDE: =% lua.c% luac.c# recursively traverses all files in the directory rwildcard=$ (wildcard $1 $2) $(foreach djue $(wildcard $1*), $(call rwildcard,$d/) 2)) # get the corresponding source file MY_ALL_FILES: = $(foreach src_path,$ (MY_FILES_PATH), $(call rwildcard,$ (src_path), *. *)) MY_SRC_LIST: = $(filter $(MY_FILES_SUFFIX), $(MY_ALL_FILES)) MY_SRC_LIST: = $(filter-out $(MY_UN_INCLUDE)) $(MY_SRC_LIST)) MY_SRC_LIST: = $(MY_SRC_LIST:$ (LOCAL_PATH) /% =%) LOCAL_SRC_FILES = $(MY_SRC_LIST) # print compilation information $(warning 'src_list='$ (LOCAL_SRC_FILES)) LOCAL_MODULE: = CSharpLuaLOCAL_LDLIBS + =-ldlLOCAL_CFLAGS: = $(L_CFLGAS) include $(BUILD_SHARED_LIBRARY)

After placing the above mk file, open the CMD command line and perform ndk compilation. Since it is not in the jni project directory of Android, executing the command is different, you can use the following command to execute the build, wait for the ndk execution to complete, and then generate the required so library.

Ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./ Application. MK 2. Write the API1 used in C #. The location of the dynamic link library in Unity.

Create a Plugins directory in the Assets directory of the Unity project to store DLL libraries for different platforms. The DLL directory required by Windows is the directory for the SO files required by Assets/Plugins/x86 and Assets/Plugins/x86_64;Android, and the directory in parentheses is Assets/Android/ [libs/arm64-v8a]. The directory in parentheses is actually the path generated by NDK compilation above.

two。 Write API for C # [LuaDll.cs]

The interfaces in most dynamic libraries can be used directly in this way, using IntPtr to represent lua_State* objects, and the parameter char* can be passed using byte [] or string, but with a slight difference.

[DllImport ("CSharpLua", EntryPoint = "luaL_newstate")] public static extern IntPtr luaL_newstate (); [DllImport ("CSharpLua", EntryPoint = "luaL_openlibs")] public static extern void luaL_openlibs (IntPtr L); [DllImport ("CSharpLua", EntryPoint = "luaL_loadbuffer")] public static extern int luaL_loadbuffer (IntPtr L, byte [] buff, uint size, string name); [DllImport ("CSharpLua", EntryPoint = "lua_call")] public static extern void lua_call (IntPtr L, int nargs, int nresults) [DllImport ("CSharpLua", EntryPoint = "lua_pcall") public static extern int lua_pcall (IntPtr L, int nargs, int nresults, int errfunc); 3. Several areas that need to be paid attention to

1. When returning char*, do not directly use string substitution, otherwise the call will cause a crash, so you need to do a transformation as shown in the following code before you can use it.

[DllImport ("CSharpLua", EntryPoint = "lua_tolstring")] private static extern IntPtr _ lua_tolstring (IntPtr L, int idx, ref uint size); public static string lua_tolstring (IntPtr L, int idx, ref uint size) {IntPtr buffer = _ lua_tolstring (L, idx, ref size); return Marshal.PtrToStringAnsi (buffer);}

2. When passing the C # function to Lua, you need to use the delegate delegate type.

Public delegate int LuaFunction (IntPtr L); [DllImport ("CSharpLua", EntryPoint = "lua_pushcclosure")] public static extern void lua_pushcclosure (IntPtr L, LuaFunction func, int idx); public static void lua_pushcfunction (IntPtr L, LuaFunction func) {lua_pushcclosure (L, func, 0);}

3. The macro code defined in the lua source code cannot be used and will be prompted that it cannot be found and needs to be implemented manually in C#, such as the two macros shown below.

# define lua_setglobal (L LUA_GLOBALSINDEX, (s)) # define lua_getglobal (L, LUA_GLOBALSINDEX, (s)) lua_getfield (L, LUA_GLOBALSINDEX, (s)) [DllImport ("CSharpLua", EntryPoint = "lua_getfield")] public static extern void lua_getfield (IntPtr L, int idx, string s); public static void lua_getglobal (IntPtr L, string s) {lua_getfield (L, LUA_GLOBALSINDEX, s) } [DllImport ("CSharpLua", EntryPoint = "lua_setfield")] public static extern void lua_setfield (IntPtr L, int idx, string s); public static void lua_setglobal (IntPtr L, string s) {lua_setfield (L, LUA_GLOBALSINDEX, s);}

4. If you need to pass the class instance object of C #, that is, userdata to lua, you need to convert it to IntPtr in C #, and if it is returned by Lua, you need to convert it back to the instance object of C # through IntPtr.

[DllImport ("CSharpLua", EntryPoint = "lua_pushlightuserdata")] public static extern void _ lua_pushlightuserdata (IntPtr L, IntPtr p); public static void lua_pushlightuserdata (IntPtr L, TP) {IntPtr obj = Marshal.GetIUnknownForObject (p); _ lua_pushlightuserdata (L, obj);} [DllImport ("CSharpLua", EntryPoint = "lua_touserdata")] public static extern IntPtr _ lua_touserdata (IntPtr L, int idx); public static T lua_touserdata (IntPtr L, int idx) {IntPtr p = _ lua_touserdata (L, idx) Return (T) Marshal.GetObjectForIUnknown (p);} III. Mutual call between C # and Lua for example 1. Create Lua environment IntPtr L = LuaDll.luaL_newstate (); LuaDll.luaL_openlibs (L); 2. Load Lua code and execute, call functions of Lua and pass parameters to Lua. Var data = Resources.Load (lua_file); int rc = LuaDll.luaL_loadbuffer (L, data.bytes, (uint) data.bytes.Length, lua_file); rc = LuaDll.lua_pcall (L, 0,0,0) LuaDll.lua_getglobal (L, "main"); / / pass parameter LuaDll.lua_pushinteger (L, 3333); LuaDll.lua_pushnumber (L3.3); / / execute main method int I = LuaDll.lua_pcall (L, 2,0,0); 3. To provide the C # function to Lua, you need to use the static method to refer to the definition of LuaFunction above. LuaDll.lua_pushcfunction (L, LuaPrint); LuaDll.lua_setglobal (L, "print"); [MonoPInvokeCallback] / / this is mainly needed on Android. Static int LuaPrint (IntPtr L) {Debug.Log ("."); return 0;} 4. The Lua code calls the C# method and provides a callback, which is called by the C# function. Static int FindAndBind (IntPtr L) {GameObject go = LuaDll.lua_touserdata (L, 1); string path = LuaDll.lua_tostring (L, 2); / / here put the function of lua on LUA_REGISTRYINDEX int idx = LuaDll.luaL_refEx (L); Transform t = go.transform.Find (path); Button btn = t.GetComponent (); btn.onClick.AddListener (delegate () {/ / the function that gets lua from the LUA_REGISTRYINDEX stack to execute. LuaDll.lua_rawgeti (L, LuaDll.LUA_REGISTRYINDEX, idx); LuaDll.lua_pcall (L, 0,0,0);}); return 0;} that's all for "how to call each other between C # and Lua". Thank you for reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report