Browse Source

Fix ICppObject native-to-managed marshaling when there is no vtable

pull/1/head
Alexander Corrado 14 years ago
parent
commit
73fb2eb2a1
  1. 26
      src/Mono.Cxxi/Abi/CppAbi.cs

26
src/Mono.Cxxi/Abi/CppAbi.cs

@ -747,11 +747,11 @@ namespace Mono.Cxxi.Abi { @@ -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 { @@ -761,14 +761,19 @@ namespace Mono.Cxxi.Abi {
// Basically emitting this:
// CppInstancePtr.ToManaged<targetType> (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 { @@ -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);

Loading…
Cancel
Save