From 1488f822c308ce794c5b10be9b7c496b3c765751 Mon Sep 17 00:00:00 2001 From: mattpodwysocki Date: Sat, 22 Oct 2016 09:51:17 -0700 Subject: [PATCH] Fix C# delegate calling conventions Summary: When using CSS-Layout in a C# UWP project in x86, by default the MSVC compiler defaults the delegate calling convention to cdecl, while .NET assumes that all delegates are declared using stdcall. This causes a problem when invoking such as this error: ``` Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. ``` This PR changes the calling convention in the C# code to reflect cdecl by using the `UnmanagedFunctionPointer` attribute and setting the calling convention to `CallingConvention.Cdecl`. ```csharp [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate CSSSize CSSMeasureFunc( IntPtr context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode); ``` I have updated all calls as well to other functions. I Closes https://github.com/facebook/css-layout/pull/231 Reviewed By: emilsjolander Differential Revision: D4063437 Pulled By: splhack fbshipit-source-id: b1069a1b9f675d2623a64a1c5f3189292a18a646 --- csharp/Facebook.CSSLayout/CSSAssert.cs | 2 ++ csharp/Facebook.CSSLayout/CSSLogger.cs | 2 ++ csharp/Facebook.CSSLayout/CSSMeasureFunc.cs | 2 ++ csharp/Facebook.CSSLayout/Native.cs | 11 ++++++++--- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/csharp/Facebook.CSSLayout/CSSAssert.cs b/csharp/Facebook.CSSLayout/CSSAssert.cs index 606fbb4c..848c9119 100644 --- a/csharp/Facebook.CSSLayout/CSSAssert.cs +++ b/csharp/Facebook.CSSLayout/CSSAssert.cs @@ -8,11 +8,13 @@ */ using System; +using System.Runtime.InteropServices; namespace Facebook.CSSLayout { internal static class CSSAssert { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void FailFunc(string message); private static bool _assertInitialized; diff --git a/csharp/Facebook.CSSLayout/CSSLogger.cs b/csharp/Facebook.CSSLayout/CSSLogger.cs index e4959ff4..a5a95d0f 100644 --- a/csharp/Facebook.CSSLayout/CSSLogger.cs +++ b/csharp/Facebook.CSSLayout/CSSLogger.cs @@ -8,11 +8,13 @@ */ using System; +using System.Runtime.InteropServices; namespace Facebook.CSSLayout { internal static class CSSLogger { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void Func(string message); private static bool _initialized; diff --git a/csharp/Facebook.CSSLayout/CSSMeasureFunc.cs b/csharp/Facebook.CSSLayout/CSSMeasureFunc.cs index 57f70d72..cde50ca2 100644 --- a/csharp/Facebook.CSSLayout/CSSMeasureFunc.cs +++ b/csharp/Facebook.CSSLayout/CSSMeasureFunc.cs @@ -8,9 +8,11 @@ */ using System; +using System.Runtime.InteropServices; namespace Facebook.CSSLayout { + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate CSSSize CSSMeasureFunc( IntPtr context, float width, diff --git a/csharp/Facebook.CSSLayout/Native.cs b/csharp/Facebook.CSSLayout/Native.cs index 1066dd14..fade6a25 100644 --- a/csharp/Facebook.CSSLayout/Native.cs +++ b/csharp/Facebook.CSSLayout/Native.cs @@ -21,10 +21,12 @@ namespace Facebook.CSSLayout #endif [DllImport(DllName)] - public static extern void CSSInteropSetLogger(CSSLogger.Func func); + public static extern void CSSInteropSetLogger( + [MarshalAs(UnmanagedType.FunctionPtr)] CSSLogger.Func func); [DllImport(DllName)] - public static extern void CSSAssertSetFailFunc(CSSAssert.FailFunc func); + public static extern void CSSAssertSetFailFunc( + [MarshalAs(UnmanagedType.FunctionPtr)] CSSAssert.FailFunc func); [DllImport(DllName)] public static extern IntPtr CSSNodeNew(); @@ -79,9 +81,12 @@ namespace Facebook.CSSLayout public static extern IntPtr CSSNodeGetContext(IntPtr node); [DllImport(DllName)] - public static extern void CSSNodeSetMeasureFunc(IntPtr node, CSSMeasureFunc measureFunc); + public static extern void CSSNodeSetMeasureFunc( + IntPtr node, + [MarshalAs(UnmanagedType.FunctionPtr)] CSSMeasureFunc measureFunc); [DllImport(DllName)] + [return: MarshalAs(UnmanagedType.FunctionPtr)] public static extern CSSMeasureFunc CSSNodeGetMeasureFunc(IntPtr node); [DllImport(DllName)]