James
James

Reputation: 41

Calling Obj-C From MonoTouch Using Selectors

Well I'm completely stumped - I cannot cal from Mono into Obj-C code using Selectors either. So as a last ditch attempt I'm posting the code:

@implementation MonoWrapper
- (id)init {
self = [super init];

if (self) {
    NSBundle *main = [NSBundle mainBundle];
    NSString *path = [main bundlePath];
    const char *c_path = [path UTF8String];

    [main autorelease]; 
    [path autorelease];

    chdir (c_path);
    setenv ("MONO_PATH", c_path, 1);
    setenv ("MONO_XMLSERIALIZER_THS", "no", 1);
    setenv ("DYLD_BIND_AT_LAUNCH", "1", 1);
    setenv ("MONO_REFLECTION_SERIALIZER", "yes", 1);

    _domain = mono_jit_init_version ("MonoTouch", "v2.0.50727");
    MonoAssembly *assembly = mono_assembly_open("PhoneGap.dll", NULL);
    MonoImage *image = mono_assembly_get_image(assembly);
    MonoClass *class = mono_class_from_name(image, "PhoneGap", "PhoneGap");
    MonoMethodDesc *methodDesc = mono_method_desc_new("PhoneGap.PhoneGap:getInt", TRUE);
    _callbackMethod = mono_method_desc_search_in_class(methodDesc, class);

    /* allocate memory for the object */
    _instance = mono_object_new (_domain, class);
    /* execute the default argument-less constructor */
    mono_runtime_object_init (_instance);   

}
// Done
return self;
}

- (void)DoSomething {
int jim = 0;
} 

- (int)multiplyA:(int)a {
void *params[] = { self, @selector(DoSomething), &a };
MonoObject *result = mono_runtime_invoke(_callbackMethod, _instance, params, NULL);
int n = *(int*)mono_object_unbox (result);
return n;
}
@end

And in MonoTouch:

using System;
using MonoTouch.ObjCRuntime;  

namespace PhoneGap
{
public class PhoneGap
{
    public PhoneGap ()
    {
    }

    public int getInt(IntPtr instance, IntPtr sel, int val) {


        Messaging.void_objc_msgSend (instance, sel);
        return val * 2;
    }
}
}

Can anyone tell me how to get the Target instance handle in Mono and how to get the Selector?

Thanks

James

Upvotes: 3

Views: 742

Answers (1)

Mikayla Hutchinson
Mikayla Hutchinson

Reputation: 16153

The target/instance IntPtr is a pointer to the native instance. You would get this when you alloc the class.

For class/static method, the target/instance IntPtr is the native class descriptor. You can get this by creating a MonoMac.ObjcRuntime.Class and using its Handle property to get the native class descriptor.

The selector IntPtr is a pointer to a selector. You can get this by creating a MonoMac.ObjcRuntime.Selector and using its Handle property to get the native selector.

When creating a wrapper class for an NSObject, you would need to subclass NSObject and use the MonoMac.Foundation.Register attribute to set its Objc-C name. Then, when you new up the wrapper, it would alloc and init the underlying native instance and you'd be able to get that from the NSObject's Handle property. This also means that you can "unwrap" pointers to NSObjects to get the 1:1 managed wrapper using MonoMac.ObjcRuntime.Runtime.GetNSObject (IntPtr ptr).

In general, you're probably better off using the btouch tools to generate the binding for you.

Upvotes: 1

Related Questions