Workaround for P/Invoke AccessViolationException

Summary:
The issue is on ARM builds for Windows UWP. For the C# P/Invoke API wrapper, any native method that returns the YogaValue struct throws the AccessViolationException. The issue is not with structs in general, as returning the YogaSize / YGSize struct works fine. The issue seems to be limited to structs that have an enum member.

I tried a number of things to resolve the issue without changing the underlying native API for Windows. I read the ARM documentation and saw reference to variable enum sizes based on the number of enum members, so I tried to use a number of different UnmanagedType values in a [MarsalAs()] attribute on the enum member of the C# struct declaration.

What ultimately worked was to return a pointer to the location of the struct, and use the System.Runtime.InteropServices.PtrToStructure API to read the struct data from that pointer. I added a few new macros that will return the struct address on Windows only, other builds are not affected.

Note, I have not tested the impact of this ch
Closes https://github.com/facebook/yoga/pull/459

Reviewed By: emilsjolander

Differential Revision: D4652278

Pulled By: splhack

fbshipit-source-id: bf7ada4da1781e3f813b3ba331974b7bded476d9
This commit is contained in:
Eric Rozell
2017-03-06 11:29:52 -08:00
committed by Facebook Github Bot
parent 62f47190fb
commit 5bc0197c78
9 changed files with 102 additions and 78 deletions

View File

@@ -7,8 +7,6 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
using System;
namespace Facebook.Yoga
{
public partial class YogaNode
@@ -17,7 +15,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Left);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Left));
}
set
@@ -30,7 +28,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Top);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Top));
}
set
@@ -43,7 +41,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Right);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Right));
}
set
@@ -56,7 +54,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Bottom);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Bottom));
}
set
@@ -69,7 +67,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Start);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.Start));
}
set
@@ -82,7 +80,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.End);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPosition(_ygNode, YogaEdge.End));
}
set
@@ -107,7 +105,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Left);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Left));
}
set
@@ -120,7 +118,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Top);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Top));
}
set
@@ -133,7 +131,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Right);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Right));
}
set
@@ -146,7 +144,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Bottom);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Bottom));
}
set
@@ -159,7 +157,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Start);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Start));
}
set
@@ -172,7 +170,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.End);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.End));
}
set
@@ -185,7 +183,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Horizontal);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Horizontal));
}
set
@@ -198,7 +196,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Vertical);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.Vertical));
}
set
@@ -211,7 +209,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.All);
return YogaValue.MarshalValue(Native.YGNodeStyleGetMargin(_ygNode, YogaEdge.All));
}
set
@@ -240,7 +238,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Left);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Left));
}
set
@@ -253,7 +251,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Top);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Top));
}
set
@@ -266,7 +264,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Right);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Right));
}
set
@@ -279,7 +277,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Bottom);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Bottom));
}
set
@@ -292,7 +290,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Start);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Start));
}
set
@@ -305,7 +303,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.End);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.End));
}
set
@@ -318,7 +316,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Horizontal);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Horizontal));
}
set
@@ -331,7 +329,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Vertical);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.Vertical));
}
set
@@ -344,7 +342,7 @@ namespace Facebook.Yoga
{
get
{
return Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.All);
return YogaValue.MarshalValue(Native.YGNodeStyleGetPadding(_ygNode, YogaEdge.All));
}
set