IDE: Visual Studio
Version: RemObjects 9.2.101.218
Language: Silver
Target .NET
Description: It appears that all Swift custom block types on .NET, with the single exception of () -> (), are treated as generic types even if they do not contain any generic parameters. As a result, they cannot be passed as delegates to unmanaged code.
Expected Behavior: Given this simple delegate (callback) function of type () -> ()
func myDelegate() {
print("Managed delegate executed")
}
we can get a native (unmanaged) pointer to it as follows:
typealias ManagedDelegate = () -> ()
var managedDelegate = ManagedDelegate(myDelegate)
var nativeDelegate: IntPtr = Marshal.GetFunctionPointerForDelegate(managedDelegate)
This native pointer can be passed to a native function in a native DLL, and the native function can use it to invoke myDelegate(). In this case, everything works as expected.
Actual Behavior:
However, if you add a return type or any method parameter to myDelegate(), for example:
func myDelegate(_ i: Int32) {
print("Managed delegate executed")
}
typealias ManagedDelegate = (Int32) -> ()
var managedDelegate = ManagedDelegate(myDelegate)
var nativeDelegate: IntPtr = Marshal.GetFunctionPointerForDelegate(managedDelegate)
the result is a runtime exception:
Unhandled Exception: System.ArgumentException: The specified Type must not be a generic type definition.
Parameter name: delegate
at System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegateInternal(Delegate d)
at System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(Delegate d)
at System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate[TDelegate](TDelegate d)
Apparently, the system is treating the type (Int32) -> () as a generic type, even though it isn’t generic. The result is that pointers to delegates of any type other than () -> () cannot be passed to native code.
This appears to be a bug, unless there is some other subtlety that I am missing.