I need to get a FunctionPointerForDelegate to pass a native P/Invoke, but the function resides in a generic class of type myClass
When I try to create the Pointer I get an error of
System.ArgumentException: 'The specified Type must not be a generic type. (Parameter 'delegate')'
Is there any workaround to this?
var c = new MyClass<int>();
c.DoWork();
public class MyClass<T> {
private protected delegate int MyCompareCallback(int idxA, int idxB);
private int SortCompareFunction(int idxA, int idxB) {
return -1; // simplified implementation
}
public void DoWork() {
MyCompareCallback SortCallback = new(SortCompareFunction);
IntPtr callbackPtr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(SortCallback);
Console.WriteLine("Success"); // Fails on previous line with System.ArgumentException: 'The specified Type must not be a generic type. (Parameter 'delegate')'
}
}
You need to consider that your delegate type MyCompareCallback
is actually MyClass<T>.MyCompareCallback
. It is a generic type.
When you read the documentation for Marshal.GetFunctionPointerForDelegate it specifically says the System.ArgumentException
will be thrown if the delegate is a generic type.
You really have two choices.
(1) remove the generic type parameter from MyClass
public class MyClass
{
private protected delegate int MyCompareCallback(int idxA, int idxB);
private int SortCompareFunction(int idxA, int idxB) => -1;
public void DoWork()
{
MyCompareCallback SortCallback = new MyCompareCallback(SortCompareFunction);
IntPtr callbackPtr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(SortCallback);
Console.WriteLine("Success");
}
}
(2) move the delegate outside of MyClass<T>
internal delegate int MyCompareCallback(int idxA, int idxB);
public class MyClass<T>
{
private int SortCompareFunction(int idxA, int idxB) => -1;
public void DoWork()
{
MyCompareCallback SortCallback = new MyCompareCallback(SortCompareFunction);
IntPtr callbackPtr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(SortCallback);
Console.WriteLine("Success");
}
}