diff --git a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs index 03f36ce6..a6fdf83f 100644 --- a/src/Generator/Generators/CLI/CLIHeadersTemplate.cs +++ b/src/Generator/Generators/CLI/CLIHeadersTemplate.cs @@ -368,7 +368,6 @@ namespace CppSharp.Generators.CLI // Output a default constructor that takes the native pointer. WriteLine("{0}({1} native);", @class.Name, nativeType); - WriteLine("{0}({1} native);", @class.Name, "System::IntPtr"); foreach (var ctor in @class.Constructors) { diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs index 537e11f9..554625f6 100644 --- a/src/Generator/Generators/CLI/CLIMarshal.cs +++ b/src/Generator/Generators/CLI/CLIMarshal.cs @@ -83,7 +83,7 @@ namespace CppSharp.Generators.CLI if (pointee.IsPrimitiveType(PrimitiveType.Void)) { - Context.Return.Write(Context.ReturnVarName); + Context.Return.Write("::System::IntPtr({0})", Context.ReturnVarName); return true; } diff --git a/src/Generator/Generators/CLI/CLISourcesTemplate.cs b/src/Generator/Generators/CLI/CLISourcesTemplate.cs index e9a9db43..3833b7d5 100644 --- a/src/Generator/Generators/CLI/CLISourcesTemplate.cs +++ b/src/Generator/Generators/CLI/CLISourcesTemplate.cs @@ -192,8 +192,7 @@ namespace CppSharp.Generators.CLI return; // Output a default constructor that takes the native pointer. - GenerateClassConstructor(@class, isIntPtr: false); - GenerateClassConstructor(@class, isIntPtr: true); + GenerateClassConstructor(@class); if (Options.GenerateFinalizers && @class.IsRefType) { @@ -215,7 +214,7 @@ namespace CppSharp.Generators.CLI foreach (var method in @class.Methods) { - if (ASTUtils.CheckIgnoreMethod(method, this.Options)) + if (ASTUtils.CheckIgnoreMethod(method, Options)) continue; // C++/CLI does not allow special member funtions for value types. @@ -611,25 +610,18 @@ namespace CppSharp.Generators.CLI GeneratePropertySetter(variable, @class, variable.Name, variable.Type); } - private void GenerateClassConstructor(Class @class, bool isIntPtr) + private void GenerateClassConstructor(Class @class) { Write("{0}::{1}(", QualifiedIdentifier(@class), @class.Name); var nativeType = string.Format("::{0}*", @class.QualifiedOriginalName); - WriteLine("{0} native)", isIntPtr ? "System::IntPtr" : nativeType); + WriteLine("{0} native)", nativeType); - var hasBase = GenerateClassConstructorBase(@class, isIntPtr); + var hasBase = GenerateClassConstructorBase(@class); WriteStartBraceIndent(); - var nativePtr = "native"; - - if (isIntPtr) - { - WriteLine("auto __native = (::{0}*)native.ToPointer();", - @class.QualifiedOriginalName); - nativePtr = "__native"; - } + const string nativePtr = "native"; if (@class.IsRefType) { @@ -680,7 +672,7 @@ namespace CppSharp.Generators.CLI } } - private bool GenerateClassConstructorBase(Class @class, bool isIntPtr, Method method = null) + private bool GenerateClassConstructorBase(Class @class, Method method = null) { var hasBase = @class.HasBase && @class.Bases[0].IsClass && @class.Bases[0].Class.IsDeclared; if (!hasBase) @@ -695,12 +687,9 @@ namespace CppSharp.Generators.CLI // We cast the value to the base clas type since otherwise there // could be ambiguous call to overloaded constructors. - if (!isIntPtr) - { - var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase); - var nativeTypeName = baseClass.Visit(cppTypePrinter); - Write("({0}*)", nativeTypeName); - } + var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase); + var nativeTypeName = baseClass.Visit(cppTypePrinter); + Write("({0}*)", nativeTypeName); WriteLine("{0})", method != null ? "nullptr" : "native"); @@ -727,7 +716,7 @@ namespace CppSharp.Generators.CLI WriteLine(")"); if (method.IsConstructor) - GenerateClassConstructorBase(@class, isIntPtr: false, method: method); + GenerateClassConstructorBase(@class, method: method); WriteStartBraceIndent(); diff --git a/src/Generator/Generators/CLI/CLITypePrinter.cs b/src/Generator/Generators/CLI/CLITypePrinter.cs index 92916b8c..449624af 100644 --- a/src/Generator/Generators/CLI/CLITypePrinter.cs +++ b/src/Generator/Generators/CLI/CLITypePrinter.cs @@ -154,10 +154,15 @@ namespace CppSharp.Generators.CLI { // Skip one indirection if passed by reference var param = Context.Parameter; - if (param != null && (param.IsOut || param.IsInOut)) + bool isRefParam = param != null && (param.IsOut || param.IsInOut); + if (isRefParam) return pointee.Visit(this, quals); - return pointee.Visit(this, quals) + "*"; + if (pointee.IsPrimitiveType(PrimitiveType.Void)) + return "::System::IntPtr"; + + var result = pointee.Visit(this, quals); + return !isRefParam && result == "::System::IntPtr" ? "void**" : result + "*"; } Enumeration @enum; diff --git a/tests/Basic/Basic.Tests.cs b/tests/Basic/Basic.Tests.cs index 38e9343e..07809d5b 100644 --- a/tests/Basic/Basic.Tests.cs +++ b/tests/Basic/Basic.Tests.cs @@ -452,5 +452,11 @@ public class BasicTests : GeneratorTestFixture for (int i = 0; i < foo.fixedArray.Length; i++) Assert.That(array[i], Is.EqualTo(foo.fixedArray[i])); } + + [Test] + public void TestInternalCtorAmbiguity() + { + new InvokesInternalCtorAmbiguity().InvokeInternalCtor(); + } } \ No newline at end of file diff --git a/tests/Basic/Basic.cpp b/tests/Basic/Basic.cpp index 3247899e..2afd045f 100644 --- a/tests/Basic/Basic.cpp +++ b/tests/Basic/Basic.cpp @@ -317,3 +317,18 @@ std::string HasStdString::testStdString(std::string s) { return s + "_test"; } + +InternalCtorAmbiguity::InternalCtorAmbiguity(void* param) +{ + // cause a crash to indicate this is the incorrect ctor to invoke + throw; +} + +InvokesInternalCtorAmbiguity::InvokesInternalCtorAmbiguity() : ptr(0) +{ +} + +InternalCtorAmbiguity* InvokesInternalCtorAmbiguity::InvokeInternalCtor() +{ + return ptr; +} diff --git a/tests/Basic/Basic.h b/tests/Basic/Basic.h index 9c9d9ce6..f0543e4c 100644 --- a/tests/Basic/Basic.h +++ b/tests/Basic/Basic.h @@ -30,6 +30,7 @@ public: float B; IgnoredType ignoredType; int fixedArray[3]; + void* ptr; const char* GetANSI(); // TODO: VC++ does not support char16 @@ -630,3 +631,18 @@ public: std::string testStdString(std::string s); std::string s; }; + +class DLL_API InternalCtorAmbiguity +{ +public: + InternalCtorAmbiguity(void* param); +}; + +class DLL_API InvokesInternalCtorAmbiguity +{ +public: + InvokesInternalCtorAmbiguity(); + InternalCtorAmbiguity* InvokeInternalCtor(); +private: + InternalCtorAmbiguity* ptr; +}; diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index e8f95159..bf607102 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -164,12 +164,4 @@ public class CSharpTempTests : GeneratorTestFixture Assert.AreEqual(q1.Array[i], q2.Array[i]); } } - - [Test] - public void TestInternalCtorAmbiguity() - { - using (new InternalCtorAmbiguity().InvokeInternalCtor()) - { - } - } } \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index 893f41c5..67238c47 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -301,25 +301,4 @@ IgnoredType PropertyWithIgnoredType::ignoredType() void PropertyWithIgnoredType::setIgnoredType(const 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; -} +} \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 0a51445e..c16c148d 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -260,15 +260,4 @@ public: void setIgnoredType(const IgnoredType& value); private: IgnoredType _ignoredType; -}; - -class DLL_API InternalCtorAmbiguity -{ -public: - InternalCtorAmbiguity(); - InternalCtorAmbiguity(void* param); - InternalCtorAmbiguity* InvokeInternalCtor(); - ~InternalCtorAmbiguity(); -private: - InternalCtorAmbiguity* copy; -}; +}; \ No newline at end of file