diff --git a/AdvancedDLSupport.Tests/Data/Interfaces/ICallingConventionLibrary.cs b/AdvancedDLSupport.Tests/Data/Interfaces/ICallingConventionLibrary.cs new file mode 100644 index 00000000..195bc0ac --- /dev/null +++ b/AdvancedDLSupport.Tests/Data/Interfaces/ICallingConventionLibrary.cs @@ -0,0 +1,38 @@ +// +// ICallingConventionLibrary.cs +// +// Copyright (c) 2018 Firwood Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using System; +using System.Collections.Generic; +using System.Text; + +using static System.Runtime.InteropServices.CallingConvention; + +#pragma warning disable SA1600, CS1591 + +namespace AdvancedDLSupport.Tests.Data.Interfaces +{ + [NativeSymbols(DefaultCallingConvention = StdCall)] + public interface ICallingConventionLibrary + { + int MultiplyBy5_STD(int num); + + [NativeSymbol(CallingConvention = Cdecl)] + int MultiplyBy5(int num); + } +} diff --git a/AdvancedDLSupport.Tests/Tests/Integration/CallingConventionTests.cs b/AdvancedDLSupport.Tests/Tests/Integration/CallingConventionTests.cs new file mode 100644 index 00000000..c35c4846 --- /dev/null +++ b/AdvancedDLSupport.Tests/Tests/Integration/CallingConventionTests.cs @@ -0,0 +1,50 @@ +// +// CallingConventionTests.cs +// +// Copyright (c) 2018 Firwood Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// + +using AdvancedDLSupport.Tests.Data.Interfaces; +using AdvancedDLSupport.Tests.TestBases; + +using Xunit; + +#pragma warning disable SA1600, CS1591 + +namespace AdvancedDLSupport.Tests.Integration +{ + public class CallingConventionTests : LibraryTestBase + { + private const string LibraryName = "CallingConventionTests"; + + public CallingConventionTests() + : base(LibraryName) + { + } + + [Fact] + public void StdCallIsDefaultInterfaceConvention() + { + Assert.Equal(20, Library.MultiplyBy5_STD(4)); + } + + [Fact] + public void NativeSymbolOverrideWorks() + { + Assert.Equal(20, Library.MultiplyBy5(4)); + } + } +} diff --git a/AdvancedDLSupport.Tests/c/CMakeLists.txt b/AdvancedDLSupport.Tests/c/CMakeLists.txt index 78346d6c..9b96d80e 100644 --- a/AdvancedDLSupport.Tests/c/CMakeLists.txt +++ b/AdvancedDLSupport.Tests/c/CMakeLists.txt @@ -42,6 +42,7 @@ list( GenericDelegateTests BooleanMarshallingTests SpanMarshallingTests + CallingConventionTests ) list( diff --git a/AdvancedDLSupport.Tests/c/src/CallingConventionTests.c b/AdvancedDLSupport.Tests/c/src/CallingConventionTests.c new file mode 100644 index 00000000..9c5dd862 --- /dev/null +++ b/AdvancedDLSupport.Tests/c/src/CallingConventionTests.c @@ -0,0 +1,12 @@ +#include +#include "comp.h" + +__declspec(dllexport) int32_t __stdcall MultiplyBy5_STD(int32_t num) +{ + return num * 5; +} + +__declspec(dllexport) int32_t MultiplyBy5(int32_t num) +{ + return num * 5; +} \ No newline at end of file diff --git a/AdvancedDLSupport.Tests/c/src/CustomLoadingLogicTests.c b/AdvancedDLSupport.Tests/c/src/CustomLoadingLogicTests.c deleted file mode 100644 index b62e907e..00000000 --- a/AdvancedDLSupport.Tests/c/src/CustomLoadingLogicTests.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -__declspec(dllexport) int32_t ReturnsOne() -{ - return 1; -} - -__declspec(dllexport) int32_t ReturnsTwo() -{ - return 2; -} \ No newline at end of file diff --git a/AdvancedDLSupport/Attributes/NativeSymbolAttribute.cs b/AdvancedDLSupport/Attributes/NativeSymbolAttribute.cs index 54739888..24ed3535 100644 --- a/AdvancedDLSupport/Attributes/NativeSymbolAttribute.cs +++ b/AdvancedDLSupport/Attributes/NativeSymbolAttribute.cs @@ -49,7 +49,6 @@ public sealed class NativeSymbolAttribute : Attribute [PublicAPI] public NativeSymbolAttribute([NotNull, CallerMemberName] string entrypoint = "") { - CallingConvention = CallingConvention.Cdecl; Entrypoint = entrypoint; } } diff --git a/AdvancedDLSupport/Reflection/IntrospectiveMemberBase.cs b/AdvancedDLSupport/Reflection/IntrospectiveMemberBase.cs index 2c4157bc..3aff9130 100644 --- a/AdvancedDLSupport/Reflection/IntrospectiveMemberBase.cs +++ b/AdvancedDLSupport/Reflection/IntrospectiveMemberBase.cs @@ -141,8 +141,14 @@ public string GetNativeEntrypoint() /// public CallingConvention GetNativeCallingConvention() { - var metadataAttribute = GetCustomAttribute() ?? - new NativeSymbolAttribute(Name); + var metadataAttribute = GetCustomAttribute(); + + if (metadataAttribute == null || metadataAttribute.CallingConvention == default) + { + NativeSymbolsAttribute attribute = MetadataType.GetCustomAttribute(); + + return attribute == null || attribute.DefaultCallingConvention == default ? CallingConvention.Cdecl : attribute.DefaultCallingConvention; + } return metadataAttribute.CallingConvention; } diff --git a/AdvancedDLSupport/SymbolTransformation/Attributes/NativeSymbolsAttribute.cs b/AdvancedDLSupport/SymbolTransformation/Attributes/NativeSymbolsAttribute.cs index b6097ed1..962cc630 100644 --- a/AdvancedDLSupport/SymbolTransformation/Attributes/NativeSymbolsAttribute.cs +++ b/AdvancedDLSupport/SymbolTransformation/Attributes/NativeSymbolsAttribute.cs @@ -18,6 +18,7 @@ // using System; +using System.Runtime.InteropServices; using JetBrains.Annotations; namespace AdvancedDLSupport @@ -40,6 +41,12 @@ public class NativeSymbolsAttribute : Attribute [PublicAPI] public SymbolTransformationMethod SymbolTransformationMethod { get; set; } + /// + /// Gets or sets the default calling convention for symbols of the interface. + /// + [PublicAPI] + public CallingConvention DefaultCallingConvention { get; set; } + /// /// Initializes a new instance of the class. ///