Xlua分析:Lua调用C#

本文详细介绍了Lua如何通过栈操作与C#交互,涉及参数传递、C#对象转换为Lua的userdata,以及Xlua框架中元表的生成和垃圾回收策略。重点讲解了C#对象如何通过XluaObjectTranslator传递给Lua,以及lua_gc的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在之前的博客Lua与C#交互初析-CSDN博客中讲了有关lua和c#交互的比较浅层的概念,即C#侧注册[LuaCallCSharp]和[CSharpCallLua]的标签后,即可实现双侧沟通。但是还是没有讲明白里面的一些具体内容包括参数传递、xlua栈调用,甚至是C#如何调用lua都没研究。本篇主题是lua如何调用C#的补充。

xLua交互知识

参考官方文档《programming in lua》的第24章开头,里面很详细地阐述了Lua和C++是如何实现交互的:栈操作。Lua API用一个抽象的栈在Lua与C之间交换值。栈中的每一条记录都可以保存任何 Lua 值。如果想要从Lua请求一个值(比如一个全局变量的值)则调用Lua,被请求的值将会被压入栈;如果想要传递一个值给 Lua,首先将这个值压入栈,然后调用 Lua(这个值就会被弹 出)。几乎所有的 API函数都用到了栈。而C#显而易见也可以和C++一侧进行交互,由此即可得出lua和C#可以通过C/C++这一层来进行通信,主要方法即是lua的堆栈操作。

C#对象如何传递给Lua

如果是int、float、bool这种C和C#互通的数据类型,实际上就直接走以上说的Lua API形式即可,直接栈操作就能实现数据交互,但是C#这边的对象则很难进行这样的操作,所以需要更多的步骤。参考Xlua ObjectTranslator.cs的Push操作:

public void Push(RealStatePtr L, object o)
{
    int index = -1;
    Type type = o.GetType();
#if !UNITY_WSA || UNITY_EDITOR
    bool is_enum = type.IsEnum;
    bool is_valuetype = type.IsValueType;
#else
    bool is_enum = type.GetTypeInfo().IsEnum;
    bool is_valuetype = type.GetTypeInfo().IsValueType;
#endif
    bool needcache = !is_valuetype || is_enum;
    if (needcache && (is_enum ? enumMap.TryGetValue(o, out index) : reverseMap.TryGetValue(o, out index)))
    {
        if (LuaAPI.xlua_tryget_cachedud(L, index, cacheRef) == 1)
        {
            return;
        }
        //这里实在太经典了,weaktable先删除,然后GC会延迟调用,当index会循环利用的时候,不注释这行将会导致重复释放
        //collectObject(index);
    }

    bool is_first;
    int type_id = getTypeId(L, type, out is_first);

    //如果一个type的定义含本身静态readonly实例时,getTypeId会push一个实例,这时候应该用这个实例
    if (is_first && needcache && (is_enum ? enumMap.TryGetValue(o, out index) : reverseMap.TryGetValue(o, out index))) 
    {
        if (LuaAPI.xlua_tryget_cachedud(L, index, cacheRef) == 1)
        {
            return;
        }
    }

    index = addObject(o, is_valuetype, is_enum);
    LuaAPI.xlua_pushcsobj(L, index, type_id, needcache, cacheRef);
}

首先push一个object的时候会判断这个object是否有相关缓存,有的话就不用继续了,没有的话就还是需要addObject的操作的。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值