MarshalCleanup INativeType.EmitMarshalling(ILGenerator /*!*/ method, LocalOrArg argIndex, List <object> /*!*/ constantPool, int constantPoolArgument) { MarshalCleanup cleanup = null; Label marshalled = method.DefineLabel(); Type argumentType = argIndex.Type; if (!argumentType.IsValueType && _type != SimpleTypeKind.Object && _type != SimpleTypeKind.Pointer) { // check if we have an explicit CData instance. If we have a CData but it's the // wrong type CheckSimpleCDataType will throw. Label primitive = method.DefineLabel(); argIndex.Emit(method); constantPool.Add(this); 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("CheckSimpleCDataType")); method.Emit(OpCodes.Brfalse, primitive); argIndex.Emit(method); method.Emit(OpCodes.Castclass, typeof(CData)); method.Emit(OpCodes.Call, typeof(CData).GetMethod("get_UnsafeAddress")); method.Emit(OpCodes.Ldobj, ((INativeType)this).GetNativeType()); method.Emit(OpCodes.Br, marshalled); method.MarkLabel(primitive); } argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } switch (_type) { case SimpleTypeKind.Boolean: case SimpleTypeKind.Char: case SimpleTypeKind.SignedByte: case SimpleTypeKind.UnsignedByte: case SimpleTypeKind.SignedShort: case SimpleTypeKind.UnsignedShort: case SimpleTypeKind.WChar: case SimpleTypeKind.SignedInt: case SimpleTypeKind.UnsignedInt: case SimpleTypeKind.UnsignedLong: case SimpleTypeKind.SignedLong: case SimpleTypeKind.Single: case SimpleTypeKind.Double: case SimpleTypeKind.UnsignedLongLong: case SimpleTypeKind.SignedLongLong: case SimpleTypeKind.VariantBool: constantPool.Add(this); 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("Get" + _type)); break; case SimpleTypeKind.Pointer: Label done = method.DefineLabel(); TryBytesConversion(method, done); Label nextTry = method.DefineLabel(); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Isinst, typeof(string)); method.Emit(OpCodes.Dup); method.Emit(OpCodes.Brfalse, nextTry); LocalBuilder lb = method.DeclareLocal(typeof(string), true); method.Emit(OpCodes.Stloc, lb); method.Emit(OpCodes.Ldloc, lb); method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Ldc_I4, RuntimeHelpers.OffsetToStringData); method.Emit(OpCodes.Add); method.Emit(OpCodes.Br, done); method.MarkLabel(nextTry); method.Emit(OpCodes.Pop); argIndex.Emit(method); if (argumentType.IsValueType) { method.Emit(OpCodes.Box, argumentType); } method.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("GetPointer")); method.MarkLabel(done); break; case SimpleTypeKind.Object: // TODO: Need cleanup here method.Emit(OpCodes.Call, typeof(CTypes).GetMethod("PyObj_ToPtr")); break; case SimpleTypeKind.CharPointer: done = method.DefineLabel(); TryToCharPtrConversion(method, argIndex, argumentType, done); cleanup = MarshalCharPointer(method, argIndex); method.MarkLabel(done); break; case SimpleTypeKind.WCharPointer: done = method.DefineLabel(); TryArrayToWCharPtrConversion(method, argIndex, argumentType, done); MarshalWCharPointer(method, argIndex); method.MarkLabel(done); break; case SimpleTypeKind.BStr: throw new NotImplementedException("BSTR marshalling"); } method.MarkLabel(marshalled); return(cleanup); }