From 73fb2eb2a121277064332028f26f42e9b2289687 Mon Sep 17 00:00:00 2001 From: Alexander Corrado Date: Mon, 22 Aug 2011 02:22:08 -0400 Subject: [PATCH] Fix ICppObject native-to-managed marshaling when there is no vtable --- src/Mono.Cxxi/Abi/CppAbi.cs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Mono.Cxxi/Abi/CppAbi.cs b/src/Mono.Cxxi/Abi/CppAbi.cs index 2016a1be..63be6fdd 100644 --- a/src/Mono.Cxxi/Abi/CppAbi.cs +++ b/src/Mono.Cxxi/Abi/CppAbi.cs @@ -747,11 +747,11 @@ namespace Mono.Cxxi.Abi { // Expects cppip = CppInstancePtr local protected virtual void EmitCreateCppObjectFromNative (ILGenerator il, Type targetType, LocalBuilder cppip) { + CppTypeInfo targetTypeInfo = null; if (targetType == typeof (ICppObject)) targetType = typeof (CppInstancePtr); - - il.Emit (OpCodes.Ldloca, cppip); - il.Emit (OpCodes.Call, cppip_native); + else + targetTypeInfo = GetTypeInfo (targetType); // FIXME: woof. do we really have to do this? // check for a native constructor (i.e. a public ctor in the wrapper that takes CppInstancePtr) if (typeof (ICppObject).IsAssignableFrom (targetType)) { @@ -761,14 +761,19 @@ namespace Mono.Cxxi.Abi { // Basically emitting this: // CppInstancePtr.ToManaged (native) ?? new targetType (native) + // ..but ToManaged is only called if there's a vtable (FIXME: otherwise we rewrap) var hasWrapper = il.DefineLabel (); - - il.Emit (OpCodes.Call, cppip_tomanaged.MakeGenericMethod (targetType)); - il.Emit (OpCodes.Dup); - il.Emit (OpCodes.Brtrue_S, hasWrapper); - il.Emit (OpCodes.Pop); - + + if (targetTypeInfo != null && targetTypeInfo.VirtualMethods.Any ()) { + il.Emit (OpCodes.Ldloca, cppip); + il.Emit (OpCodes.Call, cppip_native); + il.Emit (OpCodes.Call, cppip_tomanaged.MakeGenericMethod (targetType)); + il.Emit (OpCodes.Dup); + il.Emit (OpCodes.Brtrue_S, hasWrapper); + il.Emit (OpCodes.Pop); + } + il.Emit (OpCodes.Ldloc, cppip); il.Emit (OpCodes.Newobj, ctor); @@ -776,6 +781,9 @@ namespace Mono.Cxxi.Abi { } else if (targetType.IsValueType) { + // (targetType)Marshal.PtrToStructure (CppInstancePtr.Native, typeof (targetType)) + il.Emit (OpCodes.Ldloca, cppip); + il.Emit (OpCodes.Call, cppip_native); il.Emit (OpCodes.Ldtoken, targetType); il.Emit (OpCodes.Call, type_gettypefromhandle); il.Emit (OpCodes.Call, marshal_ptrtostructure);