示例#1
0
 public static object[] RubyFunctionParamsToObjects(IntPtr mrb, IntPtr data_type_ptr)
 {
     R_VAL[]  value = RubyDLL.GetFunctionArgs(mrb);
     object[] ret   = new object[value.Length];
     for (int i = 0; i < ret.Length; i++)
     {
         ref R_VAL val = ref value[i];
         if (!R_VAL.IsData(val))
         {
             ret[i] = ValueToObject(mrb, val);
         }
         else
         {
             IntPtr ptr = RubyDLL.mrb_data_get_ptr(mrb, val, data_type_ptr);
             ret[i] = (( GCHandle )ptr).Target;
         }
     }
        /// <summary>
        /// Builds the argument list.
        /// </summary>
        /// <param name="state">The ruby state.</param>
        /// <param name="obj">The object.</param>
        /// <param name="args">The arguments.</param>
        /// <param name="outParams">Output: A list containing the indices of all "out" parameters, or null if no out parameters are specified.</param>
        /// <returns>The arguments, appropriately converted.</returns>
        protected virtual object[] BuildArgumentList(RubyState state, object obj, CallbackArguments args, out List <int> outParams)
        {
            ParameterDescriptor[] parameters = Parameters;

            object[] pars = new object[parameters.Length];

            int j = args.IsMethodCall ? 1 : 0;

            outParams = null;

            for (int i = 0; i < pars.Length; i++)
            {
                // keep track of out and ref params
                if (parameters[i].Type.IsByRef)
                {
                    if (outParams == null)
                    {
                        outParams = new List <int> ();
                    }
                    outParams.Add(i);
                }

                // if an ext method, we have an obj -> fill the first param
                if (ExtensionMethodType != null && obj != null && i == 0)
                {
                    pars[i] = obj;
                    continue;
                }
                else if (parameters[i].Type == typeof(CallbackArguments))
                {
                    pars[i] = args.SkipMethodCall();
                }
                // else, ignore out params
                else if (parameters[i].IsOut)
                {
                    pars[i] = null;
                }
                else if (i == parameters.Length - 1 && VarArgsArrayType != null)
                {
                    List <R_VAL> extraArgs = new List <R_VAL> ();

                    while (true)
                    {
                        var arg = args.RawGet(j, false);
                        j += 1;
                        if (!R_VAL.IsNil(arg))
                        {
                            extraArgs.Add(arg);
                        }
                        else
                        {
                            break;
                        }
                    }

                    // here we have to worry we already have an array.. damn. We only support this for userdata.
                    // remains to be analyzed what's the correct behavior here. For example, let's take a params object[]..
                    // given a single table parameter, should it use it as an array or as an object itself ?
                    if (extraArgs.Count == 1)
                    {
                        R_VAL arg = extraArgs[0];

                        if (R_VAL.IsData(arg))
                        {
                            // if ( Framework.Do.IsAssignableFrom ( VarArgsArrayType, arg.UserData.Object.GetType () ) ) {
                            // pars[ i ] = RubyDLL.ValueToDataObject< object > ( state, arg, RubyState.DATA_TYPE_PTR );
                            pars[i] = RubyState.ValueToRefObject(state, arg, DataTypePtr);
                            continue;
                            // }
                        }
                    }

                    // ok let's create an array, and loop
                    Array vararg = Array.CreateInstance(VarArgsElementType, extraArgs.Count);

                    for (int ii = 0; ii < extraArgs.Count; ii++)
                    {
                        vararg.SetValue(RubyState.ValueToObjectOfType(state, extraArgs[ii], DataTypePtr,
                                                                      VarArgsElementType,
                                                                      null, false), ii);
                    }

                    pars[i] = vararg;
                }
                // else, convert it
                else
                {
                    var arg = args.RawGet(j, false);
                    pars[i] = RubyState.ValueToObjectOfType(state, arg, DataTypePtr, parameters[i].Type,
                                                            parameters[i].DefaultValue, parameters[i].HasDefaultValue);
                    j += 1;
                }
            }

            return(pars);
        }