Browse Source

Skipped patching of v-tables for objects not put in the native-managed map.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/573/head
Dimitar Dobrev 10 years ago
parent
commit
912248b5da
  1. 5
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 63
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 11
      tests/CSharp/CSharp.cpp
  4. 4
      tests/CSharp/CSharp.h

5
src/Generator/Generators/CSharp/CSharpMarshal.cs

@ -325,11 +325,12 @@ namespace CppSharp.Generators.CSharp
var dtor = originalClass.Destructors.FirstOrDefault(); var dtor = originalClass.Destructors.FirstOrDefault();
if (dtor != null && dtor.IsVirtual) if (dtor != null && dtor.IsVirtual)
{ {
Context.SupportBefore.WriteLine("else {0}{1} = ({2}) {3}.{4}({5});", Context.SupportBefore.WriteLine("else {0}{1} = ({2}) {3}.{4}({5}{6});",
MarshalsParameter MarshalsParameter
? string.Empty ? string.Empty
: string.Format("{0}.NativeToManagedMap[{1}] = ", qualifiedClass, Context.ReturnVarName), : string.Format("{0}.NativeToManagedMap[{1}] = ", qualifiedClass, Context.ReturnVarName),
ret, qualifiedIdentifier, qualifiedClass, Helpers.CreateInstanceIdentifier, Context.ReturnVarName); ret, qualifiedIdentifier, qualifiedClass, Helpers.CreateInstanceIdentifier, Context.ReturnVarName,
MarshalsParameter ? ", skipVTables: true" : string.Empty);
} }
else else
{ {

63
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -1368,17 +1368,10 @@ namespace CppSharp.Generators.CSharp
private void SaveOriginalVTablePointers(ICollection<VFTableInfo> vfTables) private void SaveOriginalVTablePointers(ICollection<VFTableInfo> vfTables)
{ {
if (Driver.Options.IsMicrosoftAbi) if (Driver.Options.IsMicrosoftAbi)
{ WriteLine("__OriginalVTables = new void*[] {{ {0} }};",
WriteLine("__OriginalVTables = new void*[{0}];", vfTables.Count); string.Join(", ", vfTables.Select((v, i) => string.Format("native->vfptr{0}.ToPointer()", i))));
for (var i = 0; i < vfTables.Count; i++)
WriteLine("__OriginalVTables[{0}] = native->vfptr{0}.ToPointer();", i);
}
else else
{ WriteLine("__OriginalVTables = new void*[] { native->vfptr0.ToPointer() };");
WriteLine("__OriginalVTables = new void*[1];");
WriteLine("__OriginalVTables[0] = native->vfptr0.ToPointer();");
}
} }
private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries) private void AllocateNewVTablesMS(Class @class, IList<VTableComponent> wrappedEntries)
@ -1443,23 +1436,10 @@ namespace CppSharp.Generators.CSharp
} }
} }
private void GenerateVTableClassSetupCall(Class @class, bool addPointerGuard = false) private void GenerateVTableClassSetupCall(Class @class)
{ {
if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0) if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0)
{
// called from internal ctors which may have been passed an IntPtr.Zero
if (addPointerGuard)
{
WriteLine("if ({0} != global::System.IntPtr.Zero && !isInternalImpl)",
Helpers.InstanceIdentifier);
PushIndent();
}
WriteLine("SetupVTables();"); WriteLine("SetupVTables();");
if (addPointerGuard)
PopIndent();
}
} }
private void GenerateVTableManagedCall(Method method) private void GenerateVTableManagedCall(Method method)
@ -1898,12 +1878,13 @@ namespace CppSharp.Generators.CSharp
if (!@class.IsAbstractImpl) if (!@class.IsAbstractImpl)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("public static {0}{1} {2}(global::System.IntPtr native{3})", WriteLine("public static {0}{1} {2}(global::System.IntPtr native{3}{4})",
@class.NeedsBase && !@class.BaseClass.IsInterface ? "new " : string.Empty, @class.NeedsBase && !@class.BaseClass.IsInterface ? "new " : string.Empty,
@class.Name, Helpers.CreateInstanceIdentifier, @class.Name, Helpers.CreateInstanceIdentifier,
@class.IsRefType ? ", bool ownsNativeInstance = false" : string.Empty); @class.IsRefType ? ", bool ownsNativeInstance = false" : string.Empty,
", bool skipVTables = false");
WriteStartBraceIndent(); WriteStartBraceIndent();
WriteLine("return new {0}(({1}.Internal*) native){2};", ctorCall, className, WriteLine("return new {0}(({1}.Internal*) native, skipVTables){2};", ctorCall, className,
@class.IsRefType @class.IsRefType
? string.Format(" {{ {0} = ownsNativeInstance }}", Helpers.OwnsNativeInstanceIdentifier) ? string.Format(" {{ {0} = ownsNativeInstance }}", Helpers.OwnsNativeInstanceIdentifier)
: string.Empty); : string.Empty);
@ -1914,7 +1895,7 @@ namespace CppSharp.Generators.CSharp
GenerateNativeConstructorByValue(@class, className, ctorCall); GenerateNativeConstructorByValue(@class, className, ctorCall);
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("{0} {1}({2}.Internal* native, bool isInternalImpl = false){3}", WriteLine("{0} {1}({2}.Internal* native, bool skipVTables = false){3}",
@class.IsAbstractImpl ? "internal" : (@class.IsRefType ? "protected" : "private"), @class.IsAbstractImpl ? "internal" : (@class.IsRefType ? "protected" : "private"),
@class.Name, className, @class.IsValueType ? " : this()" : string.Empty); @class.Name, className, @class.IsValueType ? " : this()" : string.Empty);
@ -1929,18 +1910,29 @@ namespace CppSharp.Generators.CSharp
{ {
if (shouldGenerateClassNativeField) if (shouldGenerateClassNativeField)
{ {
WriteLine("if (native == null)");
WriteLineIndent("return;");
WriteLine("{0} = new global::System.IntPtr(native);", Helpers.InstanceIdentifier); WriteLine("{0} = new global::System.IntPtr(native);", Helpers.InstanceIdentifier);
var dtor = @class.Destructors.FirstOrDefault(); var dtor = @class.Destructors.FirstOrDefault();
if (dtor != null && dtor.IsVirtual) if (dtor != null && dtor.IsVirtual)
GenerateVTableClassSetupCall(@class, true); {
WriteLine("if (skipVTables)");
PushIndent();
SaveOriginalVTablePointers(@class.Layout.VFTables);
PopIndent();
WriteLine("else");
PushIndent();
GenerateVTableClassSetupCall(@class);
PopIndent();
}
else else
{ {
if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0) if (@class.IsDynamic && GetUniqueVTableMethodEntries(@class).Count != 0)
{ {
WriteLine("if (native != null)"); WriteLine("if (native != null)");
WriteStartBraceIndent(); PushIndent();
SaveOriginalVTablePointers(@class.Layout.VFTables); SaveOriginalVTablePointers(@class.Layout.VFTables);
WriteCloseBraceIndent(); PopIndent();
} }
} }
} }
@ -1959,9 +1951,10 @@ namespace CppSharp.Generators.CSharp
if (!@class.IsAbstractImpl) if (!@class.IsAbstractImpl)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("public static {0} {1}({0}.Internal native)", className, Helpers.CreateInstanceIdentifier); WriteLine("public static {0} {1}({0}.Internal native, bool skipVTables = false)",
className, Helpers.CreateInstanceIdentifier);
WriteStartBraceIndent(); WriteStartBraceIndent();
WriteLine("return new {0}(native);", ctorCall); WriteLine("return new {0}(native, skipVTables);", ctorCall);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
@ -1994,9 +1987,9 @@ namespace CppSharp.Generators.CSharp
if (!@class.IsAbstract) if (!@class.IsAbstract)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("{0} {1}({2}.Internal native)", WriteLine("{0} {1}({2}.Internal native, bool skipVTables = false)",
@class.IsAbstractImpl ? "internal" : "private", @class.Name, className); @class.IsAbstractImpl ? "internal" : "private", @class.Name, className);
WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native))" : ": this()"); WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native), skipVTables)" : ": this()");
WriteStartBraceIndent(); WriteStartBraceIndent();
if (@class.IsRefType) if (@class.IsRefType)
{ {

11
tests/CSharp/CSharp.cpp

@ -842,11 +842,20 @@ QObject::~QObject()
{ {
} }
void QObject::event()
{
}
QWidget::QWidget() QWidget::QWidget()
{ {
QApplication::instance->notify(this); QApplication::instance->notify(this);
} }
void QWidget::event()
{
QApplication::instance->notify(&child);
}
QApplication::QApplication() QApplication::QApplication()
{ {
instance = this; instance = this;
@ -856,7 +865,7 @@ QApplication* QApplication::instance = 0;
void QApplication::notify(QObject* receiver) void QApplication::notify(QObject* receiver)
{ {
delete receiver; receiver->event();
} }
HasSamePropertyInDerivedAbstractType::HasSamePropertyInDerivedAbstractType() HasSamePropertyInDerivedAbstractType::HasSamePropertyInDerivedAbstractType()

4
tests/CSharp/CSharp.h

@ -770,12 +770,16 @@ class DLL_API QObject
public: public:
QObject(); QObject();
virtual ~QObject(); virtual ~QObject();
virtual void event();
}; };
class DLL_API QWidget : public QObject class DLL_API QWidget : public QObject
{ {
public: public:
QWidget(); QWidget();
void event();
private:
QObject child;
}; };
class DLL_API QApplication : public QObject class DLL_API QApplication : public QObject

Loading…
Cancel
Save