[Mono-osx] Invoke CIL/Managed Code from ObjC/XCode on Mac

Kevin Heeney koheeney at gmail.com
Tue Oct 28 23:51:58 EDT 2008


Thank you very much.  Between your post (Duane) and the post from  
Andreas (and the embed mono page at <http://www.mono-project.com/ 
Embedding_Mono>),  I have been able to successfully call my C#  
methods from ObjC in XCode as well as get return values from  
functions and values from public variables.  Now I am in the process  
of writing a couple of Objective-C wrapper classes to invoke methods  
in my C# classes.


Since I am doing my front end using Objective-C and my model in C#, I  
was going to write an Objective-C Wrapper generator in C# that would,  
via reflection, analyze my .NET classes and generate Objective-C code  
that I could use as wrappers to invoke those classes.  Atleast a  
simple version that would support primitive types.  Before I started  
on this, I wanted to see if anyone knows of something like this that  
has been done.  I have found plenty of ways to call Cocoa from C#,  
but I don't think I am aware of anything to go the other way.

Thanks again.
Kevin




On Oct 25, 2008, at 8:22 AM, Duane Wandless wrote:

> I will share what works for me.  First I use monobjc.  Great  
> documentation.  Easy to use.  Well supported.   I am using the  
> latest mono install 2.0, though this worked with 1.9 as well.  And  
> I use Xcode 3.1.  I place my mono EXE in build/Debug/MyCocoa.app/ 
> Content/Libraries, along with the Monobjc DLLs.  As you will see in  
> the code (main.m) below, I load the EXE relative to the app bundle  
> location.
>
> For me anyway I hit a bug in 2.0 that required me to load an EXE  
> rather than a DLL.  In some ways the EXE is better.  I have a  
> Program.cs (see below) that initializes the MonoObjc environment.   
> It is important to load the MonoObjc environment prior to Cocoa  
> setting up the IB references.  This way when the NIB file is loaded  
> it will find your [ObjectiveCClass] references, see MainForm.cs  
> below, which is snippets only.
>
> In my NIB file I have an object that has its class MonoMessage.  I  
> hookup the array, tree, outline view, fields, etc to this object.   
> At runtime they are hooked up to my mono class.  I have some objC  
> code (MainDocument.m below) that sends messages to my mono class.   
> And my mono class sends messages back to the objC world.
>
> We wanted the best of both worlds.  The power of C# and the ability  
> to reuse the code on Mac and Windows.  But we also wanted the  
> native build environment for the Leopard frontend.  So not only was  
> using IB a requirement but so was writing the UI code in objC.   
> Thanks to mono and monobjc we accomplished this with a very clean  
> environment.
>
> You can also take the mono EXE and fully embed it within the cocoa  
> app.  This way the end user is not required to install mono.  But  
> that is a topic for a different thread.
>
> Other C Flags = -D_THREAD_SAFE -D_REENTRANT -I/Library/Frameworks/ 
> Mono.framework/Versions/2.0/include/mono-1.0 -I/Library/Frameworks/ 
> Mono.framework/Versions/2.0/include/glib-2.0 -I/Library/Frameworks/ 
> Mono.framework/Versions/2.0/lib/glib-2.0/include
> Other C++ Flags = $(OTHER_CFLAGS)
> OTHER_LDFLAGS = -pthread -L/Library/Frameworks/Mono.framework/ 
> Versions/Current/lib -lmono -lpthread -lm -lgthread-2.0 -lglib-2.0 - 
> lintl -rpath at loader_path/../Libraries
>
>
> main.m:
> #import <Cocoa/Cocoa.h>
> #include <mono/jit/jit.h>
> #include <mono/metadata/assembly.h>
> #include <mono/metadata/mono-config.h>
>
> int main(int argc, char *argv[])
> {
>     NSAutoreleasePool *pool;
>     pool = [[NSAutoreleasePool alloc] init];
>
>     MonoDomain *domain;
>     NSString *libraryPath = [[[NSBundle mainBundle] bundlePath]  
> stringByAppendingPathComponent:@"Contents/Libraries"];
>     NSString *sampleAssemblyPath = [libraryPath  
> stringByAppendingPathComponent:@"MacMonoClient.exe"];
>     NSLog(@"libraryPath: %@", sampleAssemblyPath);
>     mono_config_parse ("config");
>     domain = mono_jit_init ([sampleAssemblyPath UTF8String]);
>     MonoAssembly *monoAssembly = mono_domain_assembly_open(domain,  
> [sampleAssemblyPath UTF8String]);
>     mono_jit_exec (domain, monoAssembly, 1, argv);
>     NSLog(@"sample assembly: %p", monoAssembly);
>     [pool release];
>
>     return NSApplicationMain(argc, (const char **) argv);
> }
>
> Program.cs:
> using System;
> using Monobjc;
> using Monobjc.Cocoa;
>
> namespace MacClient
> {
>     static class Program
>     {
>        public static void Main()
>        {
>             ObjectiveCRuntime.LoadFramework("Cocoa");
>             ObjectiveCRuntime.LoadFramework("QTKit");
>             ObjectiveCRuntime.Initialize();
>        }
>     }
> }
>
> MainForm.cs:
> using System;
> using Monobjc;
> using Monobjc.Cocoa;
> using Monobjc.QuickTime;
>
> namespace MacClient
> {
>     [ObjectiveCClass("MonoMessage")]
>     public class MyControl : NSObject
>     {
>         private static readonly Class ControllerClass =  
> Class.GetClassFromType(typeof(MyControl));
>
>         public MyControl() { }
>         public MyControl(IntPtr np) : base(np) { }
>
>         NSAutoreleasePool pool = new NSAutoreleasePool();
>         ~MyControl()
>         {
>             pool.Drain();
>         }
>
>         [ObjectiveCField]
>         public NSArrayController projectsController;
>         [ObjectiveCField("itemsController")]
>         public NSTreeController folderContent;
>         [ObjectiveCField]
>         public NSOutlineView folderOutline;
>
>         [ObjectiveCMessage("init")]
>         public override Id Init()
>         {
>             ObjectiveCRuntime.SendMessageSuper<IntPtr>(this,  
> ControllerClass, "init");
>              
> NSNotificationCenter.DefaultCenter.AddObserverSelectorNameObject 
> (this, ObjectiveCRuntime.Selector("doAuth:"), "doAuth", null);
>                  }
>         [ObjectiveCMessage("awakeFromNib")]
>         public void awakeFromNib()
>         {
>         }
>         [ObjectiveCMessage("doAuth:")]
>         public void SelectionChanged(NSNotification notification)
>         {
>             NSArray loginParms = notification.UserInfo.ObjectForKey 
> (new NSString("params")).CastTo<NSArray>();
>             Login(loginParms[0].CastTo<NSString>(), loginParms 
> [1].CastTo<NSString>());
>         }
>     }
> }
>
> MainDocument.m
> - (IBAction)login:(id)sender
> {
>     NSLog(@"Starting login process...");
>
>     NSString *username = [usernameTextField stringValue];
>     NSString *password = [passwordTextField stringValue];
>
>     NSArray *loginParams = [NSArray arrayWithObjects:username,  
> password, nil];
>     NSDictionary* dict =  [NSDictionary  
> dictionaryWithObject:loginParams forKey:@"params"];
>     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
>     [nc postNotificationName:@"doAuth" object:nil userInfo:dict];
> }
>
> On Fri, Oct 24, 2008 at 10:13 PM, Kevin Heeney <koheeney at gmail.com>  
> wrote:
>    I think I have hit a wall.  I am fairly new to mono on mac;  
> however am familiar with .NET and Objc/Cocoa.  I am unable to  
> successfully 'embed mono' or call methods from my Mono dll in  
> ObjC.  I have created a UI using Interface Builder and have my App  
> Controller in ObjC ready to call my C# dll which contains my  
> logic.  Cocoa# and ObjCSharp both claim to be 2 way bridges;  
> however I can only find code for calling Cocoa from C# and not the  
> other way around.  In addition, I cannot get the samples from  
> <http://www.mono-project.com/Embedding_Mono> on Embedding Mono to  
> work in XCode.  My actual issue with the latter is I cannot get  
> XCode to link to the mono framework.  I am getting errors like  
> "main.c:1: error: mono/jit/jit.h: No such file or directory".
>    I am not sure what I am missing; it may be simple.
>
> Any guidance would be appreciated.
> Thanks,
> Kevin
>
> _______________________________________________
> Mono-osx mailing list
> Mono-osx at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-osx
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-osx/attachments/20081028/9c2cafbd/attachment.html 


More information about the Mono-osx mailing list