コード例 #1
0
ファイル: Bridge.cs プロジェクト: emtees/old-code
		private static IntPtr ImplementStaticMethod (IntPtr cls, IntPtr sel, VarargStack stack) {
			try {
				if (!ClassesRegistered.Contains (cls)) 
					return IntPtr.Zero;
				
				ArrayList arguments = new ArrayList ();
				Type type = (Type) ClassesRegistered [cls];
				string selector = Marshal.PtrToStringAuto (sel);                                                      
				Type [] argumentTypes = ArgumentTypesForCall (class_getClassMethod (cls, sel));
	
				MethodInfo method = type.GetMethod (SelectorToMethod (selector, type), BindingFlags.Static | BindingFlags.Public, null, argumentTypes, null);
	
				unsafe {
					int argptr = (int)&sel+4;
					foreach (ParameterInfo parameter in method.GetParameters ()) {
						if (parameter.ParameterType.IsPrimitive || parameter.ParameterType.IsValueType) {
							arguments.Add (Marshal.PtrToStructure ((IntPtr)argptr, parameter.ParameterType));
						} else {
							if (parameter.ParameterType == typeof (string)) 
								arguments.Add (Marshal.PtrToStringAuto (Marshal.ReadIntPtr ((IntPtr)argptr)));
							else {
								IntPtr objectptr = Marshal.ReadIntPtr ((IntPtr)argptr);
								if (ManagedInstances.Contains (objectptr))
									arguments.Add (ManagedInstances [objectptr]);
								else {
									IntPtr objccls = (IntPtr) ObjCMessaging.objc_msgSend (objectptr, "class", typeof (IntPtr));
									if (!NativeClasses.Contains (objccls)) 
										NativeClasses [objccls] = AddTypeForClass ((string) ObjCMessaging.objc_msgSend ((IntPtr) ObjCMessaging.objc_msgSend (objccls, "className", typeof (IntPtr)), "cString", typeof (string)));
	
									object o = ((Type) NativeClasses [objccls]).GetConstructor (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type [] { typeof (IntPtr) }, null).Invoke (new object [] { objectptr });
									ManagedInstances [objectptr] = o;
									NativeInstances [o] = objectptr;
									arguments.Add (o);
								}  
							}
						}
						argptr += Marshal.SizeOf (typeof (IntPtr));
					}
				}
	
				object return_value = type.InvokeMember (SelectorToMethod (selector, type), BindingFlags.Static | BindingFlags.InvokeMethod, null, null, (object [])arguments.ToArray (typeof (object)));
				return ManagedToNative (return_value);
			} catch (TargetInvocationException e) {
				IntPtr nsex = objc_getClass ("NSException");
				IntPtr nsstr = objc_getClass ("NSString");
				IntPtr nm = (IntPtr) ObjCMessaging.objc_msgSend (nsstr, "stringWithUTF8String:", typeof (IntPtr), typeof (string), e.InnerException.GetType ().ToString ());
				IntPtr rsn = (IntPtr) ObjCMessaging.objc_msgSend (nsstr, "stringWithUTF8String:", typeof (IntPtr), typeof (string), e.InnerException.ToString ());
				IntPtr ex = (IntPtr) ObjCMessaging.objc_msgSend (nsex, "exceptionWithName:reason:userInfo:", typeof (IntPtr), typeof (IntPtr), nm, typeof (IntPtr), rsn, typeof (IntPtr), IntPtr.Zero);
				ObjCMessaging.objc_msgSend (ex, "raise", typeof (void));

				throw new Exception ("ImplementMethod post NSException should never be reached");
			} catch (Exception e) {
				IntPtr nsex = objc_getClass ("NSException");
				IntPtr nsstr = objc_getClass ("NSString");
				IntPtr nm = (IntPtr) ObjCMessaging.objc_msgSend (nsstr, "stringWithUTF8String:", typeof (IntPtr), typeof (string), e.GetType ().ToString ());
				IntPtr rsn = (IntPtr) ObjCMessaging.objc_msgSend (nsstr, "stringWithUTF8String:", typeof (IntPtr), typeof (string), e.ToString ());
				IntPtr ex = (IntPtr) ObjCMessaging.objc_msgSend (nsex, "exceptionWithName:reason:userInfo:", typeof (IntPtr), typeof (IntPtr), nm, typeof (IntPtr), rsn, typeof (IntPtr), IntPtr.Zero);
				ObjCMessaging.objc_msgSend (ex, "raise", typeof (void));

				throw new Exception ("ImplementMethod post NSException should never be reached");
			}
		}
コード例 #2
0
ファイル: Bridge.cs プロジェクト: emtees/old-code
		private static IntPtr ConstructObject (IntPtr cls, IntPtr sel, VarargStack stack) {
			if (!ClassesRegistered.Contains (cls)) 
				return IntPtr.Zero;
			
			ArrayList arguments = new ArrayList ();
			Type type = (Type) ClassesRegistered [cls];
			Type [] argumentTypes = ArgumentTypesForCall (class_getClassMethod (cls, sel));
			if (argumentTypes.Length == 0)
				argumentTypes = new Type [0];

			ConstructorInfo constructor = type.GetConstructor (BindingFlags.Instance | BindingFlags.Public, null, argumentTypes, null);

			unsafe {
				int argptr = (int)&sel+4;
				foreach (ParameterInfo parameter in constructor.GetParameters ()) {
					if (parameter.ParameterType.IsPrimitive || parameter.ParameterType.IsValueType) {
						if (type.IsSubclassOf (typeof (Delegate)) && parameter.ParameterType == typeof (IntPtr)) {
							// This is a magic case; we know that the target is on arguments [0];
							object target = arguments [0];
							string selector = Marshal.PtrToStringAuto (Marshal.ReadIntPtr ((IntPtr)argptr));
							MethodInfo target_method = target.GetType ().GetMethod (SelectorToMethod (selector, target.GetType ()));
							arguments.Add (MethodInfoToFtnptr (target_method));
						} else 
							arguments.Add (Marshal.PtrToStructure ((IntPtr)argptr, parameter.ParameterType));
					} else {
						if (parameter.ParameterType == typeof (string)) 
							arguments.Add (Marshal.PtrToStringAuto (Marshal.ReadIntPtr ((IntPtr)argptr)));
						else {
							IntPtr objectptr = Marshal.ReadIntPtr ((IntPtr)argptr);
							if (ManagedInstances.Contains (objectptr))
								arguments.Add (ManagedInstances [objectptr]);
							else {
								IntPtr objccls = (IntPtr) ObjCMessaging.objc_msgSend (objectptr, "class", typeof (IntPtr));
								if (!NativeClasses.Contains (objccls)) 
									NativeClasses [objccls] = AddTypeForClass ((string) ObjCMessaging.objc_msgSend ((IntPtr) ObjCMessaging.objc_msgSend (objccls, "className", typeof (IntPtr)), "cString", typeof (string)));

								object o = ((Type) NativeClasses [objccls]).GetConstructor (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type [] { typeof (IntPtr) }, null).Invoke (new object [] { objectptr });
								ManagedInstances [objectptr] = o;
								NativeInstances [o] = objectptr;
								arguments.Add (o);
							}  
						}
					}
					argptr += Marshal.SizeOf (typeof (IntPtr));
				}
			}
			object return_value = constructor.Invoke ((object [])arguments.ToArray (typeof (object)));
			
			IntPtr native_object = (IntPtr) ObjCMessaging.objc_msgSend (cls, "alloc", typeof (IntPtr));

			ManagedInstances [native_object] = return_value;
			NativeInstances [return_value] = native_object;

			return native_object;
		}