diff --git a/README.md b/README.md index 059e9e5a..a1bf3c69 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ CppSharp is a library that allows you to generate .NET bindings that wrap C/C++ ## News +* September 22nd 2013 - Conversion (type cast) operators wrapped (thanks to <a href="https://github.com/ddobrev">@ddobrev</a>) * September 21st 2013 - Multiple inheritance now supported (thanks to <a href="https://github.com/ddobrev">@ddobrev</a>) * September 11th 2013 - Added wrapping of inlined functions (thanks to <a href="https://github.com/ddobrev">@ddobrev</a>) diff --git a/src/AST/Class.cs b/src/AST/Class.cs index 029d39b5..04a136ae 100644 --- a/src/AST/Class.cs +++ b/src/AST/Class.cs @@ -191,8 +191,9 @@ namespace CppSharp.AST public override IEnumerable<Function> GetFunctionOverloads(Function function) { - return Methods.Where(method => method.Name == function.Name) - .Cast<Function>(); + if (function.OperatorKind == CXXOperatorKind.Conversion) + return Methods.Where(fn => fn.OperatorKind == CXXOperatorKind.Conversion); + return Methods.Where(method => method.Name == function.Name); } public IEnumerable<T> FindHierarchy<T>(Func<Class, IEnumerable<T>> func) diff --git a/src/AST/Namespace.cs b/src/AST/Namespace.cs index 06be0c09..98d2d7c0 100644 --- a/src/AST/Namespace.cs +++ b/src/AST/Namespace.cs @@ -242,8 +242,9 @@ namespace CppSharp.AST public virtual IEnumerable<Function> GetFunctionOverloads(Function function) { - return Functions.Where(fn => fn.Name == function.Name) - .ToList(); + if (function.OperatorKind == CXXOperatorKind.Conversion) + return Functions.Where(fn => fn.OperatorKind == CXXOperatorKind.Conversion); + return Functions.Where(fn => fn.Name == function.Name); } public bool HasDeclarations diff --git a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs index ff4f550a..49dee947 100644 --- a/src/Generator/Generators/CSharp/CSharpTextTemplate.cs +++ b/src/Generator/Generators/CSharp/CSharpTextTemplate.cs @@ -2152,10 +2152,10 @@ namespace CppSharp.Generators.CSharp public static string GetFunctionNativeIdentifier(Function function) { - var identifier = SafeIdentifier(function.Name);; + var identifier = SafeIdentifier(function.Name); if (function.IsOperator) - identifier = "Operator" + function.OperatorKind.ToString(); + identifier = "Operator" + function.OperatorKind; var overloads = function.Namespace.GetFunctionOverloads(function) .ToList(); diff --git a/src/Generator/Passes/CheckAmbiguousFunctions.cs b/src/Generator/Passes/CheckAmbiguousFunctions.cs index a44f642e..bad22625 100644 --- a/src/Generator/Passes/CheckAmbiguousFunctions.cs +++ b/src/Generator/Passes/CheckAmbiguousFunctions.cs @@ -35,6 +35,9 @@ namespace CppSharp.Passes foreach (var overload in overloads) { + if (function.OperatorKind == CXXOperatorKind.Conversion) + continue; + if (overload == function) continue; if (overload.Ignore) continue; diff --git a/src/Generator/Passes/CheckOperatorsOverloads.cs b/src/Generator/Passes/CheckOperatorsOverloads.cs index fd570a31..04972842 100644 --- a/src/Generator/Passes/CheckOperatorsOverloads.cs +++ b/src/Generator/Passes/CheckOperatorsOverloads.cs @@ -20,6 +20,9 @@ namespace CppSharp.Passes if (AlreadyVisited(@class)) return false; + if (!VisitDeclarationContext(@class)) + return false; + // Check for C++ operators that cannot be represented in C#. CheckInvalidOperators(@class); diff --git a/src/Generator/Types/Types.cs b/src/Generator/Types/Types.cs index d92f23f4..91a6e919 100644 --- a/src/Generator/Types/Types.cs +++ b/src/Generator/Types/Types.cs @@ -97,6 +97,17 @@ namespace CppSharp return base.VisitTypedefDecl(typedef); } + public override bool VisitMemberPointerType(MemberPointerType member, TypeQualifiers quals) + { + FunctionType functionType; + if (!member.IsPointerTo(out functionType)) + { + Ignore(); + return false; + } + return base.VisitMemberPointerType(member, quals); + } + public override bool VisitTemplateSpecializationType( TemplateSpecializationType template, TypeQualifiers quals) { diff --git a/tests/CSharpTemp/CSharpTemp.Tests.cs b/tests/CSharpTemp/CSharpTemp.Tests.cs index fd7dc4cf..6d706a3a 100644 --- a/tests/CSharpTemp/CSharpTemp.Tests.cs +++ b/tests/CSharpTemp/CSharpTemp.Tests.cs @@ -46,5 +46,8 @@ public class CSharpTempTests Assert.That(baz.returnQux().farAwayFunc(), Is.EqualTo(20)); int cast = baz; Assert.That(cast, Is.EqualTo(500)); + var nested = new Baz.Nested(); + int nestedCast = nested; + Assert.That(nestedCast, Is.EqualTo(300)); } } \ No newline at end of file diff --git a/tests/CSharpTemp/CSharpTemp.cpp b/tests/CSharpTemp/CSharpTemp.cpp index ff0a74af..d030f5af 100644 --- a/tests/CSharpTemp/CSharpTemp.cpp +++ b/tests/CSharpTemp/CSharpTemp.cpp @@ -46,6 +46,11 @@ Foo& Bar::operator[](int i) return m_foo; } +Baz::Nested::operator int() const +{ + return 300; +} + int Baz::takesQux(const Qux& qux) { return qux.farAwayFunc(); diff --git a/tests/CSharpTemp/CSharpTemp.h b/tests/CSharpTemp/CSharpTemp.h index 4ff75db3..1d62fa39 100644 --- a/tests/CSharpTemp/CSharpTemp.h +++ b/tests/CSharpTemp/CSharpTemp.h @@ -38,7 +38,16 @@ private: class DLL_API Baz : public Foo, public Bar { public: + class DLL_API Nested + { + public: + operator int() const; + }; + int takesQux(const Qux& qux); Qux returnQux(); operator int() const; + + typedef void *Baz::*FunctionPointerResolvedAsVoidStar; + operator FunctionPointerResolvedAsVoidStar() const { return 0; } };