带有in修饰参数的方法,被编译成ref。
1.环境
xlua 版本 v2.1.15 Editor 2021.3.3f1c1
2.复现步骤
- a.新建一个测试类
namespace TestIn
{
public static class InClass
{
public static void InMethod(in string name)
{
}
}
}
- b. GenConfig.cs中加入配置
[LuaCallCSharp] public static List<Type> LuaCallCSharp = new()
{
typeof(TestIn.InClass)
};
- c.点击Xlua -> Clear Generated Code -> Generate Code
- d.编译报错 Assets/XLua/Gen/TestIn_InClassWrap.cs(69,50): error CS1615: Argument 1 may not be passed with the 'ref' keyword
报错指向这一行: TestIn.InClass.InMethod(ref _name);
3.报错文件
using LuaAPI = UniLua.Lua;
using RealStatePtr = UniLua.ILuaState;
using LuaCSFunction = UniLua.CSharpFunctionDelegate;
#else
using LuaAPI = XLua.LuaDLL.Lua;
using RealStatePtr = System.IntPtr;
using LuaCSFunction = XLua.LuaDLL.lua_CSFunction;
#endif
using XLua;
using System.Collections.Generic;
namespace XLua.CSObjectWrap
{
using Utils = XLua.Utils;
public class TestInInClassWrap
{
public static void __Register(RealStatePtr L)
{
ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
System.Type type = typeof(TestIn.InClass);
Utils.BeginObjectRegister(type, L, translator, 0, 0, 0, 0);
Utils.EndObjectRegister(type, L, translator, null, null,
null, null, null);
Utils.BeginClassRegister(type, L, __CreateInstance, 2, 0, 0);
Utils.RegisterFunc(L, Utils.CLS_IDX, "InMethod", _m_InMethod_xlua_st_);
Utils.EndClassRegister(type, L, translator);
}
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int __CreateInstance(RealStatePtr L)
{
return LuaAPI.luaL_error(L, "TestIn.InClass does not have a constructor!");
}
[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
static int _m_InMethod_xlua_st_(RealStatePtr L)
{
try
{
{
string _name = LuaAPI.lua_tostring(L, 1);
TestIn.InClass.InMethod(ref _name);
LuaAPI.lua_pushstring(L, _name);
return 1;
}
}
catch (System.Exception gen_e)
{
return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
}
}
}
}
把in换成ref
找到 LuaClassWrap.tpl.txt 文件。其中有一句:
if pi ~= 0 then %>, <% end; if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.ParameterType.IsByRef then %>ref <% end %><%=LocalName(parameter.Name)%><% end) %> );
修改为:
if pi ~= 0 then %>, <% end; if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.IsIn and parameter.ParameterType.IsByRef then %>in <% elseif parameter.ParameterType.IsByRef then %>ref <% end %><%=LocalName(parameter.Name)%><% end) %> );
然后重新生成试试
委托生成文件:LuaDelegateBridge.tpl.txt,可以试着这样修改 修改1: if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.ParameterType.IsByRef then %>ref <% end 修改为: if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.IsIn and parameter.ParameterType.IsByRef then %>in <% elseif parameter.ParameterType.IsByRef then %>ref <% end 修改2: <%ForEachCsList(parameters, function(parameter, pi) if parameter.IsOut or parameter.ParameterType.IsByRef then %><%=GetCasterStatement(parameter.ParameterType, "errFunc" .. (" + "..out_idx), 'p' .. pi)%>; <% out_idx = out_idx + 1 end end) %> 修改为: <%ForEachCsList(parameters, function(parameter, pi) if parameter.IsOut or (parameter.ParameterType.IsByRef and not parameter.IsIn) then %><%=GetCasterStatement(parameter.ParameterType, "errFunc" .. (" + "..out_idx), 'p' .. pi)%>; <% out_idx = out_idx + 1 end end) %>