parent
98b07c42d5
commit
9cd3d0b57f
|
@ -5,22 +5,30 @@ namespace BizHawk.BizInvoke
|
||||||
{
|
{
|
||||||
public static unsafe class BizInvokerUtilities
|
public static unsafe class BizInvokerUtilities
|
||||||
{
|
{
|
||||||
#nullable disable //TODO If U1 and U2 were structs, this wouldn't be a problem. Would changing them to structs break this helper's functionality? --yoshi
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
private class U
|
private class U
|
||||||
{
|
{
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public U1 First;
|
public readonly U1? First;
|
||||||
|
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public U2 Second;
|
public readonly U2 Second;
|
||||||
|
|
||||||
|
public U(U2 second)
|
||||||
|
{
|
||||||
|
// being a union type, these assignments affect the value of both fields so they need to be in this order
|
||||||
|
First = null;
|
||||||
|
Second = second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#nullable restore
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
private class U1
|
private class U1
|
||||||
{
|
{
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public UIntPtr P;
|
public UIntPtr P;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
private class U2
|
private class U2
|
||||||
{
|
{
|
||||||
|
@ -29,10 +37,12 @@ namespace BizHawk.BizInvoke
|
||||||
|
|
||||||
public U2(object target) => Target = target;
|
public U2(object target) => Target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CF
|
private class CF
|
||||||
{
|
{
|
||||||
public int FirstField;
|
public int FirstField;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Didn't I have code somewhere else to do this already?
|
/// Didn't I have code somewhere else to do this already?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -43,19 +53,20 @@ namespace BizHawk.BizInvoke
|
||||||
int ret;
|
int ret;
|
||||||
fixed(int* fx = &c.FirstField)
|
fixed(int* fx = &c.FirstField)
|
||||||
{
|
{
|
||||||
var u = new U { Second = new U2(c) };
|
U u = new(new U2(c));
|
||||||
ret = (int)((ulong)(UIntPtr)fx - (ulong)u.First.P);
|
ret = (int) ((ulong) (UIntPtr) fx - (ulong) u.First!.P);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int ComputeStringOffset()
|
public static int ComputeStringOffset()
|
||||||
{
|
{
|
||||||
var s = new string(new char[0]);
|
var s = new string(new char[0]);
|
||||||
int ret;
|
int ret;
|
||||||
fixed(char* fx = s)
|
fixed(char* fx = s)
|
||||||
{
|
{
|
||||||
var u = new U { Second = new U2(s) };
|
U u = new(new U2(s));
|
||||||
ret = (int)((ulong)(UIntPtr)fx - (ulong)u.First.P);
|
ret = (int) ((ulong) (UIntPtr) fx - (ulong) u.First!.P);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue