How-To : IronPython and callback delegates with 'out' or 'ref' parameters
Following up on the earlier post, having found time to engage the brain a little...
Let's do the int
flavoured version, everything non-default:
namespace Callback | |
{ | |
using System; | |
public delegate IntPtr Hook(ref int handled); | |
public static class Callback | |
{ | |
public static object[] MakeCallback(Hook callback) | |
{ | |
int handled = 17; | |
IntPtr handle = callback(ref handled); | |
return new object[] { handle, handled }; | |
} | |
} | |
} |
and then in IronPython ask the variable about itself
import clr | |
clr.AddReferenceToFile('Callback.dll') | |
from Callback import * | |
from System import IntPtr | |
def callback(x): | |
print type(x) | |
print dir(x) | |
return IntPtr(42) | |
test = Callback.MakeCallback(callback) | |
print test |
Now we get
>"\Program Files\IronPython 2.6\ipy.exe" callback.py <type 'StrongBox[int]'> ['Equals', 'GetHashCode', 'GetType', 'MemberwiseClone', 'ReferenceEquals', 'ToSt ring', 'Value', '__class__', '__delattr__', '__doc__', '__format__', '__getattri bute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__re pr__', '__setattr__', '__str__', '__subclasshook__'] Array[object]((<System.IntPtr object at 0x000000000000002B [42]>, 17))
That Value
member looks interesting, so...
import clr | |
clr.AddReferenceToFile('Callback.dll') | |
from Callback import * | |
from System import IntPtr | |
def callback(x): | |
x.Value = 23 | |
return IntPtr(42) | |
test = Callback.MakeCallback(callback) | |
print test |
which gives us
>"\Program Files\IronPython 2.6\ipy.exe" callback.py Array[object]((<System.IntPtr object at 0x000000000000002B [42]>, 23))
which is what we were looking for.
Rebuilding the C# assembly with out
rather than ref
and re-instating the print
lines shows that the argument is still passed as a StrongBox
, so there is no change on the IronPython side.
Armed with this piece of knowledge about the type, I tried Googling again, and didn't find any obvious mentions of callbacks -- just the converse matter of calling .Net methods that take out
or ref
parameters. But that at least is enough to reassure me that this is not just some completely undocumented hack that would be subject to change in later versions.
Note also that if I had written
print x.GetType().ToString()
(which is what I did the first time around) rather than
print type(x)
I would have gotten the result System.Int32
, which gives no clue that adding
print dir(x)
is at all something worth doing.
No comments :
Post a Comment