MarshalCleanup INativeType.EmitMarshalling(ILGenerator /*!*/ method, LocalOrArg argIndex, List <object> /*!*/ constantPool, int constantPoolArgument) { Type argumentType = argIndex.Type; Label nextTry = method.DefineLabel(); Label done = method.DefineLabel(); if (!argumentType.IsValueType) { argIndex.Emit(method); method.Emit(OpCodes.Ldnull); method.Emit(OpCodes.Bne_Un, nextTry); method.Emit(OpCodes.Ldc_I4_0); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Br, done); } method.MarkLabel(nextTry); nextTry = method.DefineLabel(); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } constantPool.Add(this); SimpleType st = _type as SimpleType; MarshalCleanup res = null; if (st != null && !argIndex.Type.IsValueType) { if (st._type == SimpleTypeKind.Char || st._type == SimpleTypeKind.WChar) { if (st._type == SimpleTypeKind.Char) { SimpleType.TryToCharPtrConversion(method, argIndex, argumentType, done); } else { SimpleType.TryArrayToWCharPtrConversion(method, argIndex, argumentType, done); } Label notStr = method.DefineLabel(); LocalOrArg str = argIndex; if (argumentType != typeof(string)) { LocalBuilder lb = method.DeclareLocal(typeof(string)); method.Emit(OpCodes.Isinst, typeof(string)); method.Emit(OpCodes.Brfalse, notStr); argIndex.Emit(method); method.Emit(OpCodes.Castclass, typeof(string)); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); str = new Local(lb); } if (st._type == SimpleTypeKind.Char) { res = SimpleType.MarshalCharPointer(method, str); } else { SimpleType.MarshalWCharPointer(method, str); } method.Emit(OpCodes.Br, done); method.MarkLabel(notStr); argIndex.Emit(method); } } // native argument being pased (byref) method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckNativeArgument")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // lone cdata being passed method.MarkLabel(nextTry); nextTry = method.DefineLabel(); method.Emit(OpCodes.Pop); // extra null native arg argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("TryCheckCDataPointerType")); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Br, done); // pointer object being passed method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); // extra null cdata argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Ldarg, constantPoolArgument); method.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); method.Emit(OpCodes.Ldelem_Ref); method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CheckCDataType")); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldind_I); method.MarkLabel(done); return(res); }