Skip to content

Commit

Permalink
(#494) Reverse FuncPtr interop
Browse files Browse the repository at this point in the history
  • Loading branch information
BadRyuner authored and ForNeVeR committed Apr 21, 2024
1 parent c668097 commit 2e5e0d3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
15 changes: 12 additions & 3 deletions Cesium.Runtime.Tests/PtrTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public void VoidPtrTests()
Assert.Equal(0x1234L, (long)v.AsPtr());
Assert.Equal(0x1234L, (long)v.AsPtr<byte>());

Assert.Equal(sizeof(long), sizeof(VoidPtr));
Assert.Equal(sizeof(IntPtr), sizeof(VoidPtr));
}

[Fact]
Expand All @@ -20,14 +20,23 @@ public void CPtrTests()
Assert.Equal((IntPtr)0x2345, t.AsIntPtr());
Assert.Equal(0x2345L, (long)t.AsPtr<byte>());

Assert.Equal(sizeof(long), sizeof(CPtr<int>));
Assert.Equal(sizeof(IntPtr), sizeof(CPtr<int>));
}

[Fact]
public void FuncPtrTests()
{
var a = new FuncPtr<Action>((void*)0x1234);
Assert.Equal(0x1234L, (long)a.AsPtr());
Assert.Equal(sizeof(long), sizeof(FuncPtr<Action>));
Assert.Equal(sizeof(IntPtr), sizeof(FuncPtr<Action>));

FuncPtr<Func<int>> funcPtr = (Func<int>)SomeAnonFunc;
var func = SomeAnonFunc;
Assert.Equal(funcPtr.AsDelegate()(), func());

funcPtr = (delegate*<int>)&SomeAnonFunc;
Assert.Equal(funcPtr.AsDelegate()(), func());

static int SomeAnonFunc() => 5;
}
}
20 changes: 17 additions & 3 deletions Cesium.Runtime/FuncPtr.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
using System.Runtime.InteropServices;

namespace Cesium.Runtime;

/// <summary>A class encapsulating a C function pointer.</summary>
public readonly unsafe struct FuncPtr<TDelegate> where TDelegate : Delegate // TODO[#487]: Think about vararg and empty parameter list encoding.
public readonly unsafe struct FuncPtr<TDelegate> where TDelegate : MulticastDelegate // TODO[#487]: Think about vararg and empty parameter list encoding.
{
private readonly long _value;
private readonly IntPtr _value;

public FuncPtr(void* ptr)
{
_value = (long)ptr;
_value = (IntPtr)ptr;
}

public FuncPtr(IntPtr ptr)
{
_value = ptr;
}

public static implicit operator TDelegate(FuncPtr<TDelegate> funcPtr) => (TDelegate)Activator.CreateInstance(typeof(TDelegate), [null, funcPtr._value])!;
public static implicit operator FuncPtr<TDelegate>(TDelegate @delegate) => @delegate.Method.MethodHandle.GetFunctionPointer();
public static implicit operator FuncPtr<TDelegate>(IntPtr funcPtr) => new(funcPtr);
public static implicit operator FuncPtr<TDelegate>(void* funcPtr) => new(funcPtr);

public TDelegate AsDelegate() => this;

public void* AsPtr() => (void*)_value;
}
12 changes: 6 additions & 6 deletions Cesium.Runtime/VoidPtr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ namespace Cesium.Runtime;
/// <summary>A class encapsulating an opaque pointer (aka <code>void*</code> in C).</summary>
public readonly unsafe struct VoidPtr
{
private readonly long _value;
private readonly IntPtr _value;

private VoidPtr(long value)
private VoidPtr(IntPtr value)
{
_value = value;
}

public static implicit operator VoidPtr(void* ptr) => new((long)ptr);
public static implicit operator VoidPtr(void* ptr) => new((IntPtr)ptr);
public void* AsPtr() => (void*)_value;
public TResult* AsPtr<TResult>() where TResult : unmanaged => (TResult*)_value;
public IntPtr AsIntPtr() => (IntPtr)AsPtr();
Expand All @@ -21,14 +21,14 @@ private VoidPtr(long value)
/// <typeparam name="T">Type this pointer may be resolved to.</typeparam>
public readonly unsafe struct CPtr<T> where T : unmanaged
{
private readonly long _value;
private readonly IntPtr _value;

private CPtr(long value)
private CPtr(IntPtr value)
{
_value = value;
}

public static implicit operator CPtr<T>(T* ptr) => new((long)ptr);
public static implicit operator CPtr<T>(T* ptr) => new((IntPtr)ptr);
public T* AsPtr() => (T*)_value;
public TResult* AsPtr<TResult>() where TResult : unmanaged => (TResult*)_value;
public IntPtr AsIntPtr() => (IntPtr)AsPtr();
Expand Down

0 comments on commit 2e5e0d3

Please sign in to comment.