#import #import @implementation MyActor : NSObject - (void) invokeHandler: (id) handler bridge: (id) bridge { /* * Delegate.Invoke expects and object[] with (object sender, EventArgs args) packed into it * Lets get class representations of ArrayList and EventArgs */ Class ArrayListClass = [bridge getClass: "System.Collections.ArrayList"]; Class EventArgsClass = [bridge getClass: "System.EventArgs"]; // Lets get a new arraylist big enough for our needs id arraylist = [ArrayListClass initWithInt32:2]; // Lets stuff in ourselves as the sender [arraylist AddWithObject:self]; // And a instance of EventArgs [arraylist AddWithObject:[EventArgsClass init]]; // Fly; lets call Delegate.DynamicInvoke [handler DynamicInvokeWithObjectArray:[arraylist ToArray]]; } @end @implementation MyTarget : NSObject - (void) targetMethod: (id) sender args: (id) args { /* * Lets recap; at this point (you'll need to skip and read main below to follow) * At this point we have an instance of MyActor that was created by calling into the * Managed representation of it ([[MyActorClass alloc] init]). We called a native * method on actor; but in fact this trampolined thru managed land because we alloced * a managed instance representation of it. The managed instance of MyActor then trampolined * and translated the call down to the native instance of MyActor (see above). The * native instance of MyActor got passed a native representation of an EventHandler delegate * that is pointing at a native instace of a managed representation of a native class. * MyActor then built and array list and Invoked the delegate. This call trampoilines * back up to native land; and is acted on by the managed instance that handler represents. * This instance (see below) was told to act on MyTarget (this). The delegate will invoke * a S.R.E generated instance of MyTarget.targetMethod which trampolines the call to this * selector. * * Confused yet? :) */ NSLog (@"I was invoked by a %s with %s", [[sender className] cString], [[args className] cString]); } @end int main (void) { // Make Apple shut up [[NSAutoreleasePool alloc] init]; // Get the bridge and initialize it id bridge = [[ObjCSharpBridge alloc] init]; // Load objc representations of the managed representations of the real objc classes Class MyActorClass = [bridge getClass: "MyActor"]; Class MyTargetClass = [bridge getClass: "MyTarget"]; // Load objc representation of EventHandler Class EventHandlerClass = [bridge getClass: "System.EventHandler"]; // Lets generate some instances (this will generate the objc and managed types and glue them together) id actor = [[MyActorClass alloc] init]; id target = [[MyTargetClass alloc] init]; /* * Lets call a native method on actor; that takes an EventHandler as an argument * actor will call Delegate.Invoke (object []) on the EventHandler * the EventHandler is initialized with a target of "target" and method os the selector "targetMethod:args:" * We have a special case for delegates which translates: * new Delegate (object target, MethodInfo method) -> initWithTarget:Selector: */ [actor invokeHandler: [EventHandlerClass initWithTarget: target Selector: "targetMethod:args:"] bridge: bridge]; return 1; }