<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments for Thoughts from Mirality</title>
	<atom:link href="http://lambert.geek.nz/comments/feed/" rel="self" type="application/rss+xml" />
	<link>http://lambert.geek.nz</link>
	<description>Random thoughts and musings from Miral at Mirality Systems.</description>
	<lastBuildDate>Sun, 25 Mar 2012 02:41:54 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>Comment on AppDomains and unmanaged callbacks, redux by Miral</title>
		<link>http://lambert.geek.nz/2011/12/19/appdomains-and-unmanaged-callbacks-redux/comment-page-1/#comment-16521</link>
		<dc:creator>Miral</dc:creator>
		<pubDate>Sun, 25 Mar 2012 02:41:54 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=118#comment-16521</guid>
		<description>Ok, but that&#039;s even easier.  Simply declare an EventArgs derivative that includes a String member, with a corresponding event inside the Logger class, and then raise that event directly from the Log method.  Then, somewhere up in your C# code, instantiate a Logger and subscribe to its event.</description>
		<content:encoded><![CDATA[<p>Ok, but that&#8217;s even easier.  Simply declare an EventArgs derivative that includes a String member, with a corresponding event inside the Logger class, and then raise that event directly from the Log method.  Then, somewhere up in your C# code, instantiate a Logger and subscribe to its event.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on AppDomains and unmanaged callbacks, redux by tonsten</title>
		<link>http://lambert.geek.nz/2011/12/19/appdomains-and-unmanaged-callbacks-redux/comment-page-1/#comment-16501</link>
		<dc:creator>tonsten</dc:creator>
		<pubDate>Sat, 24 Mar 2012 17:11:08 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=118#comment-16501</guid>
		<description>I think I need to register event in C# side and then somehow get the Logger class (in your code) to provide me the log whenever native C++ callback triggers the log.</description>
		<content:encoded><![CDATA[<p>I think I need to register event in C# side and then somehow get the Logger class (in your code) to provide me the log whenever native C++ callback triggers the log.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on AppDomains and unmanaged callbacks, redux by Miral</title>
		<link>http://lambert.geek.nz/2011/12/19/appdomains-and-unmanaged-callbacks-redux/comment-page-1/#comment-16489</link>
		<dc:creator>Miral</dc:creator>
		<pubDate>Sat, 24 Mar 2012 14:23:43 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=118#comment-16489</guid>
		<description>If I&#039;m understanding your situation properly, you don&#039;t need to go to all that complicated a structure.  Just use the same Logger code I had above (no wrapper), but make the Log method pure virtual.  Then in the C# code, create a class derived from Logger which implements Log to call your C#-layer logging functions.

Or, if you can move the C#-layer logging functions into a DLL that can be referenced by the C++/CLI code, just call it directly from the Logger class as above, in place of the call to &lt;tt&gt;Console::WriteLine&lt;/tt&gt;.

Yet another option (though it seems needlessly complicated to me) would be to define an interface class with a &lt;tt&gt;Log&lt;/tt&gt; method, pass that to the constructor of Logger (saving it in a field), and call that from within &lt;tt&gt;Logger::Log&lt;/tt&gt;.</description>
		<content:encoded><![CDATA[<p>If I&#8217;m understanding your situation properly, you don&#8217;t need to go to all that complicated a structure.  Just use the same Logger code I had above (no wrapper), but make the Log method pure virtual.  Then in the C# code, create a class derived from Logger which implements Log to call your C#-layer logging functions.</p>
<p>Or, if you can move the C#-layer logging functions into a DLL that can be referenced by the C++/CLI code, just call it directly from the Logger class as above, in place of the call to <tt>Console::WriteLine</tt>.</p>
<p>Yet another option (though it seems needlessly complicated to me) would be to define an interface class with a <tt>Log</tt> method, pass that to the constructor of Logger (saving it in a field), and call that from within <tt>Logger::Log</tt>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on AppDomains and unmanaged callbacks, redux by tonsten</title>
		<link>http://lambert.geek.nz/2011/12/19/appdomains-and-unmanaged-callbacks-redux/comment-page-1/#comment-16487</link>
		<dc:creator>tonsten</dc:creator>
		<pubDate>Sat, 24 Mar 2012 13:29:17 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=118#comment-16487</guid>
		<description>Thank you for quick answer. I try to clarify better:

I have C# project which uses unmanaged/native C++ project. I have wrapped these managed C# and unmanaged C++ stuff using C++/CLI. That unmanaged dll will send logs asynchronously during procedure and those logs need to be catch on C# side where the &quot;real&quot; logging is.

So first I need to set callback interface &lt;code&gt;RegisterLogger(ILogger *logger)&lt;/code&gt; (C# -&gt; C++/CLI -&gt; Unmanaged C++).
Then by using this callback unmanaged C++ will report these logs to upper level (unmanaged C++ -&gt; C++/CLI -&gt; C#). I have already managed to implement this &quot;calling chain&quot; (thanks to you) like this C# -&gt; C++/CLI -&gt; unmanaged C++ -&gt; C++/CLI. So only last step is missing.

&lt;code&gt;ILoggerWrapper&lt;/code&gt; is created because that C++/CLI wrapper should provide pure .NET interface to C#.

In C# side it might look something like this:
&lt;code&gt;
 public class LoggerAdaptation : ILoggerWrapper
    {
        private ILoggerWrapper loggerWrapper;

        public void SomeMethod()
        {
            Logger logger = new Logger();
            logger.SetLogger(this.loggerWrapper);
        }

        public void LogWrap(String message)
        {
            // ...
        }

        public event EventHandler Log;

        public void OnLog(LogEventArgs e)
        {
            EventHandler handler = this.Log;
            if (handler != null)
            {
                handler(this, e);
            }
        }
    }
&lt;/code&gt;

Was that any better explanation, do you see my problem?</description>
		<content:encoded><![CDATA[<p>Thank you for quick answer. I try to clarify better:</p>
<p>I have C# project which uses unmanaged/native C++ project. I have wrapped these managed C# and unmanaged C++ stuff using C++/CLI. That unmanaged dll will send logs asynchronously during procedure and those logs need to be catch on C# side where the &#8220;real&#8221; logging is.</p>
<p>So first I need to set callback interface <code>RegisterLogger(ILogger *logger)</code> (C# -&gt; C++/CLI -&gt; Unmanaged C++).<br />
Then by using this callback unmanaged C++ will report these logs to upper level (unmanaged C++ -&gt; C++/CLI -&gt; C#). I have already managed to implement this &#8220;calling chain&#8221; (thanks to you) like this C# -&gt; C++/CLI -&gt; unmanaged C++ -&gt; C++/CLI. So only last step is missing.</p>
<p><code>ILoggerWrapper</code> is created because that C++/CLI wrapper should provide pure .NET interface to C#.</p>
<p>In C# side it might look something like this:<br />
<code><br />
 public class LoggerAdaptation : ILoggerWrapper<br />
    {<br />
        private ILoggerWrapper loggerWrapper;</p>
<p>        public void SomeMethod()<br />
        {<br />
            Logger logger = new Logger();<br />
            logger.SetLogger(this.loggerWrapper);<br />
        }</p>
<p>        public void LogWrap(String message)<br />
        {<br />
            // ...<br />
        }</p>
<p>        public event EventHandler Log;</p>
<p>        public void OnLog(LogEventArgs e)<br />
        {<br />
            EventHandler handler = this.Log;<br />
            if (handler != null)<br />
            {<br />
                handler(this, e);<br />
            }<br />
        }<br />
    }<br />
</code></p>
<p>Was that any better explanation, do you see my problem?</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on AppDomains and unmanaged callbacks, redux by Miral</title>
		<link>http://lambert.geek.nz/2011/12/19/appdomains-and-unmanaged-callbacks-redux/comment-page-1/#comment-16484</link>
		<dc:creator>Miral</dc:creator>
		<pubDate>Sat, 24 Mar 2012 12:26:33 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=118#comment-16484</guid>
		<description>I&#039;m not really clear on what &lt;tt&gt;ILoggerWrapper&lt;/tt&gt; is intended for, or what the problem you&#039;re having is.

The point of the code in the example is to allow some existing native code to call up to your &quot;real&quot; logger in the managed code.  If you have other C# code that wants to log something, just call your logger directly -- you don&#039;t need any of this.</description>
		<content:encoded><![CDATA[<p>I&#8217;m not really clear on what <tt>ILoggerWrapper</tt> is intended for, or what the problem you&#8217;re having is.</p>
<p>The point of the code in the example is to allow some existing native code to call up to your &#8220;real&#8221; logger in the managed code.  If you have other C# code that wants to log something, just call your logger directly &#8212; you don&#8217;t need any of this.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on AppDomains and unmanaged callbacks, redux by tonsten</title>
		<link>http://lambert.geek.nz/2011/12/19/appdomains-and-unmanaged-callbacks-redux/comment-page-1/#comment-16480</link>
		<dc:creator>tonsten</dc:creator>
		<pubDate>Sat, 24 Mar 2012 12:17:59 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=118#comment-16480</guid>
		<description>Since I&#039;m using this solution from C# I need to wrap native ILogger class to be able to use it from C#.
&lt;code&gt;
public interface class ILoggerWrapper
{
public:
   void LogWrap(String message) = 0;
}; 
&lt;/code&gt;

Then this wrapped interface needs to be inherited:
&lt;code&gt;
public ref class Logger : ILoggerWrapper
{
public:
    Logger()
    {
        m_Logger = new NativeLogger(gcnew LogDelegate(this, &amp;Logger::Log));
        NativeFramework::RegisterLogger(m_Logger);
    }
    ~Logger()
    {
        this-&gt;!Logger();
    }
    !Logger()
    {
        delete m_Logger;
        m_Logger = NULL;
    }
 
    void Log(String^ message)
    {
        Console::WriteLine(message);
    }
 
private:
    void Log(const std::string&amp; message)
    {
        Log(marshal_as(message));
    }
 
private:
    NativeLogger *m_Logger;
};
&lt;/code&gt;

But now I&#039;m a bit lost since I provide LogWrap function for C# user but native callback calls Log function. How I can handle this in above code?</description>
		<content:encoded><![CDATA[<p>Since I&#8217;m using this solution from C# I need to wrap native ILogger class to be able to use it from C#.<br />
<code><br />
public interface class ILoggerWrapper<br />
{<br />
public:<br />
   void LogWrap(String message) = 0;<br />
};<br />
</code></p>
<p>Then this wrapped interface needs to be inherited:<br />
<code><br />
public ref class Logger : ILoggerWrapper<br />
{<br />
public:<br />
    Logger()<br />
    {<br />
        m_Logger = new NativeLogger(gcnew LogDelegate(this, &amp;Logger::Log));<br />
        NativeFramework::RegisterLogger(m_Logger);<br />
    }<br />
    ~Logger()<br />
    {<br />
        this-&gt;!Logger();<br />
    }<br />
    !Logger()<br />
    {<br />
        delete m_Logger;<br />
        m_Logger = NULL;<br />
    }</p>
<p>    void Log(String^ message)<br />
    {<br />
        Console::WriteLine(message);<br />
    }</p>
<p>private:<br />
    void Log(const std::string&amp; message)<br />
    {<br />
        Log(marshal_as(message));<br />
    }</p>
<p>private:<br />
    NativeLogger *m_Logger;<br />
};<br />
</code></p>
<p>But now I&#8217;m a bit lost since I provide LogWrap function for C# user but native callback calls Log function. How I can handle this in above code?</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on AppDomains and unmanaged callbacks, redux by tonsten</title>
		<link>http://lambert.geek.nz/2011/12/19/appdomains-and-unmanaged-callbacks-redux/comment-page-1/#comment-16477</link>
		<dc:creator>tonsten</dc:creator>
		<pubDate>Sat, 24 Mar 2012 11:46:33 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=118#comment-16477</guid>
		<description>Hi and thank you for great and clarifying examples. Those really helped me, especially example &#039;Longer-term class-based callbacks&#039;.
I use almost the same solution in my project but I need to get those logs also to my upper layer since I&#039;m using your solution from C#. I wonder how to implement this in C# side to be able to catch those logs from native callback?</description>
		<content:encoded><![CDATA[<p>Hi and thank you for great and clarifying examples. Those really helped me, especially example &#8216;Longer-term class-based callbacks&#8217;.<br />
I use almost the same solution in my project but I need to get those logs also to my upper layer since I&#8217;m using your solution from C#. I wonder how to implement this in C# side to be able to catch those logs from native callback?</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Multithreaded Collections and WPF by WPF, ObservableCollections, and Multi-threading&#8230;what are my options?</title>
		<link>http://lambert.geek.nz/2007/10/30/wpf-multithreaded-collections/comment-page-1/#comment-14877</link>
		<dc:creator>WPF, ObservableCollections, and Multi-threading&#8230;what are my options?</dc:creator>
		<pubDate>Thu, 23 Feb 2012 16:09:30 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/2007/10/30/wpf-multithreaded-collections/#comment-14877</guid>
		<description>[...] support updating the OC on a secondary thread. I found a number of posts on the topic, like this one from Mirality, and I will be looking into those [...]</description>
		<content:encoded><![CDATA[<p>[...] support updating the OC on a secondary thread. I found a number of posts on the topic, like this one from Mirality, and I will be looking into those [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Summer of Gaming by Gaming Update: Dec 2011 &#171; Thoughts from Mirality</title>
		<link>http://lambert.geek.nz/2008/01/11/gaming-summer/comment-page-1/#comment-11826</link>
		<dc:creator>Gaming Update: Dec 2011 &#171; Thoughts from Mirality</dc:creator>
		<pubDate>Tue, 20 Dec 2011 23:27:11 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/2008/01/11/gaming-summer/#comment-11826</guid>
		<description>[...] Alice, a decade-old darker reimagining of the characters from Alice in Wonderland (which I&#8217;ve discussed before). This game continues on the same theme, this time with a slightly older Alice, now outside of the [...]</description>
		<content:encoded><![CDATA[<p>[...] Alice, a decade-old darker reimagining of the characters from Alice in Wonderland (which I&#8217;ve discussed before). This game continues on the same theme, this time with a slightly older Alice, now outside of the [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on 111111111111 by Miral</title>
		<link>http://lambert.geek.nz/2011/11/11/111111/comment-page-1/#comment-11763</link>
		<dc:creator>Miral</dc:creator>
		<pubDate>Mon, 19 Dec 2011 09:09:10 +0000</pubDate>
		<guid isPermaLink="false">http://lambert.geek.nz/?p=197#comment-11763</guid>
		<description>Indeed :P</description>
		<content:encoded><![CDATA[<p>Indeed <img src='http://lambert.geek.nz/wpdata/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
</channel>
</rss>

