So you want to embed a mono app within an existing obj-c app.  I have posted about this before but thought it was a good time to repost.  Here are the steps I do to make this work using Mono 2.6.1 and 2.6.4.  Or at least the steps I am remembering now.  You can use the MonoDevelop soft debugger against the C# code.  This is of course very useful.  But that is a topic for a different day.<div>
<br></div><div>In your main.m add this line:</div><div><br></div><div>InitMono(argc, (char**)argv);</div><div><br></div><div>Create a new library project in xcode.  Change the project settings like this:</div><div><div>OTHER_LDFLAGS = -pthread -L/Library/Frameworks/Mono.framework/Versions/Current/lib -lmono -lpthread -lm -lgthread-2.0 -lglib-2.0 -lintl -rpath@loader_path/../Libraries</div>
</div><div><div>LIBRARY_SEARCH_PATHS = Mono</div></div><div><div>OTHER_CFLAGS = -D_XOPEN_SOURCE -DPLATFORM_MACOSX -DUSE_MMAP -DUSE_MUNMAP -DGC_MACOSX_THREADS -DGetCurrentProcess=MonoGetCurrentProcess -DCreateEvent=MonoCreateEvent -DGetCurrentThread=MonoGetCurrentThread -I/Library/Frameworks/Mono.framework/Versions/Current/lib/glib-2.0/include -I/Library/Frameworks/Mono.framework/Versions/Current/include/glib-2.0 -D_THREAD_SAFE -D_REENTRANT -I/Library/Frameworks/Mono.framework/Headers/mono-1.0</div>
</div><div><div>LD_DYLIB_INSTALL_NAME = @loader_path/../Libraries/InitMono.dylib</div></div><div><br></div><div>Add a .m file to the project, initmono.m.</div><div><br></div><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">#import &lt;Cocoa/Cocoa.h&gt;</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">#include &lt;mono/jit/jit.h&gt;</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">#include &lt;mono/metadata/assembly.h&gt;</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">#include &lt;mono/metadata/mono-config.h&gt;</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">#include &lt;mono/metadata/mono-debug.h&gt;</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">#include &lt;mono/utils/mono-logger.h&gt;</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">extern void mono_mkbundle_init();</font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">void InitMono(int argc, char *argv[])</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">{</font></div></div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">MonoDomain *domain;</font></div>
</div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">NSString *libraryPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@&quot;Contents/Libraries/&quot;];</font></div>
</div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">NSString *sampleAssemblyPath = [libraryPath stringByAppendingPathComponent:@&quot;MacMonoClient.exe&quot;];</font></div>
</div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        // Create a DLL mapping file</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        // I do this at runtime in case the user relocates the app so that mono can still find the dylib</font></div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">NSString* monoconfig = @&quot;&lt;configuration&gt;&lt;dllmap dll=\&quot;mobjc-glue.dylib\&quot; target=\&quot;&quot;;</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">monoconfig = [</font><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">monoconfig stringByAppendingString:[libraryPath stringByAppendingPathComponent:@&quot;a.dylib&quot;]];</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">monoconfig = [</font><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">monoconfig stringByAppendingString:@&quot;\&quot; /&gt;&lt;/configuration&gt;&quot;];</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">[</font><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">monoconfig writeToFile:[libraryPath stringByAppendingPathComponent:@&quot;monoconfig2&quot;] atomically:YES encoding:NSASCIIStringEncoding error:NULL];</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">NSString* configFile = [libraryPath stringByAppendingPathComponent:@&quot;monoconfig2&quot;];</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">mono_config_parse ([configFile UTF8String]);</font></div>
</div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">const gchar *pix_debug;</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">pix_debug = g_getenv (&quot;EMBEDDED_MONO_DEBUG&quot;);</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">if (pix_debug != NULL) {</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">mono_debug_init (MONO_DEBUG_FORMAT_MONO);</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">}</font></div>
</div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">const gchar *mono_trace_level;</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">mono_trace_level = g_getenv (&quot;EMBEDDED_MONO_TRACE_LEVEL&quot;);</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">if (mono_trace_level != NULL)</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">mono_trace_set_level_string(mono_trace_level);</font></div>
</div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        // this is currently needed because in 2.6.1 fully embedding mono is not working</font></div>
<div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">NSString *mPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@&quot;Contents/Libraries/lib&quot;];</font></div>
</div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">mono_assembly_setrootdir([mPath UTF8String]);</font></div>
</div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">domain = mono_jit_init ([sampleAssemblyPath UTF8String]);</font></div>
<div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">MonoAssembly *monoAssembly = mono_domain_assembly_open(domain, [sampleAssemblyPath UTF8String]);</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace"><br></font></div><div><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        </font></span><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">mono_jit_exec (domain, monoAssembly, 1, argv);</font></div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">}</font></div></div><div><br></div><div>Add InitMono.dylib to your existing xcode project.</div><div><br></div><div>Compile your C# code as an EXE, the name must match what is in initmono.m.  At one point there were issues using a DLL, those may have been fixed but I have not checked.  But using an EXE is better in my opinion.  If you are using mobjc/mcocoa or monobjc you need to initialize the bindings.  The C# main is the perfect place to do that.</div>
<div><br></div><div>Now if you are not fully embedding mono, meaning you are requiring your users to install mono then you do not need these next steps.  These next steps fully embed mono so that you only ship what you need.  My total app is around 25 MB.  Now your set of DLLs and mono dylibs may be different depending on what your app uses.  I use mkbundle to figure what to include.</div>
<div><br></div><div>Again I have not checked recently, but there were issues just using the result of mkbundle.  But in theory instead of creating the directory structure (see below) you can compile into InitMono.dylib the result of mkbundle -o host.c.  And not need to add all of the lib*.dylibs, dlls, etc.  That is a topic for a different day.  </div>
<div><br></div><div>Now in your app you will need to have this directory structure:</div><div>Contents\Libraries</div><div>   InitMono.dylib</div><div>   MacMonoClient.exe</div><div>   MacMonoClient.exe.mdb</div><div>   a.dylib</div>
<div>   &lt; any other DLLs your EXE needs &gt;</div><div>   monoconfig2</div><meta charset="utf-8"><meta charset="utf-8"><meta charset="utf-8"><meta charset="utf-8"><div>   libmono.0.dylib</div><div>   libglib-2.0.0.dylib</div>
<div>   libintl.8.0.2.dylib</div><div>   libgthread-2.0.0.dylib</div><meta charset="utf-8"><meta charset="utf-8"><div>   System.Configuration.dll<span class="Apple-tab-span" style="white-space:pre">        </span></div><meta charset="utf-8"><div>
<span class="Apple-tab-span" style="white-space:pre"></span>   System.dll<span class="Apple-tab-span" style="white-space:pre">                        </span><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre"></span>   System.Core.dll<span class="Apple-tab-span" style="white-space:pre">                        </span><span class="Apple-tab-span" style="white-space:pre">        </span></div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>   System.Drawing.dll<span class="Apple-tab-span" style="white-space:pre">                </span><span class="Apple-tab-span" style="white-space:pre">                </span>  <span class="Apple-tab-span" style="white-space:pre">                </span></div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>   System.Drawing.dll.config<span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre"></span>   Mono.Security.dll<span class="Apple-tab-span" style="white-space: pre; ">                </span></div>
<meta charset="utf-8"><div><span class="Apple-tab-span" style="white-space: pre; "></span>   System.Xml.Linq.dll<span class="Apple-tab-span" style="white-space: pre; ">                </span></div><div><span class="Apple-tab-span" style="white-space: pre; "></span></div>
<div>   System.Xml.dll<span class="Apple-tab-span" style="white-space:pre">        </span></div><div>   Mono.Posix.dll<span class="Apple-tab-span" style="white-space:pre">                </span>&lt; needed for 2.6.4 &gt;</div><div><span class="Apple-tab-span" style="white-space:pre"></span>   System.Security.dll<span class="Apple-tab-span" style="white-space:pre">                </span>&lt; needed for 2.6.4 &gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre"></span>  </div><div>Contents\Libraries\lib\mono\2.0\</div><div>   mscorlib.dll                     &lt; see mono_assembly_setrootdir &gt;</div><div><br></div><div>
<br></div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"></span>Now do not think it is just that easy.  All of the mono lib*.dylibs have to be otool-ed.  As does InitMono.dylib.  So </div><div>I have a script in the InitMono xcode project that does this:</div>
<div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libmono.0.dylib @loader_path/../Libraries/libmono.0.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.dylib</div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libgthread-2.0.0.dylib @loader_path/../Libraries/libgthread-2.0.0.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.dylib</div>
<div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libglib-2.0.0.dylib @loader_path/../Libraries/libglib-2.0.0.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.dylib</div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libintl.8.0.2.dylib @loader_path/../Libraries/libintl.8.0.2.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.dylib</div>
</div><div><br></div><div>And then for all of the lib*.dylibs you need to run these commands:</div><div><div>install_name_tool -id @loader_path/../Libraries/libmono.0.dylib libmono.0.dylib</div><div>install_name_tool -id @loader_path/../Libraries/libgthread-2.0.0.dylib libgthread-2.0.0.dylib</div>
<div>install_name_tool -id @loader_path/../Libraries/libglib-2.0.0.dylib libglib-2.0.0.dylib</div><div>install_name_tool -id @loader_path/../Libraries/libintl.8.0.2.dylib libintl.8.0.2.dylib</div><div><br></div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libmono.0.dylib @loader_path/../Libraries/libmono.0.dylib libintl.8.0.2.dylib</div>
<div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libmono.0.dylib @loader_path/../Libraries/libmono.0.dylib libgthread-2.0.0.dylib</div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libmono.0.dylib @loader_path/../Libraries/libmono.0.dylib libglib-2.0.0.dylib</div>
<div><br></div><div><br></div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libintl.8.0.2.dylib @loader_path/../Libraries/libintl.8.0.2.dylib libmono.0.dylib</div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libintl.8.0.2.dylib @loader_path/../Libraries/libintl.8.0.2.dylib  libgthread-2.0.0.dylib</div>
<div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libintl.8.0.2.dylib @loader_path/../Libraries/libintl.8.0.2.dylib libglib-2.0.0.dylib</div><div><br></div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libgthread-2.0.0.dylib @loader_path/../Libraries/libgthread-2.0.0.dylib libmono.0.dylib</div>
<div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libgthread-2.0.0.dylib @loader_path/../Libraries/libgthread-2.0.0.dylib  libintl.8.0.2.dylib</div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libgthread-2.0.0.dylib @loader_path/../Libraries/libgthread-2.0.0.dylib libglib-2.0.0.dylib</div>
<div><br></div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libglib-2.0.0.dylib @loader_path/../Libraries/libglib-2.0.0.dylib libmono.0.dylib</div><div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libglib-2.0.0.dylib @loader_path/../Libraries/libglib-2.0.0.dylib  libintl.8.0.2.dylib</div>
<div>install_name_tool -change /Library/Frameworks/Mono.framework/Versions/2.6.4/lib/libglib-2.0.0.dylib @loader_path/../Libraries/libglib-2.0.0.dylib libgthread-2.0.0.dylib</div></div><div><br></div><div>Hopefully I have not forgotten anything.  Best of luck.</div>
<div>Duane</div><div><br></div><div><br></div><div><br></div>