Files
PorygonSharp/PorygonSharp/EvalValues/DelegateEvalValue.cs

41 lines
1.4 KiB
C#

using System;
using System.Linq;
using System.Runtime.InteropServices;
using PorygonSharp.Utilities;
namespace PorygonSharp.EvalValues
{
public class DelegateEvalValue
{
private delegate IntPtr InvokeDelegate(IntPtr _, IntPtr options,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]IntPtr[] parameters, int parameterCount);
private readonly Delegate _delegate;
private readonly InvokeDelegate _handler;
public readonly IntPtr Pointer;
public DelegateEvalValue(Delegate del)
{
_delegate = del;
_handler = Invoke;
var funcPtr = Marshal.GetFunctionPointerForDelegate(_handler);
Pointer = EvalValueCreator.CreateFunctionEvalValue(funcPtr, IntPtr.Zero);
}
private IntPtr Invoke(IntPtr _, IntPtr options, IntPtr[] parPtrs, int parameterCount)
{
var parameters = new object[parameterCount];
var parametersTypes = _delegate.Method.GetParameters().Select(x => x.ParameterType).ToArray();
for (var i = 0; i < parameterCount; i++)
{
var val = new EvalValue(parPtrs[i]);
parameters[i] = Caster.Cast(val, parametersTypes[i]);
}
var result = _delegate.DynamicInvoke(parameters);
return EvalValueCreator.CreateValue(result).GetPointer();
}
}
}