<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>House of Metnetsky &#187; embed</title>
	<atom:link href="http://cowarthill.com/blog/index.php/tag/embed/feed/" rel="self" type="application/rss+xml" />
	<link>http://cowarthill.com/blog</link>
	<description>Run Tortoise Run</description>
	<lastBuildDate>Fri, 26 Feb 2010 17:15:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Mono Embedded &#8211; Your Own .NET Plugin</title>
		<link>http://cowarthill.com/blog/index.php/2009/08/27/mono-embedded-one/</link>
		<comments>http://cowarthill.com/blog/index.php/2009/08/27/mono-embedded-one/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 19:25:38 +0000</pubDate>
		<dc:creator>MET</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[mono]]></category>

		<guid isPermaLink="false">http://cowarthill.com/blog/?p=284</guid>
		<description><![CDATA[I&#8217;ve embedded either for fun or work a number of languages to see what hosting them in C is like &#8211; both for performance and ease of marshalling. So far I&#8217;m impressed with the internals of Mono, but feel like there&#8217;s a lack of proper GOTCHA&#8217;s documented anywhere. Some are spread out around the web, [...]]]></description>
			<content:encoded><![CDATA[<div>I&#8217;ve embedded either for fun or work a number of languages to see what hosting them in C is like &#8211; both for performance and ease of marshalling. So far I&#8217;m impressed with the internals of Mono, but feel like there&#8217;s a lack of proper GOTCHA&#8217;s documented anywhere. Some are spread out around the web, but most don&#8217;t directly state key points. As such, I&#8217;m going to be posted a few as I come across them.</p>
<p>WARNING: Some of this may not make complete sense without reading <a href="http://www.mono-project.com/Embedding_Mono" target="_blank">http://www.mono-project.com/Embedding_Mono</a> first.</p>
<p><strong>Creating Objects</strong><br />
Like the above docs day, all you really need to do is:</p>
<pre class="brush: cpp;">
/* get handle for class from assembly */
MonoImage *image = mono_assembly_get_image(MonoAssembly*);
MonoClass *klass = mono_class_from_name(image, &quot;Namespace&quot;, &quot;Class&quot;);

/* instantiate class and call .ctor (as they're nothing more than methods) */
MonoObject *obj = mono_object_new(MonoDomain*, klass);
mono_runtime_init(obj); /* call .ctor w/out args */
</pre>
<p><strong>Reusing Objects</strong><br />
If you need to reuse this new MonoObject instance EVER I would highly suggest calling <strong>mono_gchandle_new(MonoObject*, pinned)</strong> otherwise the GC will get to it before you want it again &#8211; I GUARANTEE THIS. The reason this happens is because objects created from your C code have no real &#8220;SCOPE&#8221;, so they&#8217;re collected quickly just like they were local variables in a method. Read the following link, it&#8217;s helpful:</p>
<p><a href="http://www.go-mono.org/docs/index.aspx?link=xhtml%3Adeploy%2Fmono-api-gchandle.html" target="_blank">http://www.go-mono.org/docs/index.aspx?link=xhtml%3Adeploy%2Fmono-api-gchandle.html</a></p>
<p>As a side note, you can actually call methods on objects that have been collected as long as the methods usage of `this` is only limited to `this.GetType()` (or nearly static). Try it, you&#8217;ll get some really funny results!</p>
<p><strong>Finding Methods</strong><br />
The MonoClass* struct contains (or points to) lots of lists of data. The methods of a class are essentially one big long list and each method (every single variation) is a different instance of MonoMethod*. Take a look at the following C# class:</p>
<pre class="brush: csharp;">
namespace Test
{
	public class Foo
	{
		public Foo()
		{
		}

		public void Log(int num)
		{
		}

		public void Log(string msg)
		{
		}
	}
}
</pre>
<p>NOTICE: The Log method is overloaded!</p>
<p>One way to call Foo.Log(?) is like so:</p>
<pre class="brush: cpp;">
/* get handle for class from assembly */
MonoImage *image = mono_assembly_get_image(MonoAssembly*);
MonoClass *klass = mono_class_from_name(image, &quot;Namespace&quot;, &quot;Class&quot;);

/* instantiate class and call .ctor (as they're nothing more than methods) */
MonoObject *obj = mono_object_new(MonoDomain*, klass);
mono_runtime_init(obj); /* call .ctor w/out args */

/* Get Log method from MonoClass that takes 1 argument
MonoMethod *m = mono_class_get_method_from_name(klass, &quot;Log&quot;, 1);

/* create single argument */
void *args[1] = { mono_string_new(MonoDomain*, &quot;Hello World&quot;); };

/* last argument is to capture exceptions */
mono_runtime_invoke(m, obj, args, NULL);
</pre>
<p>Any guess what might have just happened? Well, we just passed a string to the Log(int) method because <strong>mono_class_get_method_from_name</strong> returns the first one it finds, and not the one based on the type. To fix this you could write your own method which loops through MonoMethod*&#8217;s and find the correct signature or use the helper methods:</p>
<pre class="brush: cpp;">
#include &lt;mono/metadata/debug-helpers.h&gt;

MonoMethodDesc *d = mono_method_desc_new(&quot;:Log(int)&quot;, FALSE);
MonoMethod *m = mono_method_desc_search_in_class(d, klass);
mono_method_desc_free(d);
</pre>
<p>The <strong>mono_method_desc_*</strong> functions are extremely helpful and remove some of the crazy and changing internals &#8211; so I&#8217;d suggest using them for much of your calls.</p>
<p>Here are some further examples of the string descriptor for mono_method_desc_new:</p>
<ul>
<li>Namespace.Test:Log(string) -&gt; find Log method in Test class (requires second argument to be TRUE)</li>
<li>:Log(string) -&gt; find Log method which takes a string</li>
<li>:Log(XmlReader) -&gt; find Log method which takes an XmlReader</li>
<li>:Log(My.Namespace.XmlReader) -&gt; find the method which takes YOUR funky XmlReader</li>
</ul>
<p>As you can see it covers the gamut &#8211; so thank you to whomever created that extremely useful class/struct/function-set.</p>
</div>
<div>~ Till next time!</div>
]]></content:encoded>
			<wfw:commentRss>http://cowarthill.com/blog/index.php/2009/08/27/mono-embedded-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
