Browse Source

Fixed an ambiguity between an internal ctor and a potential wrapped one.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/349/head
Dimitar Dobrev 11 years ago
parent
commit
30cb2cbe85
  1. 9
      src/Generator/Generators/CSharp/CSharpMarshal.cs
  2. 49
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 8
      tests/CSharpTemp/CSharpTemp.Tests.cs
  4. 21
      tests/CSharpTemp/CSharpTemp.cpp
  5. 11
      tests/CSharpTemp/CSharpTemp.h

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

@ -256,10 +256,11 @@ namespace CppSharp.Generators.CSharp
"Internal" : ""); "Internal" : "");
if (returnType.IsAddress()) if (returnType.IsAddress())
Context.Return.Write("({0} == IntPtr.Zero) ? {1} : ", instance, Context.Return.Write("({0} == IntPtr.Zero) ? {1} : {2}.{3}({0})", instance,
@class.IsRefType ? "null" : string.Format("new {0}()", type)); @class.IsRefType ? "null" : string.Format("new {0}()", type),
type, Helpers.CreateInstanceIdentifier);
Context.Return.Write("new {0}({1})", type, instance); else
Context.Return.Write("new {0}({1})", type, instance);
return true; return true;
} }

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

@ -45,6 +45,8 @@ namespace CppSharp.Generators.CSharp
public const string AllocatedWithHGlobalIdentifier = "__allocatedWithHGlobal"; public const string AllocatedWithHGlobalIdentifier = "__allocatedWithHGlobal";
public const string CreateInstanceIdentifier = "__CreateInstance";
public static string GetAccess(AccessSpecifier accessSpecifier) public static string GetAccess(AccessSpecifier accessSpecifier)
{ {
switch (accessSpecifier) switch (accessSpecifier)
@ -1889,32 +1891,36 @@ namespace CppSharp.Generators.CSharp
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);
} }
PushBlock(CSharpBlockKind.Method);
string className = @class.Name; string className = @class.Name;
string safeIdentifier = className; string safeIdentifier = className;
if (@class.Access == AccessSpecifier.Private && className.EndsWith("Internal")) bool isAbstractImpl = @class.Methods.Any(m => m.SynthKind == FunctionSynthKind.AbstractImplCall);
if (isAbstractImpl)
{ {
className = className.Substring(0, className = className.Substring(0,
safeIdentifier.LastIndexOf("Internal", StringComparison.Ordinal)); safeIdentifier.LastIndexOf("Internal", StringComparison.Ordinal));
} }
WriteLine("internal {0}({1}.Internal* native)", safeIdentifier,
className); if (!@class.IsAbstract)
WriteLineIndent(": this(new global::System.IntPtr(native))"); {
WriteStartBraceIndent(); PushBlock(CSharpBlockKind.Method);
WriteCloseBraceIndent(); WriteLine("public static {0} {1}(global::System.IntPtr native)", safeIdentifier, Helpers.CreateInstanceIdentifier);
PopBlock(NewLineKind.BeforeNextBlock); WriteStartBraceIndent();
WriteLine("return new {0}(({1}.Internal*) native);", safeIdentifier, className);
WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock);
}
GenerateNativeConstructorByValue(@class, className, safeIdentifier); GenerateNativeConstructorByValue(@class, className, safeIdentifier);
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("public {0}(global::System.IntPtr native, bool isInternalImpl = false){1}", WriteLine("{0} {1}({2}.Internal* native, bool isInternalImpl = false){3}",
safeIdentifier, @class.IsValueType ? " : this()" : string.Empty); @class.IsRefType ? "protected" : "private",
safeIdentifier, className, @class.IsValueType ? " : this()" : string.Empty);
var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType; var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType;
if (hasBaseClass) if (hasBaseClass)
WriteLineIndent(": base(native{0})", WriteLineIndent(": base(({0}.Internal*) native{1})",
@class.Methods.Any(m => m.SynthKind == FunctionSynthKind.AbstractImplCall) ? @class.BaseClass.Name, isAbstractImpl ? ", true" : string.Empty);
", true" : string.Empty);
WriteStartBraceIndent(); WriteStartBraceIndent();
@ -1922,13 +1928,13 @@ namespace CppSharp.Generators.CSharp
{ {
if (ShouldGenerateClassNativeField(@class)) if (ShouldGenerateClassNativeField(@class))
{ {
WriteLine("{0} = native;", Helpers.InstanceIdentifier); WriteLine("{0} = new global::System.IntPtr(native);", Helpers.InstanceIdentifier);
GenerateVTableClassSetupCall(@class, true); GenerateVTableClassSetupCall(@class, true);
} }
} }
else else
{ {
WriteLine("var {0} = (Internal*){1}.ToPointer();", WriteLine("var {0} = {1};",
Generator.GeneratedIdentifier("ptr"), "native"); Generator.GeneratedIdentifier("ptr"), "native");
GenerateStructMarshalingProperties(@class); GenerateStructMarshalingProperties(@class);
} }
@ -1960,7 +1966,7 @@ namespace CppSharp.Generators.CSharp
if (@class.IsRefType) if (@class.IsRefType)
{ {
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("private static global::System.IntPtr __CopyValue({0}.Internal native)", className); WriteLine("private static {0}.Internal* __CopyValue({0}.Internal native)", className);
WriteStartBraceIndent(); WriteStartBraceIndent();
if (@class.HasNonTrivialCopyConstructor) if (@class.HasNonTrivialCopyConstructor)
{ {
@ -1975,12 +1981,13 @@ namespace CppSharp.Generators.CSharp
WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size); WriteLine("var ret = Marshal.AllocHGlobal({0});", @class.Layout.Size);
WriteLine("{0}.Internal.{1}(ret, new global::System.IntPtr(&native));", WriteLine("{0}.Internal.{1}(ret, new global::System.IntPtr(&native));",
QualifiedIdentifier(@class), GetFunctionNativeIdentifier(copyCtorMethod)); QualifiedIdentifier(@class), GetFunctionNativeIdentifier(copyCtorMethod));
WriteLine("return ret;"); WriteLine("return ({0}.Internal*) ret;", className);
} }
else else
{ {
WriteLine("global::System.IntPtr ret = Marshal.AllocHGlobal({0});", @class.Layout.Size); WriteLine("{0}.Internal* ret = ({0}.Internal*) Marshal.AllocHGlobal({1});",
WriteLine("*({0}.Internal*) ret = native;", className); className, @class.Layout.Size);
WriteLine("*ret = native;", className);
WriteLine("return ret;"); WriteLine("return ret;");
} }
WriteCloseBraceIndent(); WriteCloseBraceIndent();
@ -1988,7 +1995,7 @@ namespace CppSharp.Generators.CSharp
} }
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
WriteLine("internal {0}({1}.Internal native)", safeIdentifier, className); WriteLine("internal {0}({1}.Internal native)", safeIdentifier, className);
WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native))" : ": this(&native)", className); WriteLineIndent(@class.IsRefType ? ": this(__CopyValue(native))" : ": this(&native)");
WriteStartBraceIndent(); WriteStartBraceIndent();
if (@class.IsRefType) if (@class.IsRefType)
{ {
@ -2008,7 +2015,7 @@ namespace CppSharp.Generators.CSharp
Write(": this("); Write(": this(");
if (method != null) if (method != null)
Write("IntPtr.Zero"); Write("(Internal*) null");
else else
Write("native"); Write("native");

8
tests/CSharpTemp/CSharpTemp.Tests.cs

@ -172,4 +172,12 @@ public class CSharpTempTests : GeneratorTestFixture
Assert.AreEqual(q1.Array[i], q2.Array[i]); Assert.AreEqual(q1.Array[i], q2.Array[i]);
} }
} }
[Test]
public void TestInternalCtorAmbiguity()
{
using (new InternalCtorAmbiguity().InvokeInternalCtor())
{
}
}
} }

21
tests/CSharpTemp/CSharpTemp.cpp

@ -298,3 +298,24 @@ void PropertyWithIgnoredType::setIgnoredType(const IgnoredType<int> &value)
{ {
_ignoredType = value; _ignoredType = value;
} }
InternalCtorAmbiguity::InternalCtorAmbiguity() : copy(0)
{
}
InternalCtorAmbiguity::InternalCtorAmbiguity(void* param) : copy(0)
{
// cause a crash to indicate this is the incorrect ctor to invoke
throw;
}
InternalCtorAmbiguity* InternalCtorAmbiguity::InvokeInternalCtor()
{
return copy = new InternalCtorAmbiguity();
}
InternalCtorAmbiguity::~InternalCtorAmbiguity()
{
if (copy)
delete copy;
}

11
tests/CSharpTemp/CSharpTemp.h

@ -264,3 +264,14 @@ public:
private: private:
IgnoredType<int> _ignoredType; IgnoredType<int> _ignoredType;
}; };
class DLL_API InternalCtorAmbiguity
{
public:
InternalCtorAmbiguity();
InternalCtorAmbiguity(void* param);
InternalCtorAmbiguity* InvokeInternalCtor();
~InternalCtorAmbiguity();
private:
InternalCtorAmbiguity* copy;
};

Loading…
Cancel
Save