From c4b48cf1856496edcd728ac0af89326228389527 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Wed, 22 Oct 2014 15:43:17 +0300 Subject: [PATCH] Fixed some problems with arrays of void after mapping void* to IntPtr. Signed-off-by: Dimitar Dobrev --- .../Generators/CSharp/CSharpMarshal.cs | 11 ++++++++--- .../Generators/CSharp/CSharpTypePrinter.cs | 17 +++++++++++------ .../Passes/HandleDefaultParamValuesPass.cs | 4 +++- tests/CSharpTemp/CSharpTemp.Tests.cs | 2 ++ tests/CSharpTemp/CSharpTemp.cpp | 6 +++++- tests/CSharpTemp/CSharpTemp.h | 8 +++----- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index cf0d74ff..b7f88df6 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -121,7 +121,11 @@ namespace CppSharp.Generators.CSharp supportBefore.WriteStartBraceIndent(); supportBefore.WriteLine("{0} = new {1}[{2}];", value, array.Type, array.Size); supportBefore.WriteLine("for (int i = 0; i < {0}; i++)", array.Size); - supportBefore.WriteLineIndent("{0}[i] = {1}[i];", value, Context.ReturnVarName); + if (array.Type.IsPointerToPrimitiveType(PrimitiveType.Void)) + supportBefore.WriteLineIndent("{0}[i] = new global::System.IntPtr({1}[i]);", + value, Context.ReturnVarName); + else + supportBefore.WriteLineIndent("{0}[i] = {1}[i];", value, Context.ReturnVarName); supportBefore.WriteCloseBraceIndent(); Context.Return.Write(value); break; @@ -352,8 +356,9 @@ namespace CppSharp.Generators.CSharp supportBefore.WriteLine("if ({0} != null)", Context.ArgName); supportBefore.WriteStartBraceIndent(); supportBefore.WriteLine("for (int i = 0; i < {0}; i++)", array.Size); - supportBefore.WriteLineIndent("{0}[i] = {1}[i];", - Context.ReturnVarName, Context.ArgName); + supportBefore.WriteLineIndent("{0}[i] = {1}[i]{2};", + Context.ReturnVarName, Context.ArgName, + array.Type.IsPointerToPrimitiveType(PrimitiveType.Void) ? ".ToPointer()" : string.Empty); supportBefore.WriteCloseBraceIndent(); break; default: diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index efe3a234..073e9260 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -116,12 +116,15 @@ namespace CppSharp.Generators.CSharp if (ContextKind == CSharpTypePrinterContextKind.Native && array.SizeType == ArrayType.ArraySize.Constant) { - if (array.Type.Desugar().IsPointerToPrimitiveType()) + Type arrayType = array.Type.Desugar(); + PrimitiveType primitiveType; + if (arrayType.IsPointerToPrimitiveType(out primitiveType)) { - return new CSharpTypePrinterResult + if (primitiveType == PrimitiveType.Void) { - Type = string.Format("{0}*", array.Type.Visit(this, quals)) - }; + return "void**"; + } + return string.Format("{0}*", array.Type.Visit(this, quals)); } // Do not write the fixed keyword multiple times for nested array types var fixedKeyword = array.Type is ArrayType ? string.Empty : "fixed "; @@ -217,14 +220,16 @@ namespace CppSharp.Generators.CSharp { // Skip one indirection if passed by reference var param = Context.Parameter; - if (isManagedContext && param != null && (param.IsOut || param.IsInOut)) + bool isRefParam = param != null && (param.IsOut || param.IsInOut); + if (isManagedContext && isRefParam) return pointee.Visit(this, quals); if (ContextKind == CSharpTypePrinterContextKind.GenericDelegate || pointee.IsPrimitiveType(PrimitiveType.Void)) return "global::System.IntPtr"; - return pointee.Visit(this, quals) + "*"; + var result = pointee.Visit(this, quals); + return !isRefParam && result.Type == "global::System.IntPtr" ? "void**" : result + "*"; } Enumeration @enum; diff --git a/src/Generator/Passes/HandleDefaultParamValuesPass.cs b/src/Generator/Passes/HandleDefaultParamValuesPass.cs index 3489c2d5..d547e2d6 100644 --- a/src/Generator/Passes/HandleDefaultParamValuesPass.cs +++ b/src/Generator/Passes/HandleDefaultParamValuesPass.cs @@ -57,7 +57,9 @@ namespace CppSharp.Passes { if (desugared.IsPointer()) { - parameter.DefaultArgument.String = "null"; + // IntPtr.Zero is not a constant + parameter.DefaultArgument.String = desugared.IsPointerToPrimitiveType(PrimitiveType.Void) ? + "new global::System.IntPtr()" : "null"; return true; } return false; diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index 4bdd777e..b26ab610 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -133,6 +133,8 @@ public class CSharpTempTests : GeneratorTestFixture methodsWithDefaultValues.DefaultChar(); methodsWithDefaultValues.DefaultEmptyChar(); methodsWithDefaultValues.DefaultPointer(); + methodsWithDefaultValues.DefaultVoidStar(); + methodsWithDefaultValues.DefaultValueType(); methodsWithDefaultValues.DefaultRefTypeAfterOthers(); methodsWithDefaultValues.DefaultRefTypeBeforeAndAfterOthers(5, new Foo()); methodsWithDefaultValues.DefaultRefTypeBeforeOthers(); diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index d00df5ae..893f41c5 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -245,7 +245,11 @@ void MethodsWithDefaultValues::defaultPointer(Foo *ptr) { } -void MethodsWithDefaultValues::defaultValueType(ValueType bar) +void MethodsWithDefaultValues::defaultVoidStar(void* ptr) +{ +} + +void MethodsWithDefaultValues::defaultValueType(QGenericArgument valueType) { } diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 3e8ece09..f2d8c535 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -183,10 +183,6 @@ public: void Name(); }; -struct DLL_API ValueType -{ -}; - enum class Flags { Flag1 = 1, @@ -209,6 +205,7 @@ struct QGenericArgument { public: QGenericArgument(const char* name = 0); + void* fixedArrayInValueType[1]; private: const char* _name; }; @@ -218,7 +215,8 @@ class DLL_API MethodsWithDefaultValues public: MethodsWithDefaultValues(Foo foo = Foo()); void defaultPointer(Foo* ptr = 0); - void defaultValueType(ValueType bar = ValueType()); + void defaultVoidStar(void* ptr = 0); + void defaultValueType(QGenericArgument valueType = QGenericArgument()); void defaultChar(char c = 'a'); void defaultEmptyChar(char c = 0); void defaultRefTypeBeforeOthers(Foo foo = Foo(), int i = 5, Bar::Items item = Bar::Item2);