Lua 实验(3) 注册c#方法到lua

1.首先在C的工程中 加入一些接口方法

#define EXPORTBUILD

//加载头文件 
#include "LuaInterface.h"
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "luaconf.h"

_DLLExport void LI_doString(lua_State *L , char* chunk)
{
	luaL_dostring(L, chunk); 
}

_DLLExport double LI_tonumber(lua_State *L, int idx)
{
	return lua_tonumberx(L,idx,NULL);
}

_DLLExport void LI_register(lua_State *L, const char *str , lua_CFunction fn)
{
	lua_register(L,str,fn);
}
因为Lua只提供了一些基本的方法导出到dll,以上的一些方法只定义了宏,所以将这些方法定义好。

2. 然后将lua工程还有上面的文件导出为DLL放入U3D plugin下。

3. U3D下,新建Test.cs

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
using System;

public delegate int LuaCSFunction(IntPtr luaState);

[AttributeUsage(AttributeTargets.Method)]
public sealed class MonoPInvokeCallbackAttribute : Attribute
{
    public MonoPInvokeCallbackAttribute(Type type)
    {
    }
}

public class Test : MonoBehaviour {
    const string dllName = "lualib";

    [DllImport (dllName)]
    public static extern int MyLuaDoString(string abc);
    [DllImport(dllName)]
    public static extern BITMAP TestMap(int x, int y);
    [DllImport(dllName)]
    public static extern IntPtr DllluaL_newstate();
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern void DllluaL_openlibs(IntPtr L);
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern void DllluaL_dostring(IntPtr luaState , string abc);
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern void Dlllua_close(IntPtr luaState);
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern double Dlllua_tonumber(IntPtr luaState, int idx);

    [DllImport(dllName)]
    public static extern IntPtr luaL_newstate();
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern void luaL_openlibs(IntPtr L);
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern int luaL_loadstring(IntPtr luaState, string chunk);
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern int lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc);
    [DllImport(dllName)]
    public static extern void my_doString(IntPtr luaState, string chunk);
    [DllImport(dllName)]
    public static extern void LI_doString(IntPtr luaState, string chunk);
    [DllImport(dllName)]
    public static extern double LI_tonumber(IntPtr luaState, int idx);
    [DllImport(dllName)]
    public static extern double LI_register(IntPtr luaState, string str , IntPtr fn);

    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern void lua_close(IntPtr luaState);
    [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
    public static extern double lua_tonumber(IntPtr luaState, int idx);

    public void RegFunction(IntPtr luaState, string name, LuaCSFunction func)
    {
        IntPtr fn = Marshal.GetFunctionPointerForDelegate(func);
        LI_register(luaState, name, fn);
    }

    public int TestAddInCS(int a,int b)
	{
		Debug.LogWarning("----"+a);
		return a+b;
	}


    void Awake()
 	{
 		/*int aa = MyLuaDoString("print(1+2);return 4;");
 		Debug.LogWarning("-----");
 		Debug.LogWarning("-----"+aa);

        BITMAP tm = TestMap(2, 3);

        IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(tm));
        Marshal.StructureToPtr(tm, intPtr, false);*/

        IntPtr ptr2 = luaL_newstate();
        luaL_openlibs(ptr2);
        //luaL_loadstring(ptr2, "hellO");
        Debug.LogWarning("-----");
        RegFunction(ptr2, "UDebug", UDebug);
        LI_doString(ptr2, "UDebug();print(1+2);return 100;");
        double res = LI_tonumber(ptr2, -1);
        Debug.LogWarning("-----" + res);

        lua_close(ptr2);

    }
 	
 	void Update ()
    {

    }

    [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
    public static int UDebug(IntPtr L)
    {
        Debug.LogWarning("hello");
        return 0;
    }

}

   
首先,要注册方法到Lua,那么就要用到

    public static extern double LI_register(IntPtr luaState, string str , IntPtr fn);

这个方法,

 在lua dll工程中,对应的是

_DLLExport void LI_register(lua_State *L, const char *str , lua_CFunction fn)

这个方法,其中c工程中如果是类什么的,我们都用指针去对应他。包括之前的lua_State 也是如此。


而在C#端,传方法要用的是委托的形式,所以用

public void RegFunction(IntPtr luaState, string name, LuaCSFunction func)

这个方法进行转换委托->指针 。

然后调用LI_register即可。

[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))] 只是一个说明,说明这个方法是作为LuaCSFunction 委托使用的。其实不要这个说明也没关系。


整个流程就是 C# 委托->C# IntPtr指针 (非委托形式) -> lua dll 指针


4. 最后得出结果 (hello 是c# 这边的方法打印出来的,lua调用这个方法。)



5. 如果需要传递参数,LUA有个好就是参数也会绑定到类实例上。

修改UDebug如下;

public static int UDebug(IntPtr L)
    {
        Debug.LogWarning("---------In UDebug");
        double res = LI_tonumber(L, 1);

        Debug.LogWarning(string.Format("-----:{0}" ,res));

        return 0;
    }
参数是存在了luastate 对象里面的。通过栈的形式,所以需要L_tonumber 调出其中的参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值