提交 fa1b6d85 编写于 作者: J johnche(车雄生)

新增xlua.get_generic_method,用于调用泛型函数

上级 0b5aaa54
......@@ -219,6 +219,31 @@
描述:
让一个类的私有字段,属性,方法等可用
例子:
xlua.private_accessible(CS.UnityEngine.GameObject)
#### xlua.get_generic_method
描述:
获取一个泛型方法
例子:
~~~lua
local foo_generic = xlua.get_generic_method(CS.GetGenericMethodTest, 'Foo')
local bar_generic = xlua.get_generic_method(CS.GetGenericMethodTest, 'Bar')
local foo = foo_generic(CS.System.Int32, CS.System.Double)
local bar = bar_generic(CS.System.Double, CS.UnityEngine.GameObject)
-- call instance method
local o = CS.GetGenericMethodTest()
local ret = foo(o, 1, 2)
print(ret)
-- call static method
bar(2, nil)
~~~
#### cast函数
......@@ -226,7 +251,7 @@
指明以特定的接口访问对象,这在实现类无法访问的时候(比如internal修饰)很有用,这时可以这么来(假设下面的calc对象实现了C#的PerformentTest.ICalc接口)
cast(calc, typeof(CS.PerformentTest.ICalc))
......
......@@ -154,6 +154,47 @@ go:GetButton().onClick:AddListener(function()
end)
```
如果xlua版本大于2.1.12的话,新增反射调用泛型方法的支持,比如对于这么个C#类型:
```csharp
public class GetGenericMethodTest
{
int a = 100;
public int Foo<T1, T2>(T1 p1, T2 p2)
{
Debug.Log(typeof(T1));
Debug.Log(typeof(T2));
Debug.Log(p1);
Debug.Log(p2);
return a;
}
public static void Bar<T1, T2>(T1 p1, T2 p2)
{
Debug.Log(typeof(T1));
Debug.Log(typeof(T2));
Debug.Log(p1);
Debug.Log(p2);
}
}
```
在lua那这么调用:
```lua
local foo_generic = xlua.get_generic_method(CS.GetGenericMethodTest, 'Foo')
local bar_generic = xlua.get_generic_method(CS.GetGenericMethodTest, 'Bar')
local foo = foo_generic(CS.System.Int32, CS.System.Double)
local bar = bar_generic(CS.System.Double, CS.UnityEngine.GameObject)
-- call instance method
local o = CS.GetGenericMethodTest()
local ret = foo(o, 1, 2)
print(ret)
-- call static method
bar(2, nil)
```
## 支持lua调用C#重载函数吗?
支持,但没有C#端支持的那么完善,比如重载方法void Foo(int a)和void Foo(short a),由于int和short都对应lua的number,是没法根据参数判断调用的是哪个重载。这时你可以借助扩展方法来为其中一个起一个别名。
......
......@@ -605,6 +605,9 @@ namespace XLua
LuaAPI.xlua_pushasciistring(L, "tofunction");
LuaAPI.lua_pushstdcallcfunction(L, StaticLuaCallbacks.ToFunction);
LuaAPI.lua_rawset(L, -3);
LuaAPI.xlua_pushasciistring(L, "get_generic_method");
LuaAPI.lua_pushstdcallcfunction(L, StaticLuaCallbacks.GetGenericMethod);
LuaAPI.lua_rawset(L, -3);
LuaAPI.xlua_pushasciistring(L, "release");
LuaAPI.lua_pushstdcallcfunction(L, StaticLuaCallbacks.ReleaseCsObject);
LuaAPI.lua_rawset(L, -3);
......
......@@ -1089,6 +1089,85 @@ namespace XLua
}
}
[MonoPInvokeCallback(typeof(LuaCSFunction))]
public static int GenericMethodWraper(RealStatePtr L)
{
try
{
ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
var genericMethod = translator.GetByType<MethodInfo>(L, LuaAPI.xlua_upvalueindex(1));
int n = LuaAPI.lua_gettop(L);
Type[] typeArguments = new Type[n];
for(int i = 0; i < n; i++)
{
Type type = getType(L, translator, i + 1);
if (type == null)
{
return LuaAPI.luaL_error(L, "param #" + (i + 1) + " is not a type");
}
typeArguments[i] = type;
}
var method = genericMethod.MakeGenericMethod(typeArguments);
translator.PushFixCSFunction(L,
new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, method.Name, new MethodBase[] { method }).Call));
return 1;
}
catch (Exception e)
{
return LuaAPI.luaL_error(L, "c# exception in GenericMethodWraper: " + e);
}
}
[MonoPInvokeCallback(typeof(LuaCSFunction))]
public static int GetGenericMethod(RealStatePtr L)
{
try
{
ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
Type type = getType(L, translator, 1);
if (type == null)
{
return LuaAPI.luaL_error(L, "xlua.get_generic_method, can not find c# type");
}
string methodName = LuaAPI.lua_tostring(L, 2);
if (string.IsNullOrEmpty(methodName))
{
return LuaAPI.luaL_error(L, "xlua.get_generic_method, #2 param need a string");
}
System.Collections.Generic.List<MethodInfo> matchMethods = new System.Collections.Generic.List<MethodInfo>();
var allMethods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
for(int i = 0; i < allMethods.Length; i++)
{
var method = allMethods[i];
if (method.Name == methodName && method.IsGenericMethodDefinition)
{
matchMethods.Add(method);
}
}
int methodIdx = 0;
if (matchMethods.Count == 0)
{
LuaAPI.lua_pushnil(L);
}
else
{
if (LuaAPI.lua_isinteger(L, 3))
{
methodIdx = LuaAPI.xlua_tointeger(L, 3);
}
translator.PushAny(L, matchMethods[methodIdx]);
LuaAPI.lua_pushstdcallcfunction(L, GenericMethodWraper, 1);
}
}
catch (Exception e)
{
return LuaAPI.luaL_error(L, "c# exception in xlua.get_generic_method: " + e);
}
return 1;
}
[MonoPInvokeCallback(typeof(LuaCSFunction))]
public static int ReleaseCsObject(RealStatePtr L)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册