Browse files

Move to old-code

svn path=/trunk/old-code/; revision=156206
  • Loading branch information...
1 parent 8352f77 commit 20b8403e0d696edce4ca99a2360354c232d725e0 @migueldeicaza migueldeicaza committed Apr 27, 2010
Showing with 2,366 additions and 0 deletions.
  1. 0 objc-sharp/AUTHORS
  2. +3 −0 objc-sharp/ChangeLog
  3. +1 −0 objc-sharp/Makefile.am
  4. 0 objc-sharp/NEWS
  5. 0 objc-sharp/README
  6. +156 −0 objc-sharp/autogen.sh
  7. +57 −0 objc-sharp/configure.in
  8. +3 −0 objc-sharp/src/ChangeLog
  9. +1 −0 objc-sharp/src/Makefile.am
  10. +7 −0 objc-sharp/src/bridge/ChangeLog
  11. +9 −0 objc-sharp/src/bridge/Makefile.am
  12. +27 −0 objc-sharp/src/bridge/ObjCSharpBridge.h
  13. +129 −0 objc-sharp/src/bridge/ObjCSharpBridge.m
  14. +6 −0 objc-sharp/src/objc-sharp/AssemblyInfo.cs.in
  15. +979 −0 objc-sharp/src/objc-sharp/Bridge.cs
  16. +12 −0 objc-sharp/src/objc-sharp/ChangeLog
  17. +244 −0 objc-sharp/src/objc-sharp/Mach.cs
  18. +23 −0 objc-sharp/src/objc-sharp/Makefile.am
  19. +30 −0 objc-sharp/src/objc-sharp/NativeMember.cs
  20. +48 −0 objc-sharp/src/objc-sharp/NativeRepresentation.cs
  21. +210 −0 objc-sharp/src/objc-sharp/ObjCMessaging.cs
  22. +10 −0 objc-sharp/src/objc-sharp/VarargStack.cs
  23. BIN objc-sharp/src/objc-sharp/objc-sharp.snk
  24. +3 −0 objc-sharp/test/ChangeLog
  25. +49 −0 objc-sharp/test/Makefile.am
  26. +84 −0 objc-sharp/test/events.m
  27. +21 −0 objc-sharp/test/exceptionhandling.m
  28. +47 −0 objc-sharp/test/instancemethods.m
  29. +45 −0 objc-sharp/test/marshalling.m
  30. +36 −0 objc-sharp/test/staticmethods.m
  31. +3 −0 objc-sharp/test/testlibrary/ChangeLog
  32. +11 −0 objc-sharp/test/testlibrary/ExceptionTests.cs
  33. +59 −0 objc-sharp/test/testlibrary/InstanceTests.cs
  34. +21 −0 objc-sharp/test/testlibrary/Makefile.am
  35. +13 −0 objc-sharp/test/testlibrary/NativeMarshalTests.cs
  36. +19 −0 objc-sharp/test/testlibrary/StaticTests.cs
View
0 objc-sharp/AUTHORS
No changes.
View
3 objc-sharp/ChangeLog
@@ -0,0 +1,3 @@
+2005-10-25 Geoff Norton <gnorton@customerdna.com>
+
+ * Initial import
View
1 objc-sharp/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=src test
View
0 objc-sharp/NEWS
No changes.
View
0 objc-sharp/README
No changes.
View
156 objc-sharp/autogen.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+set -e
+
+PACKAGE=objc-sharp
+
+LIBTOOLIZE=${LIBTOOLIZE-libtoolize}
+LIBTOOLIZE_FLAGS="--copy --force"
+AUTOHEADER=${AUTOHEADER-autoheader}
+AUTOMAKE_FLAGS="--add-missing"
+AUTOCONF=${AUTOCONF-autoconf}
+
+automake_min_vers=1.6
+aclocal_min_vers=$automake_min_vers
+autoconf_min_vers=2.59
+libtoolize_min_vers=1.5
+
+LC_ALL=C
+
+ARGV0=$0
+
+srcdir=`dirname $ARGV0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+
+cd $srcdir
+
+if ($AUTOCONF --version) < /dev/null > /dev/null 2>&1 ; then
+ if ($AUTOCONF --version | head -n 1 | awk 'NR==1 { if( $(NF) >= '$autoconf_min_vers') \
+ exit 1; exit 0; }');
+ then
+ echo "$ARGV0: ERROR: \`$AUTOCONF' is too old."
+ $AUTOCONF --version
+ echo " (version $autoconf_min_vers or newer is required)"
+ DIE="yes"
+ fi
+else
+ echo $AUTOCONF: command not found
+ echo
+ echo "$ARGV0: ERROR: You must have \`autoconf' installed to compile $PACKAGE."
+ echo " (version $autoconf_min_vers or newer is required)"
+ DIE="yes"
+fi
+
+if test x"$AUTOMAKE" = x || test x"$ACLOCAL" = x ; then
+ am_ver=""
+ for ver in "" "-1.9" "-1.8" "-1.7" ; do
+ am="automake$ver"
+ if ($am --version) < /dev/null > /dev/null 2>&1 ; then
+ if ($am --version | head -n 1 | awk 'NR==1 { if( $(NF) >= '$automake_min_vers') \
+ exit 1; exit 0; }'); then : ; else
+ am_ver=$ver
+ break;
+ fi
+ fi
+ done
+
+ AUTOMAKE=${AUTOMAKE-automake$am_ver}
+ ACLOCAL=${ACLOCAL-aclocal$am_ver}
+fi
+
+if ($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 ; then
+ if ($AUTOMAKE --version | head -n 1 | awk 'NR==1 { if( $(NF) >= '$automake_min_vers') \
+ exit 1; exit 0; }');
+ then
+ echo "$ARGV0: ERROR: \`$AUTOMAKE' is too old."
+ $AUTOMAKE --version
+ echo " (version $automake_min_vers or newer is required)"
+ DIE="yes"
+ fi
+ if ($ACLOCAL --version) < /dev/null > /dev/null 2>&1; then
+ if ($ACLOCAL --version | head -n 1 | awk 'NR==1 { if( $(NF) >= '$aclocal_min_vers' ) \
+ exit 1; exit 0; }' );
+ then
+ echo "$ARGV0: ERROR: \`$ACLOCAL' is too old."
+ $ACLOCAL --version
+ echo " (version $aclocal_min_vers or newer is required)"
+ DIE="yes"
+ fi
+ else
+ echo $ACLOCAL: command not found
+ echo
+ echo "$ARGV0: ERROR: Missing \`$ACLOCAL'"
+ echo " The version of $AUTOMAKE installed doesn't appear recent enough."
+ DIE="yes"
+ fi
+else
+ echo $AUTOMAKE: command not found
+ echo
+ echo "$ARGV0: ERROR: You must have \`automake' installed to compile $PACKAGE."
+ echo " (version $automake_min_vers or newer is required)"
+ DIE="yes"
+fi
+
+if ($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 ; then
+ if ($LIBTOOLIZE --version | awk 'NR==1 { if( $4 >= '$libtoolize_min_vers') \
+ exit 1; exit 0; }');
+ then
+ echo "$ARGV0: ERROR: \`$LIBTOOLIZE' is too old."
+ echo " (version $libtoolize_min_vers or newer is required)"
+ DIE="yes"
+ fi
+else
+ echo $LIBTOOLIZE: command not found
+ echo
+ echo "$ARGV0: ERROR: You must have \`libtoolize' installed to compile $PACKAGE."
+ echo " (version $libtoolize_min_vers or newer is required)"
+ DIE="yes"
+fi
+
+if test -z "$ACLOCAL_FLAGS"; then
+ acdir=`$ACLOCAL --print-ac-dir`
+ if [ ! -f $acdir/pkg.m4 ]; then
+ echo "$ARGV0: Error: Could not find pkg-config macros."
+ echo " (Looked in $acdir/pkg.m4)"
+ echo " If pkg.m4 is available in /another/directory, please set"
+ echo " ACLOCAL_FLAGS=\"-I /another/directory\""
+ echo " Otherwise, please install pkg-config."
+ echo ""
+ echo "pkg-config is available from:"
+ echo "http://www.freedesktop.org/software/pkgconfig/"
+ DIE=yes
+ fi
+fi
+
+if test "X$DIE" != X; then
+ exit 1
+fi
+
+
+if test -z "$*"; then
+ echo "$ARGV0: Note: \`./configure' will be run with no arguments."
+ echo " If you wish to pass any to it, please specify them on the"
+ echo " \`$0' command line."
+ echo
+fi
+
+do_cmd() {
+ echo "$ARGV0: running \`$@'"
+ $@
+}
+
+do_cmd $LIBTOOLIZE $LIBTOOLIZE_FLAGS
+
+do_cmd $ACLOCAL $ACLOCAL_FLAGS
+
+do_cmd $AUTOHEADER
+
+do_cmd $AUTOMAKE $AUTOMAKE_FLAGS
+
+do_cmd $AUTOCONF
+
+cd $ORIGDIR || exit 1
+
+do_cmd $srcdir/configure --enable-maintainer-mode ${1+"$@"} && echo "Now type \`make' to compile" || exit 1
View
57 objc-sharp/configure.in
@@ -0,0 +1,57 @@
+
+AC_INIT(README)
+AC_CANONICAL_SYSTEM
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(objc-sharp, 0.9.0)
+AM_MAINTAINER_MODE
+
+API_VERSION=0.9.0.0
+AC_SUBST(API_VERSION)
+
+AC_CHECK_TOOL(CC, gcc, gcc)
+AC_PROG_CC
+AC_PROG_INSTALL
+
+AC_HEADER_STDC
+AM_PROG_LIBTOOL
+
+# 64bit totally untested send patches
+AC_CHECK_SIZEOF(void *, 4)
+
+MONO_REQUIRED_VERSION=1.1.9
+PKG_CHECK_MODULES(MONO, mono >= $MONO_REQUIRED_VERSION, has_mono=true, has_mono=false)
+
+AC_PATH_PROG(GACUTIL, gacutil, no)
+if test "x$GACUTIL" = "xno" ; then
+ AC_MSG_ERROR([Cannot locate gacutil. Please install mono])
+fi
+
+if test "x$has_mono" = "xtrue"; then
+ GACUTIL_FLAGS='/package $(PACKAGE_VERSION) /gacdir $(DESTDIR)$(prefix)/lib'
+ AC_PATH_PROG(RUNTIME, mono, no)
+ AC_PATH_PROG(MCS, mcs, no)
+else
+ AC_MSG_ERROR([You need to install mono >= 1.1.9])
+fi
+
+OBJC="gcc"
+OBJCFLAGS=""
+_AM_DEPENDENCIES(OBJC)
+
+AC_SUBST(MCS)
+AC_SUBST(GACUTIL)
+AC_SUBST(GACUTIL_FLAGS)
+AC_SUBST(MONO_CFLAGS)
+AC_SUBST(MONO_LIBS)
+AC_SUBST(OBJC)
+AC_SUBST(OBJCFLAGS)
+
+AC_OUTPUT([
+Makefile
+src/Makefile
+src/objc-sharp/AssemblyInfo.cs
+src/objc-sharp/Makefile
+src/bridge/Makefile
+test/Makefile
+test/testlibrary/Makefile
+])
View
3 objc-sharp/src/ChangeLog
@@ -0,0 +1,3 @@
+2005-10-25 Geoff Norton <gnorton@customerdna.com>
+
+ * Initial import
View
1 objc-sharp/src/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=bridge objc-sharp
View
7 objc-sharp/src/bridge/ChangeLog
@@ -0,0 +1,7 @@
+2006-05-21 Eric Butler <eric@extremeboredom.net>
+
+ * src/bridge/ObjCSharpBridge.m: Assign "kls" to the exception's class
+
+2005-10-25 Geoff Norton <gnorton@customerdna.com>
+
+ * Initial import
View
9 objc-sharp/src/bridge/Makefile.am
@@ -0,0 +1,9 @@
+lib_LTLIBRARIES=libObjCSharp.la
+
+libObjCSharp_la_SOURCES= \
+ ObjCSharpBridge.h \
+ ObjCSharpBridge.m
+
+libObjCSharp_la_OBJCFLAGS=$(MONO_CFLAGS)
+libObjCSharp_la_LDFLAGS=
+libObjCSharp_la_LIBADD=
View
27 objc-sharp/src/bridge/ObjCSharpBridge.h
@@ -0,0 +1,27 @@
+#import <ObjCSharpBridge.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSException.h>
+#import <objc/objc-class.h>
+#import <mono/metadata/class.h>
+#import <mono/metadata/object.h>
+#import <mono/metadata/assembly.h>
+#import <mono/metadata/image.h>
+#import <mono/metadata/appdomain.h>
+
+@interface ObjCSharpBridge : NSObject
+
+ NSString *exceptionName;
+ MonoDomain *domain;
+ MonoAssembly *assembly;
+ MonoImage *image;
+ MonoClass *klass;
+ MonoMethod *getclass;
+ MonoMethod *loader;
+ MonoObject *object;
+
+ - (id) init;
+ - (void) release;
+ - (int) loadAssembly: (char *) name;
+ - (char *) exceptionToString: (MonoObject *) ex;
+ - (Class) getClass: (char *) type;
+@end
View
129 objc-sharp/src/bridge/ObjCSharpBridge.m
@@ -0,0 +1,129 @@
+#import <ObjCSharpBridge.h>
+
+@implementation ObjCSharpBridge
+
+- init
+{
+ [super init];
+
+ exceptionName = [[NSString stringWithUTF8String:"ObjCSharpBridgeException"] retain];
+
+ domain = (MonoDomain *)mono_jit_init ("ObjCSharp");
+ if (!domain)
+ [[NSException exceptionWithName: exceptionName reason: [NSString stringWithUTF8String:"objc-sharp.dll not found for mono_jit_init"] userInfo: nil] raise];
+
+
+ assembly = mono_domain_assembly_open (domain, "objc-sharp.dll");
+ if (!assembly)
+ [[NSException exceptionWithName: exceptionName reason: [NSString stringWithUTF8String:"assembly open error for: objc-sharp.dll"] userInfo: nil] raise];
+
+ image = mono_assembly_get_image (assembly);
+ if (!image)
+ [[NSException exceptionWithName: exceptionName reason: [NSString stringWithUTF8String:"image open error for: objc-sharp.dll"] userInfo: nil] raise];
+
+ klass = mono_class_from_name (image, "ObjCSharp", "Bridge");
+ if (!klass)
+ [[NSException exceptionWithName: exceptionName reason: [NSString stringWithUTF8String:"class open error for: ObjCSharp.Bridge"] userInfo: nil] raise];
+
+ getclass = mono_class_get_method_from_name (klass, "GetClass", 1);
+ if (!getclass)
+ [[NSException exceptionWithName: exceptionName reason: [NSString stringWithUTF8String:"method not found in ObjCSharp.Bridge"] userInfo: nil] raise];
+
+ loader = mono_class_get_method_from_name (klass, "LoadAssembly", 1);
+ if (!loader)
+ [[NSException exceptionWithName: exceptionName reason: [NSString stringWithUTF8String:"method not found in ObjCSharp.Bridge"] userInfo: nil] raise];
+
+ object = mono_object_new (domain, klass);
+
+ mono_runtime_object_init (object);
+
+ mono_assembly_set_main (assembly);
+ mono_runtime_exec_main (mono_class_get_method_from_name (klass, "SetupBridge", 0), (MonoArray *)object, NULL);
+
+// mono_set_defaults (5, 0);
+
+ return self;
+}
+
+- (void) release
+{
+ [super release];
+ mono_jit_cleanup (domain);
+}
+
+- (int) loadAssembly: (char *) name
+{
+ gpointer args [1];
+ MonoString *namestr;
+ MonoObject *exception;
+
+ namestr = mono_string_new (domain, name);
+
+ args [0] = namestr;
+ MonoObject *ret = mono_runtime_invoke (loader, object, args, &exception);
+ if (exception)
+ [[NSException exceptionWithName: [NSString stringWithUTF8String:mono_class_get_name (mono_object_get_class (exception))] reason: [NSString stringWithUTF8String:[self exceptionToString: exception]] userInfo: nil] raise];
+ return 1;
+}
+
+- (char *) exceptionToString: (MonoObject *) ex
+{
+ MonoClass *kls;
+ MonoMethod *mth;
+ MonoString *str;
+
+ kls = mono_object_get_class (ex);
+
+ mth = mono_class_get_method_from_name_flags (kls, "ToString", 0, 0x0040 | 0x0006);
+
+ str = (MonoString *) mono_runtime_invoke (mth, ex, NULL, NULL);
+
+ return mono_string_to_utf8 (str);
+}
+
+- (Class) getClass: (char *) type
+{
+ gpointer args [1];
+ MonoString *typestr;
+ MonoObject *exception;
+
+ typestr = mono_string_new (domain, type);
+
+ args [0] = typestr;
+ MonoObject *ret = mono_runtime_invoke (getclass, object, args, &exception);
+ if (exception)
+ [[NSException exceptionWithName: [NSString stringWithUTF8String:mono_class_get_name (mono_object_get_class (exception))] reason: [NSString stringWithUTF8String:[self exceptionToString: exception]] userInfo: nil] raise];
+ return (Class)*(int *)mono_object_unbox (ret);
+}
+@end
+
+void setupDelegate (void *ptr) {}
+
+void dumpMethodList (struct objc_method_list *method_list) {
+ int i = 0;
+ if (method_list != nil && method_list != (struct objc_method_list *)0xffffffff) {
+ struct objc_method *method = method_list->method_list;
+ printf ("methods: %i\n", method_list->method_count);
+ for (i = 0; i < method_list->method_count; method++, i++) {
+ printf ("\tname: %s\n", method->method_name);
+ printf ("\ttypes: %s\n", method->method_types);
+ printf ("\timp: %x\n", method->method_imp);
+ }
+ }
+}
+
+void dumpClass (struct objc_class *cls) {
+ printf ("name: %s %s\n", cls->name, cls->isa->name);
+ printf ("\tversion: %i\n", cls->version);
+ printf ("\tinfo: %i\n", cls->info);
+ printf ("\tinstance_size: %i %i\n", cls->instance_size, cls->isa->instance_size);
+ printf ("\tsuper_class: %x %s\n", cls->super_class, cls->super_class->name);
+ printf ("\tivars: %x\n", cls->ivars);
+ printf ("\tmethodLists: %x\n", cls->methodLists);
+ printf ("\tcache: %x\n", cls->cache);
+ printf ("\tprotocols: %x\n", cls->protocols);
+ if (cls->methodLists) {
+ dumpMethodList (*cls->methodLists);
+ }
+}
+
View
6 objc-sharp/src/objc-sharp/AssemblyInfo.cs.in
@@ -0,0 +1,6 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly:AssemblyVersion("@API_VERSION@")]
+[assembly:AssemblyDelaySign(false)]
+[assembly:AssemblyKeyFile("objc-sharp.snk")]
View
979 objc-sharp/src/objc-sharp/Bridge.cs
@@ -0,0 +1,979 @@
+#define DEBUG
+
+using System;
+using System.Threading;
+using System.Reflection;
+using System.Collections;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+
+namespace ObjCSharp {
+ public class Bridge {
+ protected static IDictionary RegisteredClasses = new Hashtable ();
+ protected static IDictionary ClassesRegistered = new Hashtable ();
+ protected static IDictionary ManagedInstances = new Hashtable ();
+ protected static IDictionary NativeInstances = new Hashtable ();
+ protected static IDictionary LoadedAssemblies = new Hashtable ();
+
+ protected static IDictionary NativeClasses = new Hashtable ();
+
+ private static IMPDelegate implement_method;
+ private static IMPDelegate implement_static_method;
+ private static IMPDelegate construct_object;
+
+ public delegate IntPtr IMPDelegate (IntPtr cls, IntPtr sel, VarargStack stack);
+
+ private static AssemblyBuilder assembly_builder;
+ private static AssemblyName assembly_name;
+ private static ModuleBuilder module_builder;
+
+ public static void SetupBridge () {
+ implement_method = new IMPDelegate (ImplementMethod);
+ implement_static_method = new IMPDelegate (ImplementStaticMethod);
+ construct_object = new IMPDelegate (ConstructObject);
+ setupDelegate (implement_method);
+ setupDelegate (implement_static_method);
+ setupDelegate (construct_object);
+
+ AppDomain.CurrentDomain.TypeResolve += new ResolveEventHandler(TypeResolver);
+// Mach.InstallExceptionHandler ();
+
+ assembly_name = new AssemblyName ();
+ assembly_name.Name = "ObjCSharp";
+ assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly (assembly_name, AssemblyBuilderAccess.Run);
+ module_builder = assembly_builder.DefineDynamicModule (assembly_name.Name);
+ }
+
+ private static IntPtr MethodInfoToFtnptr (MethodInfo method) {
+ if (module_builder.Assembly.GetType ("BridgeHelpers" + method.ToString ()) != null)
+ return (IntPtr) module_builder.Assembly.GetType ("BridgeHelpers" + method.ToString ()).InvokeMember ("InternalMethodInfoToFtnPtr", BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.Public, null, null, new object[] { });
+
+ TypeBuilder ftn_converter_builder = module_builder.DefineType ("BridgeHelpers" + method.ToString (), TypeAttributes.Public);
+ MethodBuilder ftn_method = ftn_converter_builder.DefineMethod ("InternalMethodInfoToFtnPtr", MethodAttributes.Public | MethodAttributes.Static, typeof (IntPtr), new Type[] { });
+ ILGenerator il_generator = ftn_method.GetILGenerator ();
+
+ il_generator.Emit (OpCodes.Ldftn, method);
+ il_generator.Emit (OpCodes.Ret);
+
+ Type ftn_converter = ftn_converter_builder.CreateType ();
+ return (IntPtr) ftn_converter.InvokeMember ("InternalMethodInfoToFtnPtr", BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.Public, null, null, new object[] { });
+ }
+
+ 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");
+ }
+ }
+
+ private static IntPtr ImplementMethod (IntPtr cls, IntPtr sel, VarargStack stack) {
+ try {
+ if (!ManagedInstances.Contains (cls))
+ return IntPtr.Zero;
+
+ ArrayList arguments = new ArrayList ();
+ object target = (object) ManagedInstances [cls];
+ Type type = target.GetType ();
+ Type [] argumentTypes = ArgumentTypesForCall (class_getInstanceMethod ((IntPtr) ObjCMessaging.objc_msgSend (cls, "class", typeof (IntPtr)), sel));
+
+ string selector = Marshal.PtrToStringAuto (sel);
+ MethodInfo method = type.GetMethod (SelectorToMethod (selector, type), BindingFlags.Instance | 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 (objectptr == IntPtr.Zero)
+ arguments.Add (null);
+ else 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.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, target, (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");
+ }
+ }
+
+ 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;
+ }
+
+ private static Type [] ArgumentTypesForCall (IntPtr native_method) {
+ if (native_method == IntPtr.Zero)
+ return new Type [0];
+
+ int num_arguments = method_getNumberOfArguments (native_method);
+ Type [] types = new Type [num_arguments-2];
+ IntPtr typestr = IntPtr.Zero;
+ int offset = 0;
+
+ for (int i = 2; i < num_arguments; i++) {
+ method_getArgumentInfo (native_method, i, ref typestr, ref offset);
+ types [i-2] = DecodedType (Marshal.PtrToStringAuto (typestr));
+ }
+ return types;
+ }
+
+ private static object NativeToManaged (IntPtr ptr) {
+ if (ptr == IntPtr.Zero)
+ return null;
+
+ if (ManagedInstances.Contains (ptr))
+ return ManagedInstances [ptr];
+
+ IntPtr objccls = (IntPtr) ObjCMessaging.objc_msgSend (ptr, "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 [] { ptr });
+ ManagedInstances [ptr] = o;
+ NativeInstances [o] = ptr;
+
+ return o;
+ }
+
+ private static IntPtr ManagedToNative (object return_value) {
+ if (return_value == null)
+ return IntPtr.Zero;
+
+ if (NativeInstances.Contains (return_value))
+ return (IntPtr) NativeInstances [return_value];
+
+ Type type = return_value.GetType ();
+ IntPtr native_object = IntPtr.Zero;
+
+ if (type == typeof (string)) {
+ native_object = Marshal.StringToHGlobalAuto ((string)return_value);
+ } else if (type.IsPrimitive || type.IsValueType) {
+ native_object = Marshal.AllocHGlobal (Marshal.SizeOf (return_value.GetType ()));
+ Marshal.StructureToPtr (return_value, native_object, true);
+ } else {
+ IntPtr cls = RegisterClass (type.FullName);
+ native_object = (IntPtr) ObjCMessaging.objc_msgSend (cls, "alloc", typeof (IntPtr));
+ NativeInstances [return_value] = native_object;
+ ManagedInstances [native_object] = return_value;
+ }
+
+ return native_object;
+ }
+
+ public static void LoadAssembly (string name) {
+ LoadedAssemblies [name] = AppDomain.CurrentDomain.Load (AssemblyName.GetAssemblyName (name));
+ foreach (AssemblyName referenced in ((Assembly)LoadedAssemblies [name]).GetReferencedAssemblies ())
+ LoadedAssemblies [referenced] = AppDomain.CurrentDomain.Load (referenced);
+ }
+
+ public static IntPtr GetClass (string classname) {
+ IntPtr clsptr = RegisterClass (classname);
+ return clsptr;
+ }
+
+ public static IntPtr RegisterClass (string classname) {
+ if (RegisteredClasses.Contains (classname))
+ return (IntPtr) RegisteredClasses [classname];
+
+ Type type = Type.GetType (classname);
+
+ if (type == null)
+ throw new ArgumentException ("Attempting to register a null type");
+
+ if (module_builder.GetType (type.ToString ()) != null)
+ return (IntPtr) objc_getClass (classname);
+
+ IntPtr super_class = objc_lookUpClass ("NSObject");
+
+ IntPtr return_value = objc_lookUpClass (classname);
+ if (return_value != IntPtr.Zero)
+ return return_value;
+
+ NativeRepresentation representation = GenerateNativeRepresentation (type);
+ IntPtr [] methods = new IntPtr [representation.Methods.Length];
+ IntPtr [] signatures = new IntPtr [representation.Methods.Length];
+ IntPtr [] staticmethods = new IntPtr [representation.StaticMethods.Length];
+ IntPtr [] staticsignatures = new IntPtr [representation.StaticMethods.Length];
+ IntPtr [] constructors = new IntPtr [representation.Constructors.Length];
+ IntPtr [] constructor_signatures = new IntPtr [representation.Constructors.Length];
+ IntPtr [] member_names = new IntPtr [representation.Members.Length];
+ IntPtr [] member_types = new IntPtr [representation.Members.Length];
+
+ for (int i = 0; i < representation.Constructors.Length; i++) {
+ constructors [i] = Marshal.StringToCoTaskMemAnsi (representation.Constructors [i]);
+ constructor_signatures [i] = Marshal.StringToCoTaskMemAnsi (representation.ConstructorSignatures [i]);
+ }
+
+ for (int i = 0; i < representation.StaticMethods.Length; i++) {
+ staticmethods [i] = Marshal.StringToCoTaskMemAnsi (representation.StaticMethods [i]);
+ staticsignatures [i] = Marshal.StringToCoTaskMemAnsi (representation.StaticSignatures [i]);
+ }
+
+ for (int i = 0; i < representation.Methods.Length; i++) {
+ methods [i] = Marshal.StringToCoTaskMemAnsi (representation.Methods [i]);
+ signatures [i] = Marshal.StringToCoTaskMemAnsi (representation.Signatures [i]);
+ }
+
+ for (int i = 0; i < representation.Members.Length; i++) {
+ member_names [i] = Marshal.StringToCoTaskMemAnsi (representation.Members [i].Name);
+ member_types [i] = Marshal.StringToCoTaskMemAnsi (representation.Members [i].Type);
+ }
+
+ // MAGIC WARNING: This is serious voodoo; touch at your own risk
+ unsafe {
+ // This is from this layout:
+ /*
+ struct objc_class {
+ struct objc_class *isa;
+ struct objc_class *super_class;
+ const char *name;
+ long version;
+ long info;
+ long instance_size;
+ struct objc_ivar_list *ivars;
+ struct objc_method_list **methodLists;
+ struct objc_cache *cache;
+ struct objc_protocol_list *protocols;
+ }
+ */
+
+ // lets cache some frequently used values
+ FieldInfo delegate_target = typeof (Delegate).GetField ("delegate_trampoline", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ int ptrsize = Marshal.SizeOf (typeof (IntPtr));
+ int longsize = Marshal.SizeOf (typeof (int)); // Longs are 4 in native land
+ int intsize = Marshal.SizeOf (typeof (int));
+
+ char *nameptr = (char*)Marshal.StringToHGlobalAuto (classname);
+ void *root_class = (void*)super_class;
+
+ // We first need to find the root_class; we do this by walking up ->super_class
+ while ((int)*((int *)((int)root_class+ptrsize)) != 0) {
+ root_class = (void *)(int)*((int *)((int)root_class+ptrsize));
+ }
+ // allocate the class
+ void *new_class = (void*)Marshal.AllocHGlobal ((ptrsize*7) + (longsize*3));
+ void *meta_class = (void*)Marshal.AllocHGlobal ((ptrsize*7) + (longsize*3));
+
+ // setup the class
+ *(int *)((int)new_class+0) = (int)meta_class;
+ *(int *)((int)new_class+(ptrsize*3)+longsize) = 0x1;
+ *(int *)((int)meta_class+(ptrsize*3)+longsize) = 0x2;
+
+ // set the class name
+ *(int *)((int)new_class+(ptrsize*2)) = (int)nameptr;
+ *(int *)((int)meta_class+(ptrsize*2)) = (int)nameptr;
+
+ // set the class version
+ *(int *)((int)new_class+(ptrsize*3)) = 0;
+ *(int *)((int)meta_class+(ptrsize*3)) = 0;
+
+ // connect the class heirarchy
+ *(int *)((int)new_class+ptrsize) = (int)super_class;
+ *(int *)((int)meta_class+ptrsize) = (int)*(int *)((int)super_class);
+ *(int *)((int)meta_class) = (int)*(int *)((int)root_class);
+
+ // put in empty method lists for now
+ void *new_class_mlist = (void *)Marshal.AllocHGlobal ((ptrsize*2)+intsize);
+ void *meta_class_mlist = (void *)Marshal.AllocHGlobal ((ptrsize*2)+intsize);
+
+ *(int *)((int)new_class_mlist) = -1;
+ *(int *)((int)meta_class_mlist) = -1;
+
+ *(int *)((int)new_class+(ptrsize*4)+(longsize*3)) = (int)new_class_mlist;
+ *(int *)((int)meta_class+(ptrsize*4)+(longsize*3)) = (int)meta_class_mlist;
+
+ // add the ivars
+ int ivar_size = (int)*(int *)((int)super_class+(ptrsize*3)+(longsize*2));
+ void *ivar_list = (void *)Marshal.AllocHGlobal (intsize+ptrsize+((representation.Members.Length+1)*((ptrsize*2)+intsize)));
+ void *ivar = (void*)((int)ivar_list+intsize);
+ *(int *)((int)ivar_list) = representation.Members.Length;
+ for (int i = 0; i < representation.Members.Length; i++) {
+ *(int *)((int)ivar) = (int)member_names [i];
+ *(int *)((int)ivar+ptrsize) = (int)member_types [i];
+ *(int *)((int)ivar+(ptrsize*2)) = ivar_size;
+ ivar_size += representation.Members [i].Size;
+ ivar = (void *)((int)ivar+(ptrsize*2)+intsize);
+ }
+ *(int *)((int)new_class+(ptrsize*3)+(longsize*3)) = (int)ivar_list;
+ *(int *)((int)meta_class+(ptrsize*3)+(longsize*3)) = 0;
+
+ *(int *)((int)ivar) = (int)Marshal.StringToCoTaskMemAnsi ("methodCallback");
+ *(int *)((int)ivar+ptrsize) = (int)Marshal.StringToCoTaskMemAnsi ("^?");
+ *(int *)((int)ivar+(ptrsize*2)) = ivar_size;
+ ivar_size += 4;
+
+ *(int *)((int)new_class+(ptrsize*3)+(longsize*2)) = ivar_size;
+ *(int *)((int)meta_class+(ptrsize*3)+(longsize*2)) = (int)*(int *)(((int)((int*)(int)*(int *)((int)meta_class+ptrsize)))+(ptrsize*3)+(longsize*2));
+
+ // zero the cache and protocols;
+ *(int *)((int)new_class+(ptrsize*5)+(longsize*3)) = 0;
+ *(int *)((int)new_class+(ptrsize*6)+(longsize*3)) = 0;
+ *(int *)((int)meta_class+(ptrsize*5)+(longsize*3)) = 0;
+ *(int *)((int)meta_class+(ptrsize*6)+(longsize*3)) = 0;
+
+ objc_addClass ((IntPtr)new_class);
+
+ // add the methods
+ void *method_list;
+ void *methodptr;
+ IntPtr trampoline;
+
+ if (representation.Methods.Length > 0) {
+ method_list = (void *)Marshal.AllocHGlobal (ptrsize+intsize+((representation.Methods.Length)*(ptrsize*3)));
+ *(int *)((int)method_list+ptrsize) = representation.Methods.Length;
+ methodptr = (void*)((int)method_list+ptrsize+intsize);
+ trampoline = (IntPtr)delegate_target.GetValue (implement_method);
+ for (int i = 0; i < representation.Methods.Length; i++) {
+ *(int *)((int)methodptr) = (int)sel_getUid (methods [i]);
+ *(int *)((int)methodptr+ptrsize) = (int)signatures [i];
+ *(int *)((int)methodptr+(ptrsize*2)) = (int)trampoline;
+ methodptr = (void *)((int)methodptr+(ptrsize*3));
+ }
+
+
+ class_addMethods ((IntPtr)new_class, (IntPtr)method_list);
+ }
+
+ if (representation.Constructors.Length > 0) {
+ method_list = (void *)Marshal.AllocHGlobal (ptrsize+intsize+((representation.Constructors.Length)*(ptrsize*3)));
+ *(int *)((int)method_list+ptrsize) = representation.Constructors.Length;
+ methodptr = (void*)((int)method_list+ptrsize+intsize);
+ trampoline = (IntPtr)delegate_target.GetValue (construct_object);
+ for (int i = 0; i < representation.Constructors.Length; i++) {
+ *(int *)((int)methodptr) = (int)sel_getUid (constructors [i]);
+ *(int *)((int)methodptr+ptrsize) = (int)constructor_signatures [i];
+ *(int *)((int)methodptr+(ptrsize*2)) = (int)trampoline;
+ methodptr = (void *)((int)methodptr+(ptrsize*3));
+ }
+
+ class_addMethods ((IntPtr)meta_class, (IntPtr)method_list);
+ }
+
+ if (representation.StaticMethods.Length > 0) {
+ method_list = (void *)Marshal.AllocHGlobal (ptrsize+intsize+((representation.StaticMethods.Length)*(ptrsize*3)));
+ *(int *)((int)method_list+ptrsize) = representation.StaticMethods.Length;
+ methodptr = (void*)((int)method_list+ptrsize+intsize);
+ trampoline = (IntPtr)delegate_target.GetValue (implement_static_method);
+ for (int i = 0; i < representation.StaticMethods.Length; i++) {
+ *(int *)((int)methodptr) = (int)sel_getUid (staticmethods [i]);
+ *(int *)((int)methodptr+ptrsize) = (int)staticsignatures [i];
+ *(int *)((int)methodptr+(ptrsize*2)) = (int)trampoline;
+ methodptr = (void *)((int)methodptr+(ptrsize*3));
+ }
+
+ class_addMethods ((IntPtr)meta_class, (IntPtr)method_list);
+ }
+ return_value = (IntPtr)new_class;
+ }
+ // END MAGIC
+
+ RegisteredClasses [classname] = return_value;
+ ClassesRegistered [return_value] = type;
+
+ return return_value;
+ }
+
+ internal static NativeRepresentation GenerateNativeRepresentation (Type type) {
+ NativeRepresentation representation = new NativeRepresentation ();
+
+ ArrayList constructors = new ArrayList ();
+ ArrayList constructor_signatures = new ArrayList ();
+ ArrayList methods = new ArrayList ();
+ ArrayList signatures = new ArrayList ();
+ ArrayList staticmethods = new ArrayList ();
+ ArrayList staticsignatures = new ArrayList ();
+ ArrayList nativemembers = new ArrayList ();
+
+ foreach (MethodInfo method in type.GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
+ signatures.Add (GenerateMethodSignature (method));
+ methods.Add (MethodToSelector (method));
+ }
+
+ foreach (MethodInfo method in type.GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) {
+ staticsignatures.Add (GenerateMethodSignature (method));
+ staticmethods.Add (MethodToSelector (method));
+ }
+
+ foreach (ConstructorInfo constructor in type.GetConstructors (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance)) {
+ constructor_signatures.Add (GenerateConstructorSignature (constructor));
+ constructors.Add (ConstructorToSelector (constructor, type));
+ }
+
+ // FIXME: Implement members
+
+ representation.Constructors = (string[])constructors.ToArray (typeof (string));
+ representation.ConstructorSignatures = (string[])constructor_signatures.ToArray (typeof (string));
+ representation.Methods = (string[])methods.ToArray (typeof (string));
+ representation.Signatures = (string[])signatures.ToArray (typeof (string));
+ representation.StaticMethods = (string[])staticmethods.ToArray (typeof (string));
+ representation.StaticSignatures = (string[])staticsignatures.ToArray (typeof (string));
+ representation.Members = (NativeMember[])nativemembers.ToArray (typeof (NativeMember));
+
+ return representation;
+ }
+
+ public static Type DecodedType (string objctype) {
+ switch (objctype.Substring (0, 1)) {
+ case "c":
+ return typeof (char);
+ case "C":
+ return typeof (char);
+ case "s":
+ return typeof (short);
+ case "S":
+ return typeof (ushort);
+ case "i":
+ return typeof (int);
+ case "I":
+ return typeof (uint);
+ case "l":
+ return typeof (long);
+ case "L":
+ return typeof (ulong);
+ case "f":
+ return typeof (float);
+ case "d":
+ return typeof (double);
+ case "v":
+ return typeof (void);
+ case "?":
+ return typeof (object);
+ case "^":
+ return typeof (IntPtr);
+ case "*":
+ return typeof (string);
+ case "B":
+ return typeof (bool);
+ case "@":
+ return typeof (object);
+ case "(": {
+ int index = objctype.IndexOf (")");
+
+ if (index > 0)
+ return Type.GetType (objctype.Substring (1, index-1));
+ else
+ throw new Exception ("DecodedType decoding exception for unknown: " + objctype);
+ }
+ default:
+ throw new Exception ("DecodedType decoding exception for unknown: " + objctype);
+ }
+ }
+
+ public static string EncodedType (Type type, out int size) {
+ if (type == typeof (char)) {
+ size = Marshal.SizeOf (typeof (char));
+ return "c";
+ }
+ if (type == typeof (Int32)) {
+ size = Marshal.SizeOf (typeof (Int32));
+ return "i";
+ }
+ if (type == typeof (short)) {
+ size = Marshal.SizeOf (typeof (short));
+ return "s";
+ }
+ if (type == typeof (long)) {
+ size = Marshal.SizeOf (typeof (long));
+ return "l";
+ }
+ if (type == typeof (Int64)) {
+ size = Marshal.SizeOf (typeof (Int64));
+ return "q";
+ }
+ if (type == typeof (UInt32)) {
+ size = Marshal.SizeOf (typeof (UInt32));
+ return "I";
+ }
+ if (type == typeof (ushort)) {
+ size = Marshal.SizeOf (typeof (ushort));
+ return "S";
+ }
+ if (type == typeof (ulong)) {
+ size = Marshal.SizeOf (typeof (ulong));
+ return "L";
+ }
+ if (type == typeof (UInt64)) {
+ size = Marshal.SizeOf (typeof (UInt64));
+ return "Q";
+ }
+ if (type == typeof (float)) {
+ size = Marshal.SizeOf (typeof (float));
+ return "f";
+ }
+ if (type == typeof (double)) {
+ size = Marshal.SizeOf (typeof (double));
+ return "d";
+ }
+ if (type == typeof (bool)) {
+ size = Marshal.SizeOf (typeof (bool));
+ return "B";
+ }
+ if (type == typeof (string)) {
+ size = Marshal.SizeOf (typeof (IntPtr));
+ return "*";
+ }
+ if (type == typeof (void)) {
+ size = 0;
+ return "v";
+ }
+ size = 4;
+ return "(" + type + ")";
+ }
+
+ public static string GenerateConstructorSignature (ConstructorInfo constructor) {
+ int size = 0;
+ int p = 0;
+ int q = 0;
+ string signature = "";
+
+ foreach (ParameterInfo param in constructor.GetParameters ()) {
+ if (param.ParameterType.IsPrimitive)
+ size += Marshal.SizeOf (param.ParameterType);
+ else
+ size += Marshal.SizeOf (typeof (IntPtr));
+ }
+
+ signature += EncodedType (typeof (IntPtr), out p);
+ signature += size;
+ signature += "@0:4";
+ p = 4;
+
+ foreach (ParameterInfo param in constructor.GetParameters ()) {
+ signature += EncodedType (param.ParameterType, out q);
+ p += q;
+ signature += p;
+ }
+
+ return signature;
+ }
+
+ public static string GenerateMethodSignature (MethodInfo method) {
+ int size = 0;
+ int p = 0;
+ int q = 0;
+ string signature = "";
+
+ foreach (ParameterInfo param in method.GetParameters ()) {
+ if (param.ParameterType.IsPrimitive)
+ size += Marshal.SizeOf (param.ParameterType);
+ else
+ size += Marshal.SizeOf (typeof (IntPtr));
+ }
+
+ signature += EncodedType (method.ReturnType, out p);
+ signature += size;
+ signature += "@0:4";
+ p = 4;
+
+ foreach (ParameterInfo param in method.GetParameters ()) {
+ signature += EncodedType (param.ParameterType, out q);
+ p += q;
+ signature += p;
+ }
+
+ return signature;
+ }
+
+ private static string ConstructorToSelector (ConstructorInfo constructor, Type type) {
+ if (type.IsSubclassOf (typeof (Delegate)))
+ return "initWithTarget:Selector:";
+
+ string selector = "init";
+
+ ParameterInfo [] parameters = constructor.GetParameters ();
+ if (parameters.Length > 0)
+ selector += "With" + parameters [0].ParameterType.ToString ().Substring (parameters [0].ParameterType.ToString ().LastIndexOf (".") > 0 ? parameters [0].ParameterType.ToString ().LastIndexOf (".")+1 : 0) + ":";
+ for (int i = 1; i < parameters.Length; i++)
+ selector += parameters [i].ParameterType.ToString ().Substring (parameters [i].ParameterType.ToString ().LastIndexOf (".") > 0 ? parameters [i].ParameterType.ToString ().LastIndexOf (".")+1 : 0) + ":";
+
+ return selector;
+ }
+
+ private static string SelectorToMethod (string selector, Type type) {
+ string methodname = selector;
+
+ if (methodname.IndexOf ("With") > 0)
+ methodname = methodname.Substring (0, methodname.IndexOf ("With"));
+ if (methodname.IndexOf (":") > 0)
+ methodname = methodname.Substring (0, methodname.IndexOf (":"));
+
+ return methodname;
+ }
+
+ private static string MethodToSelector (MethodInfo method) {
+ string selector = method.Name;
+ ParameterInfo [] parameters = method.GetParameters ();
+ if (parameters.Length > 0)
+ selector += "With" + parameters [0].ParameterType.ToString ().Substring (parameters [0].ParameterType.ToString ().LastIndexOf (".") > 0 ? parameters [0].ParameterType.ToString ().LastIndexOf (".")+1 : 0) + ":";
+ for (int i = 1; i < parameters.Length; i++)
+ selector += parameters [i].ParameterType.ToString ().Substring (parameters [i].ParameterType.ToString ().LastIndexOf (".") > 0 ? parameters [i].ParameterType.ToString ().LastIndexOf (".")+1 : 0) + ":";
+
+ return selector.Replace ("[]", "Array");
+ }
+
+ private static Assembly TypeResolver (object sender, ResolveEventArgs args) {
+ foreach (Assembly assembly in LoadedAssemblies.Values) {
+ if (assembly.GetType (args.Name) != null)
+ return assembly;
+ }
+ if (module_builder.Assembly.GetType (args.Name) != null)
+ return module_builder.Assembly;
+
+ Type nativetype = AddTypeForClass (args.Name);
+ if (nativetype != null) {
+ NativeClasses [objc_getClass (args.Name)] = nativetype;
+ return module_builder.Assembly;
+ }
+
+ return null;
+ }
+
+ private static Type AddTypeForClass (string classname) {
+ if (classname == null)
+ return null;
+ if (module_builder.Assembly.GetType (classname) != null)
+ return module_builder.Assembly.GetType (classname);
+
+ IntPtr cls = objc_getClass (classname);
+
+ if (cls == IntPtr.Zero)
+ return null;
+
+ TypeBuilder type_builder = module_builder.DefineType (classname, TypeAttributes.Public | TypeAttributes.Class);
+ MethodBuilder method_builder;
+ ILGenerator il_generator;
+
+ IntPtr iterator = IntPtr.Zero;
+
+ IntPtr lst = class_nextMethodList (cls, ref iterator);
+
+ FieldBuilder field_builder = type_builder.DefineField ("native_object", typeof (IntPtr), FieldAttributes.Private);
+ PropertyBuilder property_builder = type_builder.DefineProperty ("NativeObject", PropertyAttributes.HasDefault, typeof (IntPtr), new Type [] { typeof (IntPtr) });
+
+ MethodBuilder get_method_builder = type_builder.DefineMethod ("GetNativeObject", MethodAttributes.Public, typeof (IntPtr), new Type[] {});
+ MethodBuilder set_method_builder = type_builder.DefineMethod ("SetNativeObject", MethodAttributes.Public, null, new Type [] { typeof (IntPtr) });
+
+ il_generator = get_method_builder.GetILGenerator ();
+ il_generator.Emit (OpCodes.Ldarg_0);
+ il_generator.Emit (OpCodes.Ldfld, field_builder);
+ il_generator.Emit (OpCodes.Ret);
+
+ il_generator = set_method_builder.GetILGenerator ();
+ il_generator.Emit (OpCodes.Ldarg_0);
+ il_generator.Emit (OpCodes.Ldarg_1);
+ il_generator.Emit (OpCodes.Stfld, field_builder);
+ il_generator.Emit (OpCodes.Ret);
+
+ property_builder.SetGetMethod (get_method_builder);
+ property_builder.SetSetMethod (set_method_builder);
+
+ ConstructorBuilder constructor_builder = type_builder.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, new Type [] { typeof (IntPtr) });
+
+ il_generator = constructor_builder.GetILGenerator ();
+ il_generator.Emit (OpCodes.Ldarg_0);
+ il_generator.Emit (OpCodes.Call, typeof (object).GetConstructor (new Type[0]));
+ il_generator.Emit (OpCodes.Ldarg_0);
+ il_generator.Emit (OpCodes.Ldarg_1);
+ il_generator.Emit (OpCodes.Callvirt, set_method_builder);
+ il_generator.Emit (OpCodes.Ret);
+
+ while (lst != IntPtr.Zero) {
+ int methodcnt = (int)Marshal.ReadIntPtr ((IntPtr)((int)lst+4));
+
+ for (int i = 0; i < methodcnt; i++) {
+ IntPtr methptr = Marshal.ReadIntPtr ((IntPtr)((int)lst+8+(i*Marshal.SizeOf (typeof (IntPtr))*3)));
+ string selector = Marshal.PtrToStringAuto (methptr);
+ IntPtr typestr = Marshal.ReadIntPtr ((IntPtr)((int)lst+12+(i*Marshal.SizeOf (typeof (IntPtr))*3)));
+ Type [] argtypes = ArgumentTypesForCall (class_getInstanceMethod ((IntPtr) ObjCMessaging.objc_msgSend (cls, "class", typeof (IntPtr)), sel_getUid (methptr)));
+ Type returntype = DecodedType (Marshal.PtrToStringAuto (typestr));
+
+ // Fixme; handle retvals and args
+ method_builder = type_builder.DefineMethod (SelectorToMethod (selector, null), MethodAttributes.Public, returntype, argtypes);
+ il_generator = method_builder.GetILGenerator ();
+
+// DEBUG
+ // load self.NativeObject
+ il_generator.Emit (OpCodes.Ldarg_0);
+ il_generator.Emit (OpCodes.Callvirt, get_method_builder);
+
+ // load the selector
+ il_generator.Emit (OpCodes.Ldstr, selector);
+
+ // load the returntype
+ if (returntype.IsPrimitive || returntype.IsValueType) {
+ il_generator.Emit (OpCodes.Ldtoken, returntype);
+ } else {
+ if (returntype == typeof (void))
+ il_generator.Emit (OpCodes.Ldtoken, typeof (void));
+ else
+ il_generator.Emit (OpCodes.Ldtoken, typeof (IntPtr));
+ }
+ il_generator.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
+
+ if (argtypes.Length > 0) {
+ il_generator.Emit (OpCodes.Ldc_I4, argtypes.Length*2);
+ il_generator.Emit (OpCodes.Newarr, typeof (Object));
+ il_generator.Emit (OpCodes.Dup);
+
+ // load the args
+ for (int j = 1; j < argtypes.Length+1; j++) {
+ // get the type
+ il_generator.Emit (OpCodes.Ldc_I4, (j-1)*2);
+ if (argtypes [j-1].IsPrimitive || argtypes [j-1].IsValueType) {
+ if (j < 4) {
+ switch (j) {
+ case 1:
+ il_generator.Emit (OpCodes.Ldarg_1);
+ break;
+ case 2:
+ il_generator.Emit (OpCodes.Ldarg_2);
+ break;
+ case 3:
+ il_generator.Emit (OpCodes.Ldarg_3);
+ break;
+ }
+ } else
+ il_generator.Emit (OpCodes.Ldarg_S, j);
+ il_generator.Emit (OpCodes.Box, argtypes [j-1]);
+ il_generator.Emit (OpCodes.Callvirt, typeof (Object).GetMethod ("GetType"));
+ } else {
+ il_generator.Emit (OpCodes.Ldtoken, typeof (IntPtr));
+ il_generator.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
+ }
+ il_generator.Emit (OpCodes.Stelem_Ref);
+ il_generator.Emit (OpCodes.Dup);
+ // get the type
+ // get the arg
+ il_generator.Emit (OpCodes.Ldc_I4, ((j-1)*2)+1);
+ if (j < 4) {
+ switch (j) {
+ case 1:
+ il_generator.Emit (OpCodes.Ldarg_1);
+ break;
+ case 2:
+ il_generator.Emit (OpCodes.Ldarg_2);
+ break;
+ case 3:
+ il_generator.Emit (OpCodes.Ldarg_3);
+ break;
+ }
+ } else
+ il_generator.Emit (OpCodes.Ldarg_S, j);
+ if (argtypes [j-1].IsPrimitive || argtypes [j-1].IsValueType) {
+ il_generator.Emit (OpCodes.Box, argtypes [j-1]);
+ } else {
+ il_generator.Emit (OpCodes.Call, typeof (Bridge).GetMethod ("ManagedToNative", BindingFlags.Static | BindingFlags.NonPublic));
+ il_generator.Emit (OpCodes.Box, typeof (IntPtr));
+ }
+ il_generator.Emit (OpCodes.Stelem_Ref);
+ if (j < argtypes.Length)
+ il_generator.Emit (OpCodes.Dup);
+ }
+ il_generator.Emit (OpCodes.Call, typeof (ObjCMessaging).GetMethod ("objc_msgSend", new Type [] {typeof (IntPtr), typeof (String), typeof (Type), typeof (object []) }));
+ } else
+ il_generator.Emit (OpCodes.Call, typeof (ObjCMessaging).GetMethod ("objc_msgSend", new Type [] {typeof (IntPtr), typeof (String), typeof (Type) }));
+ if (!returntype.IsPrimitive && !returntype.IsValueType) {
+ il_generator.Emit (OpCodes.Unbox, typeof (IntPtr));
+ il_generator.Emit (OpCodes.Ldind_I);
+ il_generator.Emit (OpCodes.Call, typeof (Bridge).GetMethod ("NativeToManaged", BindingFlags.Static | BindingFlags.NonPublic));
+ } else {
+ if (returntype == typeof (void))
+ il_generator.Emit (OpCodes.Pop);
+ }
+ il_generator.Emit (OpCodes.Ret);
+ }
+ lst = class_nextMethodList (cls, ref iterator);
+ }
+ return type_builder.CreateType ();
+ }
+
+ [DllImport ("libobjc.dylib")]
+ private static extern IntPtr class_nextMethodList (IntPtr cls, ref IntPtr iterator);
+
+/*
+ [DllImport ("libObjCSharp.dylib")]
+ private static extern void dumpMethodList (IntPtr cls);
+
+ [DllImport ("libObjCSharp.dylib")]
+ private static extern void dumpClass (IntPtr cls);
+*/
+
+ [DllImport ("libObjCSharp.dylib")]
+ private static extern void setupDelegate (IMPDelegate d);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern IntPtr objc_lookUpClass (string name);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern IntPtr sel_getUid (IntPtr name);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern IntPtr objc_getClass (string classname);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern void objc_addClass (IntPtr cls);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern void class_addMethods (IntPtr cls, IntPtr methods);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern int method_getNumberOfArguments (IntPtr method);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern int method_getArgumentInfo (IntPtr method, int index, ref IntPtr type, ref int offset);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern IntPtr class_getInstanceMethod (IntPtr cls, IntPtr sel);
+
+ [DllImport ("libobjc.dylib")]
+ private static extern IntPtr class_getClassMethod (IntPtr cls, IntPtr sel);
+ }
+
+ internal struct objc_method {
+ internal string method_name;
+ internal string method_types;
+ internal IntPtr method_imp;
+ }
+}
View
12 objc-sharp/src/objc-sharp/ChangeLog
@@ -0,0 +1,12 @@
+2006-05-30 Geoff Norton <gnorton@customerdna.com>
+
+ * Bridge.cs: Dont box the return values that are already boxed.
+
+2006-05-17 Geoff Norton <gnorton@customerdna.com>
+
+ * Bridge.cs:
+ Mach.cs: Work around a mcs compiler bug (#78422)
+
+2005-10-25 Geoff Norton <gnorton@customerdna.com>
+
+ * Initial import
View
244 objc-sharp/src/objc-sharp/Mach.cs
@@ -0,0 +1,244 @@
+using System;
+using System.Threading;
+using System.Runtime.InteropServices;
+
+namespace ObjCSharp {
+ internal class Mach {
+ internal const int KERN_SUCCESS = 0;
+
+ internal const int MACH_MSG_SUCCESS = 0x00000000;
+
+ internal const int MACH_PORT_NULL = 0;
+ internal const int MACH_PORT_RIGHT_RECEIVE = 1;
+ internal const int MACH_MSG_TYPE_MAKE_SEND = 20;
+
+ internal const int EXC_BAD_ACCESS = 1;
+ internal const int EXC_BAD_INSTRUCTION = 2;
+ internal const int EXC_ARITHMETIC = 3;
+ internal const int EXC_EMULATION = 4;
+ internal const int EXC_SOFTWARE = 5;
+ internal const int EXC_BREAKPOINT = 6;
+ internal const int EXC_SYSCALL = 7;
+ internal const int EXC_MACH_SYSCALL = 8;
+ internal const int EXC_RPC_ALERT = 9;
+
+ internal const int EXC_MASK_MACHINE = 0;
+ internal const int EXC_MASK_BAD_ACCESS = (1 << EXC_BAD_ACCESS);
+ internal const int EXC_MASK_BAD_INSTRUCTION = (1 << EXC_BAD_INSTRUCTION);
+ internal const int EXC_MASK_ARITHMETIC = (1 << EXC_ARITHMETIC);
+ internal const int EXC_MASK_EMULATION = (1 << EXC_EMULATION);
+ internal const int EXC_MASK_SOFTWARE = (1 << EXC_SOFTWARE);
+ internal const int EXC_MASK_BREAKPOINT = (1 << EXC_BREAKPOINT);
+ internal const int EXC_MASK_SYSCALL = (1 << EXC_SYSCALL);
+ internal const int EXC_MASK_MACH_SYSCALL = (1 << EXC_MACH_SYSCALL);
+ internal const int EXC_MASK_RPC_ALERT = (1 << EXC_RPC_ALERT);
+
+ internal const int EXC_MASK_ALL = (EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_EMULATION | EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT | EXC_MASK_SYSCALL | EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT | EXC_MASK_MACHINE);
+
+ internal const int EXCEPTION_DEFAULT = 1;
+
+ internal const int THREAD_STATE_NONE = 7;
+
+ internal const int MACH_SEND_MSG = 0x00000001;
+ internal const int MACH_RCV_MSG = 0x00000002;
+
+ internal const int MSG_SIZE = 512;
+
+ internal static Thread exc_thread;
+ internal static IntPtr exception_port = IntPtr.Zero;
+
+ internal static void InstallExceptionHandler () {
+ if (exception_port != IntPtr.Zero)
+ return;
+
+ Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Installing mach exception handler.", DateTime.Now);
+
+ int rc = 0;
+ exception_port = (IntPtr)MACH_PORT_NULL;
+ IntPtr task = IntPtr.Zero;
+
+ rc = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, ref exception_port);
+
+ if (rc != KERN_SUCCESS)
+ throw new Exception ("mach_port_allocate returned: " + rc);
+
+ rc = mach_port_insert_right (mach_task_self (), exception_port, exception_port, MACH_MSG_TYPE_MAKE_SEND);
+
+ if (rc != KERN_SUCCESS)
+ throw new Exception ("mach_port_insert_right returned: " + rc);
+
+ rc = task_for_pid (mach_task_self (), getpid (), ref task);
+
+ if (rc != KERN_SUCCESS)
+ throw new Exception ("task_for_pid returned: " + rc);
+
+ rc = task_set_exception_ports (task, EXC_MASK_ALL & ~(EXC_MASK_MACH_SYSCALL | EXC_MASK_SYSCALL | EXC_MASK_RPC_ALERT), exception_port, EXCEPTION_DEFAULT, THREAD_STATE_NONE);
+
+ if (rc != KERN_SUCCESS)
+ throw new Exception ("task_set_exception_ports returned: " + rc);
+
+ exc_thread = new Thread (new ThreadStart (ExceptionHandler));
+ exc_thread.Start ();
+ }
+
+ internal static void TestExceptionHandler () {
+ Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Testing mach exception handler.", DateTime.Now);
+ Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Marshal.ReadIntPtr (IntPtr.Zero);", DateTime.Now);
+ try {
+ Marshal.ReadIntPtr (IntPtr.Zero);
+ } catch (NullReferenceException) {
+ Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Generated and caught a NullReferenceException.", DateTime.Now);
+ } catch (Exception e) {
+ Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] ERROR: An exception of type {1} was raised.", DateTime.Now, e.GetType ());
+ throw e;
+ }
+ }
+
+ internal static void RemoveExceptionHandler () {
+ throw new NotImplementedException ();
+
+ /*
+ * This isn't quite right; FIXME
+ if (exception_port == IntPtr.Zero)
+ return;
+
+ Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Removing mach exception handler.", DateTime.Now);
+
+ int rc = 0;
+ IntPtr type = IntPtr.Zero;
+
+ rc = mach_port_extract_right (mach_task_self (), exception_port, MACH_MSG_TYPE_MAKE_SEND, ref exception_port, ref type);
+
+ if (rc != KERN_SUCCESS)
+ throw new Exception ("mach_port_extract_right returned: " + rc);
+
+ exception_port = IntPtr.Zero;
+ exc_thread.Abort ();
+ */
+ }
+
+ internal static void ExceptionHandler () {
+ int r;
+ mach_msg msg;
+ mach_msg reply;
+
+ msg.buffer = IntPtr.Zero;
+ msg.msgh_bits = 0;
+ msg.msgh_size = 0;
+ msg.msgh_remote_port = IntPtr.Zero;
+ msg.msgh_local_port = IntPtr.Zero;
+ msg.msgh_reserved = 0;
+ msg.msgh_id = 0;
+
+ reply.buffer = IntPtr.Zero;
+ reply.msgh_bits = 0;
+ reply.msgh_size = 0;
+ reply.msgh_remote_port = IntPtr.Zero;
+ reply.msgh_local_port = IntPtr.Zero;
+ reply.msgh_reserved = 0;
+ reply.msgh_id = 0;
+
+ while (true) {
+ //Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Waiting for a mach exception.", DateTime.Now);
+ r = mach_msg (ref msg, MACH_RCV_MSG, MSG_SIZE, MSG_SIZE, exception_port, 0, MACH_PORT_NULL);
+
+ if (r != MACH_MSG_SUCCESS)
+ throw new Exception ("mach_msg");
+
+ //Console.WriteLine ("Dumping exception msg:");
+ //dump (msg, msg.msgh_size);
+
+ Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Handling a mach exception.", DateTime.Now);
+
+ reply.msgh_bits = 0x12;
+ reply.msgh_size = 0x24;
+ reply.msgh_remote_port = msg.msgh_remote_port;
+ reply.msgh_local_port = IntPtr.Zero;
+ reply.msgh_reserved = 0;
+ reply.msgh_id = msg.msgh_id+0x64;
+ unsafe {
+ int *ptr = (int *)(((int) &reply.msgh_id)+(Marshal.SizeOf (typeof (int))*3));
+ *(ptr) = 0x5;
+ }
+
+ //Console.WriteLine ("Dumping exception reply:");
+ //dump (reply, reply.msgh_size);
+
+ //Console.WriteLine ("[{0:yyyy-mm-dd hh:MM:ss}] Replying from a mach exception.", DateTime.Now);
+ r = mach_msg (ref reply, MACH_SEND_MSG, reply.msgh_size, 0, msg.msgh_local_port, 0, MACH_PORT_NULL);
+
+ if (r != MACH_MSG_SUCCESS)
+ throw new Exception ("mach_msg reply");
+ }
+ }
+
+ internal static void dump (mach_msg msg, uint size) {
+ unsafe {
+ int ctr = 0;
+ int ln = 0;
+ void *msgptr = &msg;
+ for (int i = 0; i < size; i++) {
+ if (ln == 0 && ctr == 0)
+ Console.Write ("\t0x{0:x} ", ((int)msgptr)+i);
+ byte b = Marshal.ReadByte ((IntPtr)((int)msgptr+i));
+ Console.Write ("{0:x2}", b);
+ ++ctr;
+ if (ctr == 4) {
+ Console.Write (" ");
+ ctr = 0;
+ ln++;
+ }
+ if (ln == 4) {
+ Console.WriteLine ();
+ ln = 0;
+ }
+ }
+ for (int i = 0; i < (4-ln); i++)
+ Console.Write ("00000000 ");
+ Console.WriteLine ();
+ }
+ }
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static int mach_msg (ref mach_msg msg, uint message_type, uint snd_size, int rcv_size, IntPtr exception_port, int unknown, int mach_port);
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static int task_set_exception_ports (IntPtr mach_task_t, int exception_mask, IntPtr exception_port, int exception_state, int thread_state);
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static int mach_port_extract_right (IntPtr mach_task_t, IntPtr a_exception_port, uint mach_msg_type, ref IntPtr b_exception_port, ref IntPtr type);
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static int mach_port_insert_right (IntPtr mach_task_t, IntPtr a_exception_port, IntPtr b_exception_port, uint mach_msg_type);
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static int mach_port_allocate (IntPtr mach_task_t, uint mach_port_right_t, ref IntPtr exception_port);
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static int task_for_pid (IntPtr mach_task_t, uint pid, ref IntPtr task);
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static IntPtr mach_task_self ();
+
+ [DllImport ("/usr/lib/libc.dylib")]
+ internal extern static uint getpid ();
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ internal struct mach_msg {
+ [FieldOffset (0)]
+ internal uint msgh_bits;
+ [FieldOffset (4)]
+ internal uint msgh_size;
+ [FieldOffset (8)]
+ internal IntPtr msgh_remote_port;
+ [FieldOffset (12)]
+ internal IntPtr msgh_local_port;
+ [FieldOffset (16)]
+ internal uint msgh_reserved;
+ [FieldOffset (20)]
+ internal int msgh_id;
+ [FieldOffset (508)]
+ internal IntPtr buffer;
+ }
+}
View
23 objc-sharp/src/objc-sharp/Makefile.am
@@ -0,0 +1,23 @@
+ASSEMBLY_NAME=objc-sharp
+ASSEMBLY=$(ASSEMBLY_NAME).dll
+TARGET=$(ASSEMBLY)
+noinst_DATA=$(ASSEMBLY) objc-sharp.snk
+
+CLEANFILES=$(ASSEMBLY) AssemblyInfo.cs
+
+sources = \
+ Bridge.cs \
+ NativeRepresentation.cs \
+ VarargStack.cs \
+ Mach.cs \
+ NativeMember.cs \
+ ObjCMessaging.cs
+
+EXTRA_DIST=$(sources) \
+ AssemblyInfo.cs \
+ objc-sharp.snk
+
+build_sources = $(addprefix $(srcdir)/, $(sources))
+
+$(ASSEMBLY): $(build_sources)
+ $(MCS) /unsafe /out:$(ASSEMBLY) /target:library $(build_sources)
View
30 objc-sharp/src/objc-sharp/NativeMember.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace ObjCSharp {
+ internal class NativeMember {
+ private string name;
+ private string type;
+ private int size;
+
+ public NativeMember (string name, string type, int size) {
+ this.name = name;
+ this.type = type;
+ this.size = size;
+ }
+
+ public string Name {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+
+ public string Type {
+ get { return this.type; }
+ set { this.type = value; }
+ }
+
+ public int Size {
+ get { return this.size; }
+ set { this.size = value; }
+ }
+ }
+}
View
48 objc-sharp/src/objc-sharp/NativeRepresentation.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace ObjCSharp {
+ internal class NativeRepresentation {
+ private string[] constructors;
+ private string[] constructor_signatures;
+ private string[] methods;
+ private string[] signatures;
+ private string[] staticmethods;
+ private string[] staticsignatures;
+ private NativeMember[] members;
+
+ public string[] Constructors {
+ get { return this.constructors; }
+ set { this.constructors = value; }
+ }
+
+ public string[] ConstructorSignatures {
+ get { return this.constructor_signatures; }
+ set { this.constructor_signatures = value; }
+ }
+
+ public string[] StaticMethods {
+ get { return this.staticmethods; }
+ set { this.staticmethods = value; }
+ }
+
+ public string[] StaticSignatures {
+ get { return this.staticsignatures; }
+ set { this.staticsignatures = value; }
+ }
+
+ public string[] Methods {
+ get { return this.methods; }
+ set { this.methods = value; }
+ }
+
+ public string[] Signatures {
+ get { return this.signatures; }
+ set { this.signatures = value; }
+ }
+
+ public NativeMember[] Members {
+ get { return this.members; }
+ set { this.members = value; }
+ }
+ }
+}
View
210 objc-sharp/src/objc-sharp/ObjCMessaging.cs
@@ -0,0 +1,210 @@
+using System;
+using System.Text;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+
+namespace ObjCSharp {
+ public class ObjCMessaging {
+ [DllImport("libobjc.dylib")]
+ public static extern IntPtr sel_registerName(string selectorName);
+
+ static AssemblyBuilder builder = null;
+ static AssemblyBuilder superbuilder = null;
+ static AssemblyName an = null;
+ static AssemblyName superan = null;
+ static ModuleBuilder module = null;
+ static ModuleBuilder supermodule = null;
+ static Hashtable types = new Hashtable();
+ static Hashtable supertypes = new Hashtable();
+ static void GenerateAssembly(string type, bool super) {
+ string[] argstypes = type.Split('_');
+
+ if (an == null) {
+ an = new AssemblyName();
+ an.Name = "Apple.ObjCMessaging";
+ }
+ if (superan == null) {
+ superan = new AssemblyName();
+ superan.Name = "Apple.ObjCMessagingSuper";
+ }
+ if (builder == null)
+ builder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
+ if (superbuilder == null)
+ superbuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(superan, AssemblyBuilderAccess.Run);
+ if (module == null)
+ module = builder.DefineDynamicModule(an.Name);
+ if (supermodule == null)
+ supermodule = superbuilder.DefineDynamicModule(superan.Name);
+
+ ModuleBuilder modbuilder = (super ? supermodule : module);
+ TypeBuilder tb = modbuilder.DefineType(type, TypeAttributes.Public);
+ Type rettype = System.Type.GetType(argstypes[0]);
+ if (rettype.IsValueType && rettype.Namespace != "System") {
+ Type[] args = new Type[argstypes.Length];
+ args[0] = System.Type.GetType ("System.IntPtr");
+ for (int i = 0; i < argstypes.Length-1; ++i)
+ args[i+1] = System.Type.GetType (argstypes[i+1]);
+
+ tb.DefinePInvokeMethod("objc_msgSend" + (super ? "Super" : "") + "_stret", "libobjc.dylib", MethodAttributes.PinvokeImpl|MethodAttributes.Static|MethodAttributes.Public, CallingConventions.Standard, null, args, CallingConvention.Winapi, CharSet.Auto);
+ } else {
+ Type[] args = new Type[argstypes.Length-1];
+ for (int i = 0; i < argstypes.Length-1; ++i)
+ args[i] = System.Type.GetType (argstypes[i+1]);
+ tb.DefinePInvokeMethod("objc_msgSend" + (super ? "Super" : ""), "libobjc.dylib", MethodAttributes.PinvokeImpl|MethodAttributes.Static|MethodAttributes.Public, CallingConventions.Standard, rettype, args, CallingConvention.Winapi, CharSet.Auto);
+ }
+ tb.CreateType();
+ if (super)
+ supertypes.Add(type, 1);
+ else
+ types.Add(type, 1);
+ }
+ static Assembly TypeResolve(string type, bool super)
+ {
+ if (super) {
+ if (supertypes[type] == null)
+ GenerateAssembly(type, super);
+ return supermodule.Assembly;
+ }
+ if (types[type] == null)
+ GenerateAssembly(type, super);
+ return module.Assembly;
+ }
+
+ public static object objc_msgSend (IntPtr receiver, string selector, Type rettype) {
+ Type marshalrettype = rettype;
+ if (rettype == typeof (string))
+ marshalrettype = typeof (System.IntPtr);
+
+ string type = marshalrettype.ToString() + "_System.IntPtr_System.IntPtr";
+ Type t = TypeResolve(type, false).GetType(type);
+ object ret;
+ if (rettype.IsValueType && rettype.Namespace != "System") {
+ IntPtr ptr = Marshal.AllocHGlobal (Marshal.SizeOf (rettype));
+ object[] realArgs = new object[3];
+ realArgs[0] = ptr;
+ realArgs[1] = receiver;
+ realArgs[2] = sel_registerName(selector);
+
+ t.InvokeMember("objc_msgSend_stret", BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.Static, null, null, realArgs);
+ ret = Marshal.PtrToStructure (ptr, rettype);
+ Marshal.FreeHGlobal (ptr);
+ } else {
+ object[] realArgs = new object[2];
+ realArgs[0] = receiver;
+ realArgs[1] = sel_registerName(selector);
+ ret = t.InvokeMember("objc_msgSend", BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.Static, null, null, realArgs);
+ }
+ if (rettype == typeof(string))
+ ret = Marshal.PtrToStringAuto ((IntPtr)ret);
+ return ret;
+
+ }
+ public static object objc_msgSend (IntPtr receiver, string selector, Type rettype, params object[] args) {
+ Type marshalrettype = rettype;
+ if (rettype == typeof (string))
+ marshalrettype = typeof (System.IntPtr);
+
+ StringBuilder type = new StringBuilder();
+ type.AppendFormat("{0}_System.IntPtr_System.IntPtr", marshalrettype);
+ for (int i = 0; i < args.Length; i+=2) {
+ type.AppendFormat("_{0}", args[i]);
+ }
+ Type t = TypeResolve(type.ToString(), false).GetType(type.ToString());
+
+ object o = Activator.CreateInstance(t);
+ object ret;
+ if (rettype.IsValueType && rettype.Namespace != "System") {
+ IntPtr ptr = Marshal.AllocHGlobal (Marshal.SizeOf (rettype));
+ object[] realArgs = new object[(args.Length/2)+3];
+ realArgs[0] = ptr;
+ realArgs[1] = receiver;
+ realArgs[2] = sel_registerName(selector);
+ for (int i = 0, j = 3; i < args.Length; i+=2, j++) {
+ if (args[i+1].GetType ().IsEnum)
+ realArgs[j] = Convert.ChangeType (args[i+1], Enum.GetUnderlyingType (args[i+1].GetType ()));
+ else
+ realArgs[j] = args[i+1];
+ }
+
+ t.InvokeMember("objc_msgSend_stret", BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.Static, null, o, realArgs);
+ ret = Marshal.PtrToStructure (ptr, rettype);
+ Marshal.FreeHGlobal (ptr);
+ } else {
+ object[] realArgs = new object[(args.Length/2)+2];
+ realArgs[0] = receiver;
+ realArgs[1] = sel_registerName(selector);
+ for (int i = 0, j = 2; i < args.Length; i+=2, j++) {
+ if (args[i+1].GetType ().IsEnum)
+ realArgs[j] = Convert.ChangeType (args[i+1], Enum.GetUnderlyingType (args[i+1].GetType ()));
+ else
+ realArgs[j] = args[i+1];
+ }
+ ret = t.InvokeMember("objc_msgSend", BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.Static, null, o, realArgs);
+ }
+ if (rettype == typeof(string))
+ ret = Marshal.PtrToStringAuto ((IntPtr)ret);
+ return ret;
+ }
+
+ public static object objc_msgSendSuper (IntPtr receiver, string selector, Type rettype, params object[] args) {
+ Type marshalrettype = rettype;
+ if (rettype == typeof (string))
+ marshalrettype = typeof (System.IntPtr);
+
+ StringBuilder type = new StringBuilder();
+ type.AppendFormat("{0}_System.IntPtr_System.IntPtr", marshalrettype);
+ for (int i = 0; i < args.Length; i+=2) {
+ type.AppendFormat("_{0}", args[i]);
+ }
+ Type t = TypeResolve(type.ToString(), true).GetType(type.ToString());
+
+ objc_super target;
+ target.receiver = receiver;
+ target.superclass = (IntPtr) objc_msgSend (receiver, "superclass", typeof (IntPtr));
+ IntPtr supertarget = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (objc_super)));
+ Marshal.StructureToPtr (target, supertarget, true);
+
+ object o = Activator.CreateInstance(t);
+ object ret;
+ if (rettype.IsValueType && rettype.Namespace != "System") {
+ IntPtr ptr = Marshal.AllocHGlobal (Marshal.SizeOf (rettype));
+ object[] realArgs = new object[(args.Length/2)+3];
+ realArgs[0] = ptr;
+ realArgs[1] = supertarget;
+ realArgs[2] = sel_registerName(selector);
+ for (int i = 0, j = 3; i < args.Length; i+=2, j++) {
+ if (args[i+1].GetType ().IsEnum)
+ realArgs[j] = Convert.ChangeType (args[i+1], Enum.GetUnderlyingType (args[i+1].GetType ()));
+ else
+ realArgs[j] = args[i+1];
+ }
+
+ t.InvokeMember("objc_msgSendSuper_stret", BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.Static, null, o, realArgs);
+ ret = Marshal.PtrToStructure (ptr, rettype);
+ Marshal.FreeHGlobal (ptr);
+ } else {
+ object[] realArgs = new object[(args.Length/2)+2];
+ realArgs[0] = supertarget;
+ realArgs[1] = sel_registerName(selector);
+ for (int i = 0, j = 2; i < args.Length; i+=2, j++) {
+ if (args[i+1].GetType ().IsEnum)
+ realArgs[j] = Convert.ChangeType (args[i+1], Enum.GetUnderlyingType (args[i+1].GetType ()));
+ else
+ realArgs[j] = args[i+1];
+ }
+ ret = t.InvokeMember("objc_msgSendSuper", BindingFlags.InvokeMethod|BindingFlags.Public|BindingFlags.Static, null, o, realArgs);
+ }
+ Marshal.FreeHGlobal (supertarget);
+ if (rettype == typeof(string))
+ ret = Marshal.PtrToStringAuto ((IntPtr)ret);
+ return ret;
+ }
+ }
+
+ internal struct objc_super {
+ internal IntPtr receiver;
+ internal IntPtr superclass;
+ }
+}
View
10 objc-sharp/src/objc-sharp/VarargStack.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace ObjCSharp {
+ [StructLayout (LayoutKind.Explicit)]
+ public struct VarargStack {
+ [FieldOffset (252)]
+ public IntPtr stack;
+ }
+}
View
BIN objc-sharp/src/objc-sharp/objc-sharp.snk
Binary file not shown.
View
3 objc-sharp/test/ChangeLog
@@ -0,0 +1,3 @@
+2005-10-25 Geoff Norton <gnorton@customerdna.com>
+
+ * Initial import
View
49 objc-sharp/test/Makefile.am
@@ -0,0 +1,49 @@
+SUBDIRS=testlibrary
+
+DEPS=$(top_builddir)/src/bridge/libObjCSharp.la
+LDADDS=$(top_builddir)/src/bridge/libObjCSharp.la
+
+noinst_PROGRAMS= \
+ events \
+ exceptionhandling \
+ instancemethods \
+ marshalling \
+ staticmethods
+
+EXTRA_DIST= \
+ $(events_SOURCES) \
+ $(exceptionhandling_SOURCES) \
+ $(instancemethods_SOURCES) \
+ $(marshalling_SOURCES) \
+ $(staticmethods_SOURCES)
+
+OBJCFLAGS=$(MONO_LIBS) $(MONO_CFLAGS) -I$(top_srcdir)/src/bridge -Wl,-framework -Wl,Foundation -fobjc-exceptions
+
+events_DEPENDENCIES=$(DEPS)
+events_LDADD=$(LDADDS)
+events_SOURCES=events.m
+
+exceptionhandling_DEPENDENCIES=$(DEPS)
+exceptionhandling_LDADD=$(LDADDS)
+exceptionhandling_SOURCES=exceptionhandling.m
+
+instancemethods_DEPENDENCIES=$(DEPS)
+instancemethods_LDADD=$(LDADDS)
+instancemethods_SOURCES=instancemethods.m
+
+marshalling_DEPENDENCIES=$(DEPS)
+marshalling_LDADD=$(LDADDS)
+marshalling_SOURCES=marshalling.m
+
+staticmethods_DEPENDENCIES=$(DEPS)
+staticmethods_LDADD=$(LDADDS)
+staticmethods_SOURCES=staticmethods.m
+
+test:
+ cp ../src/objc-sharp/objc-sharp.dll .
+ cp ./testlibrary/test-library.dll .
+ ./events
+ ./exceptionhandling
+ ./marshalling
+ ./staticmethods
+ ./instancemethods
View
84 objc-sharp/test/events.m
@@ -0,0 +1,84 @@
+#import <ObjCSharpBridge.h>
+#import <Foundation/Foundation.h>
+
+@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];
+
+ @try {
+ // 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 0;
+ } @catch (NSException *ex) {
+ NSLog (@"Unhandled exception: %s", [[ex name] cString]);
+ NSLog (@"%s", [[ex reason] cString]);
+ return 1;
+ }
+}
View
21 objc-sharp/test/exceptionhandling.m
@@ -0,0 +1,21 @@
+#import <ObjCSharpBridge.h>
+#import <Foundation/Foundation.h>
+
+int main (void) {
+ [[NSAutoreleasePool alloc] init];
+
+ @try {
+ id bridge = [ObjCSharpBridge alloc];
+ [bridge init];
+
+ [bridge loadAssembly: "test-library.dll"];
+
+ Class ExceptionTests = [bridge getClass: "TestLibrary.ExceptionTests"];
+
+ [ExceptionTests ThrowException];
+
+ return 1;
+ } @catch (NSException *e) {
+ return 0;
+ }
+}
View
47 objc-sharp/test/instancemethods.m
@@ -0,0 +1,47 @@
+#import <ObjCSharpBridge.h>
+#import <Foundation/Foundation.h>
+
+int main (void) {
+ [[NSAutoreleasePool alloc] init];
+
+ @try {
+ id bridge = [ObjCSharpBridge alloc];
+ [bridge init];
+
+ [bridge loadAssembly: "test-library.dll"];
+
+ Class InstanceTests = [bridge getClass: "TestLibrary.InstanceTests"];
+ Class Console = [bridge getClass: "System.Console"];
+
+ // Create an couple instances instance
+ id a = [InstanceTests init];
+ id b = [InstanceTests initWithInt32:-2 Single:-2.0f];
+
+ if (*(int *)[a ReturnIntValue] != *(int *)[a get_IntValue])
+ return 2;
+
+ if (*(float *)[a ReturnFloatValue] != *(float *)[a get_FloatValue])
+ return 3;
+
+ if (*(bool *)[a CompareToWithInstanceTests:b] != FALSE)
+ return 4;
+
+ if (*(int *)[b ReturnIntValue] != -2)
+ return 5;
+
+ if (*(float *)[b ReturnFloatValue] != -2.0f)
+ return 6;
+
+ [a set_IntValueWithInt32: -2];
+ [a set_FloatValueWithSingle: -2.0f];
+
+ if (*(bool *)[a CompareToWithInstanceTests:b] != TRUE)
+ return 7;
+
+ return 0;
+ } @catch (NSException *e) {
+ NSLog (@"Unhandled Exception: %s", [[e name] cString]);
+ NSLog (@"%s\n", [[e reason] cString]);
+ return 1;
+ }
+}
View
45 objc-sharp/test/marshalling.m
@@ -0,0 +1,45 @@
+#import <ObjCSharpBridge.h>
+#import <Foundation/Foundation.h>
+
+@implementation NativeClass : NSObject
+int myint;
+
+- (void) setInteger: (int) toset
+{
+ myint = toset;
+}
+
+- (bool) compareInteger: (int) tocompare
+{
+ return (tocompare == myint);
+}
+
+@end
+
+int main (void) {
+ // Make Apple shut up
+ [[NSAutoreleasePool alloc] init];
+
+ @try {
+ // Get the bridge and initialize it
+ id bridge = [[ObjCSharpBridge alloc] init];
+
+ [bridge loadAssembly: "test-library.dll"];
+
+ id native = [[NativeClass alloc] init];
+ [native setInteger:-1];
+
+ Class NativeMarshalTests = [bridge getClass: "TestLibrary.NativeMarshalTests"];
+
+ id tester = [NativeMarshalTests init];
+
+ if ([tester InvokeCompareWithInt32:-1 Object:native] == FALSE)
+ return 2;
+
+ return 0;
+ } @catch (NSException *ex) {
+ NSLog (@"Unhandled exception: %s", [[ex name] cString]);
+ NSLog (@"%s", [[ex reason] cString]);
+ return 1;
+ }
+}
View
36 objc-sharp/test/staticmethods.m
@@ -0,0 +1,36 @@
+#import <ObjCSharpBridge.h>
+#import <Foundation/Foundation.h>
+
+int main (void) {
+ [[NSAutoreleasePool alloc] init];
+
+ @try {
+ id bridge = [ObjCSharpBridge alloc];
+ [bridge init];
+
+ [bridge loadAssembly: "test-library.dll"];
+
+ Class TestClass = [bridge getClass: "TestLibrary.StaticTests"];
+ Class Console = [bridge getClass: "System.Console"];
+
+ // Call a static class method
+ [TestClass StaticMethod];
+
+ // Call a static bound method
+ [Console WriteLineWithString:"Console.WriteLine (\"Hello World\")"];
+
+ if (*(int *)[TestClass ReturnInt32] != -1) {
+ return 2;
+ }
+
+ if (*(float *)[TestClass ReturnFloat] != -1.0f) {
+ return 3;
+ }
+
+ return 0;
+ } @catch (NSException *e) {
+ NSLog (@"Unhandled Exception: %s", [[e name] cString]);
+ NSLog (@"%s", [[e reason] cString]);
+ return 1;
+ }
+}
View
3 objc-sharp/test/testlibrary/ChangeLog
@@ -0,0 +1,3 @@
+2005-10-25 Geoff Norton <gnorton@customerdna.com>
+
+ * Initial import
View
11 objc-sharp/test/testlibrary/ExceptionTests.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Reflection;
+
+namespace TestLibrary {
+ public class ExceptionTests {
+
+ public static void ThrowException () {
+ throw new Exception ("Handled exception");
+ }
+ }
+}
View
59 objc-sharp/test/testlibrary/InstanceTests.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Reflection;
+
+namespace TestLibrary {
+ public class InstanceTests {
+ private int intvalue;
+ private float floatvalue;
+