Browse Source

When generating delegates attributed types need to be taken into account or proper calling convention won't get picked up.

pull/234/head
Elias Holzer 12 years ago committed by triton
parent
commit
cc3cc40fc4
  1. 17
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  2. 13
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 11
      tests/Basic/Basic.Tests.cs
  4. 13
      tests/Basic/Basic.h
  5. 4
      tests/Tests.h

17
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -716,13 +716,18 @@ namespace CppSharp.Generators.CLI
var insideClass = typedef.Namespace is Class; var insideClass = typedef.Namespace is Class;
var callingConvention = function.CallingConvention.ToInteropCallConv(); var attributedType = typedef.Type.GetPointee() as AttributedType;
if (callingConvention != System.Runtime.InteropServices.CallingConvention.Winapi) if (attributedType != null)
{ {
WriteLine("[{0}({1}::{2})] ", var equivalentFunctionType = attributedType.Equivalent.Type as FunctionType;
"System::Runtime::InteropServices::UnmanagedFunctionPointer", var callingConvention = equivalentFunctionType.CallingConvention.ToInteropCallConv();
"System::Runtime::InteropServices::CallingConvention", if (callingConvention != System.Runtime.InteropServices.CallingConvention.Winapi)
callingConvention); {
WriteLine("[{0}({1}::{2})] ",
"System::Runtime::InteropServices::UnmanagedFunctionPointer",
"System::Runtime::InteropServices::CallingConvention",
callingConvention);
}
} }
WriteLine("{0}{1};", WriteLine("{0}{1};",

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

@ -2543,8 +2543,17 @@ namespace CppSharp.Generators.CSharp
else if (typedef.Type.IsPointerTo(out functionType)) else if (typedef.Type.IsPointerTo(out functionType))
{ {
PushBlock(CSharpBlockKind.Typedef); PushBlock(CSharpBlockKind.Typedef);
WriteLine("[UnmanagedFunctionPointerAttribute(global::System.Runtime.InteropServices.CallingConvention.{0})]", var attributedType = typedef.Type.GetPointee() as AttributedType;
functionType.CallingConvention.ToInteropCallConv()); if (attributedType != null)
{
var equivalentFunctionType = attributedType.Equivalent.Type as FunctionType;
var callingConvention = equivalentFunctionType.CallingConvention.ToInteropCallConv();
if (callingConvention != System.Runtime.InteropServices.CallingConvention.Winapi)
{
WriteLine("[UnmanagedFunctionPointerAttribute(global::System.Runtime.InteropServices.CallingConvention.{0})]",
callingConvention);
}
}
TypePrinter.PushContext(CSharpTypePrinterContextKind.Native); TypePrinter.PushContext(CSharpTypePrinterContextKind.Native);
WriteLine("{0}unsafe {1};", WriteLine("{0}unsafe {1};",
Helpers.GetAccess(typedef.Access), Helpers.GetAccess(typedef.Access),

11
tests/Basic/Basic.Tests.cs

@ -176,13 +176,12 @@ public class BasicTests : GeneratorTestFixture
var delegates = new TestDelegates(); var delegates = new TestDelegates();
var doubleSum = delegates.A(2) + delegates.B(2); var doubleSum = delegates.A(2) + delegates.B(2);
Assert.AreEqual(8, doubleSum); Assert.AreEqual(8, doubleSum);
}
[Test] var stdcall = delegates.StdCall(i => i);
public void TestAttributedDelegate() Assert.AreEqual(1, stdcall);
{
var result = basic.AttributedDelegate(2); var cdecl = delegates.CDecl(i => i);
Assert.AreEqual(4, result); Assert.AreEqual(1, cdecl);
} }
[Test] [Test]

13
tests/Basic/Basic.h

@ -242,6 +242,8 @@ DLL_API int operator==(const Foo2& a, const Foo2& b)
// Tests delegates // Tests delegates
typedef int (*DelegateInGlobalNamespace)(int); typedef int (*DelegateInGlobalNamespace)(int);
typedef int (STDCALL *DelegateStdCall)(int);
typedef int (CDECL *DelegateCDecl)(int n);
struct DLL_API TestDelegates struct DLL_API TestDelegates
{ {
@ -252,6 +254,9 @@ struct DLL_API TestDelegates
static int Double(int N) { return N * 2; } static int Double(int N) { return N * 2; }
int Triple(int N) { return N * 3; } int Triple(int N) { return N * 3; }
int StdCall(DelegateStdCall del) { return del(1); }
int CDecl(DelegateCDecl del) { return del(1); }
DelegateInClass A; DelegateInClass A;
DelegateInGlobalNamespace B; DelegateInGlobalNamespace B;
// As long as we can't marshal them make sure they're ignored // As long as we can't marshal them make sure they're ignored
@ -262,14 +267,6 @@ TestDelegates::TestDelegates() : A(Double), B(Double), C(&TestDelegates::Triple)
{ {
} }
// Tests delegate generation for attributed function types
typedef int(__cdecl *AttributedDelegate)(int n);
DLL_API int __cdecl Double(int n) { return n * 2; }
DLL_API AttributedDelegate GetAttributedDelegate()
{
return Double;
}
// Tests memory leaks in constructors // Tests memory leaks in constructors
// C#: Marshal.FreeHGlobal(arg0); // C#: Marshal.FreeHGlobal(arg0);
struct DLL_API TestMemoryLeaks struct DLL_API TestMemoryLeaks

4
tests/Tests.h

@ -2,8 +2,12 @@
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define DLL_API __declspec(dllexport) #define DLL_API __declspec(dllexport)
#define STDCALL __stdcall
#define CDECL __cdecl
#else #else
#define DLL_API __attribute__ ((visibility ("default"))) #define DLL_API __attribute__ ((visibility ("default")))
#define STDCALL __attribute__((stdcall))
#define CDECL __attribute__((stdcall))
#endif #endif
#define CS_OUT #define CS_OUT
Loading…
Cancel
Save