GameCTO / luainterface

Automatically exported from code.google.com/p/luainterface
0 stars 0 forks source link

lost the function's return value when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code #26

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
luainterface v2.0.3
i got a issue in when call dotnet function like "int foo(arg1,out arg2,out 
arg3)" in lua code.
the return value will lost.

why?
In luaMethodWrapper class, Method "call":
---------------------------------------------------------------
for (int index = 0; index < len; index++)
            {
                nReturnValues++;
                //for(int i=0;i<lastCalledMethod.outList.Length;i++)
                _Translator.push(luaState, _LastCalledMethod.args[result[index]]);
            }

            return nReturnValues < 1 ? 1 : nReturnValues;
---------------------------------------------------------------
when call "int foo(arg,out arg1)", nReturnValues should be 2. but it was 1.

===========================Solution============================
my solution as follow:

luaMethodWrapper.call(IntPtr luaState){

for (int index = 0; index < len; index++)
            {
                nReturnValues++;
                //for(int i=0;i<lastCalledMethod.outList.Length;i++)
                _Translator.push(luaState, _LastCalledMethod.args[result[index]]);
            }

            //by isSingle 2010-09-10 11:26:31 
            //Desc: 
            //  if not return void,we need add 1,
            //  or we will lost the function's return value 
            //  when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code 
            if (!_LastCalledMethod.IsReturnVoid && nReturnValues>0) {
                nReturnValues++;
            }
            return nReturnValues < 1 ? 1 : nReturnValues;

}

MethodCache struct:
struct MethodCache{
 public MethodBase cachedMethod {
            get {
                return _cachedMethod;
            }
            set {
                _cachedMethod = value;
                MethodInfo mi=value as MethodInfo;
                if (mi != null) {
                    if (string.Compare(mi.ReturnType.Name, "System.Void", true) == 0) {
                        IsReturnVoid = true;
                    }
                    else {
                        IsReturnVoid =false;
                    }
                }
                else {

                }
            }
        }
        public bool IsReturnVoid;
}

By the way:
  we can use FastInvoke instead of Reflection when call a dotNet method. FastInvoke faster about 50%.
FastInvoker http://www.codeproject.com/KB/cs/FastMethodInvoker.aspx
========================FastInvoker Solution======================
struct MethodCache
    {
        MethodBase _cachedMethod;
        public MethodBase cachedMethod {
            get {
                return _cachedMethod;
            }
            set {
                _cachedMethod = value;
                MethodInfo mi=value as MethodInfo;
                if (mi != null) {
                    fastInvoke = FastInvoker.GetMethodInvoker(mi); //create a FstInvoker Delegate
                    if (string.Compare(mi.ReturnType.Name, "System.Void", true) == 0) {
                        IsReturnVoid = true;
                    }
                    else {
                        IsReturnVoid =false;
                    }
                }
                else {
                    //Debug.Assert(mi!=null,"不是MethodInfo");
                }
            }
        }
        public FastInvokeHandler fastInvoke; //fast invoke delegate
    ..
}

luaMethodWrapper.Call(IntPtr luastate){

...

    //_Translator.push(luaState, _LastCalledMethod.cachedMethod.Invoke(null, _LastCalledMethod.args));
   //use fastInvoker instead of reflection 
   _Translator.push(luaState, _LastCalledMethod.fastInvoke(null, _LastCalledMethod.args));

...

}

Original issue reported on code.google.com by isSin...@gmail.com on 10 Sep 2010 at 4:04

GoogleCodeExporter commented 9 years ago
I've implemented your fix for out parameters into the code, thanks for 
submitting!

Will have to look a little further into your fast invoker code a little later 
on.

Original comment by capre...@gmail.com on 8 Aug 2011 at 9:24

GoogleCodeExporter commented 9 years ago
Hi,

The latest modification doesn't work for me.
this line is bad : 
IsReturnVoid = string.Compare(mi.ReturnType.Name, "System.Void", true) == 0;

because the name is "Void" and not "System.Void"

must i remplace "Name" by "FullName" or "System.Void" by "Void" ?

Thanks in advance

Original comment by maxime.m...@gmail.com on 26 Oct 2011 at 2:15

GoogleCodeExporter commented 9 years ago
sorry,should be "Void"

Original comment by isSin...@gmail.com on 29 Oct 2011 at 5:19