static Argument MarshalInArg(TypeInfo typeInfo, DynamicMetaObject obj, ref Action free) { var arg = new Argument(); if (typeInfo.IsPointer) { switch (typeInfo.Tag) { case TypeTag.Interface: var iface = typeInfo.Interface; switch (iface.InfoType) { case InfoType.Boxed: case InfoType.Interface: case InfoType.Object: case InfoType.Struct: case InfoType.Union: if (obj.Value == null) { arg.Pointer = IntPtr.Zero; } else { dynamic dObj = obj.Value; arg.Pointer = dObj.Handle; } break; default: throw new NotImplementedException(); } break; case TypeTag.UTF8: var utf8Ptr = GMarshal.StringToUtf8Ptr((string)obj.Value); arg.Pointer = utf8Ptr; free += () => GMarshal.Free(utf8Ptr); break; case TypeTag.Array: var elementType = typeInfo.GetParamType(0); switch (typeInfo.ArrayType) { case ArrayType.C: if (elementType.Tag == TypeTag.UTF8) { var strvPtr = GMarshal.StringArrayToGStrvPtr((string[])obj.Value); arg.Pointer = strvPtr; free += () => GMarshal.FreeGStrv(strvPtr); } else { throw new NotImplementedException(); } break; default: throw new NotImplementedException(); } break; default: throw new NotImplementedException(); } } else { switch (typeInfo.Tag) { case TypeTag.Boolean: arg.Boolean = (bool)obj.Value; break; case TypeTag.Int8: arg.Int8 = (sbyte)obj.Value; break; case TypeTag.UInt8: arg.UInt8 = (byte)obj.Value; break; case TypeTag.Int16: arg.Int16 = (short)obj.Value; break; case TypeTag.UInt16: arg.UInt16 = (ushort)obj.Value; break; case TypeTag.Int32: arg.Int32 = (int)obj.Value; break; case TypeTag.UInt32: arg.UInt32 = (uint)obj.Value; break; case TypeTag.Int64: arg.Int64 = (long)obj.Value; break; case TypeTag.UInt64: arg.UInt64 = (ulong)obj.Value; break; case TypeTag.Interface: var iface = typeInfo.Interface; switch (iface.InfoType) { case InfoType.Enum: case InfoType.Flags: var valueInfo = (ValueInfo)obj.Value; arg.Int64 = valueInfo.Value; break; default: throw new NotImplementedException(); } break; default: throw new NotImplementedException(); } } return(arg); }