MonoTouch: talking from Obj-C to MonoTouch

2019-02-27 19:51发布

问题:

I'm trying to call into a MonoTouch assembly from an existing Objective C project. I found this article:

http://www.guidebee.biz/forum/redirect.php?fid=16&tid=176&goto=nextoldset

In there it pretty much describes the steps very well however when I try to build the project in XCode I get the following error:

error: There is no SDK with specified name or path '/Developer/MonoTouch/SDKs/MonoTouch.iphonesimulator.sdk'

So, to be clear:

  1. I have the correct path added the Architectures Additional SDKs
  2. Physically checked the path is correct
  3. I am building against the latest SDK (that I have anyway) which is iOS 4.2

I am stumped. Is this a problem with XCode not finding the correct path to the SDK or something deeper? Worryingly I noticed that the URL referenced in the article ( http://monotouch.net/Documentation/XCode ) is now missing - so has Novell MonoTouch deliberately removed this for some reason?

Update:

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 Mono:

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?

回答1:

MonoTouch historically included support before we had our own debugger. We have since deprecated this support as we now have a fully fledged debugger. What you are trying to do, while technically possible is not a supported workflow. If you wish to continue down this path, I suggest using the "-keeptemp" flag to MonoTouch combined with "-v -v -v" which will not delete the temporary files we generate when compiling the project.

Using this information you can extract the main.m template, and could theoretically figure out how to invoke arm-darwin-mono to cross compile yourself.