<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Marcus' Blog</title>
    <link>http://www.heege.net/blog/</link>
    <description>Random thoughts about C++/CLI, .NET/Native interop and other topics</description>
    <copyright>Marcus Heege</copyright>
    <lastBuildDate>Thu, 15 Oct 2009 20:40:45 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.7.5016.2</generator>
    <managingEditor>marcus@heege.net</managingEditor>
    <webMaster>marcus@heege.net</webMaster>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,ae4f5285-9d04-4999-9765-1d7fcf6b2da2.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,ae4f5285-9d04-4999-9765-1d7fcf6b2da2.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In the last post, I have covered an aspect of sandboxing – unexpected AppDomain switches
      caused by thread promotion. In this post, I will focus on sandboxing, too. However,
      this time the primary focus is not security but performance. Nevertheless, at the
      end of this post, I will present an idea that might cause you less pain if you think
      about the thread-promotion issue.
   </p>
        <p>
      So what are the performance issues of executing plug-ins in sandboxed AppDomains?
      Creating and managing AppDomains internally is by far not the most expensive part
      here. Typically, calls across application domains have much more impact on performance.
      There are different options for calling across application domains:
   </p>
        <ul>
          <li>
         AppDomain.DoCallback</li>
          <li>
         Calling objects in other application domains via transparent proxies</li>
          <li>
         ICLRRuntimeHost::ExecuteInAppDomain (a COM-based API internally used by msclr/appdomain.h
         and its various call_in_appdomain templates)</li>
        </ul>
        <p>
      Compared to calls inside an appdomain, all of these options are dark slow. Even if
      you use an optimization described <a href="http://www.codeproject.com/KB/dotnet/FastAppDomainMarshal.aspx">here</a>,
      there is a significant cost involved in cross AppDomain calls. For scenarios that
      require a lot of calls between the host application and the plug-in and vice versa,
      this is often not acceptable.
   </p>
        <p>
      A customer of mine recently came up with a simple but very interesting idea that I
      have not considered so far: Why should the plug-in be executed in a different AppDomain?
      Can’t we create a sandboxed AppDomain in which only our assemblies and system assemblies
      have full-trust permissions whereas the plug-ins can only use a restricted permission-set?
   </p>
        <p>
      Like most interesting questions, this question is not easy to answer. I do not claim
      that I have the ultimate answer to this question, but I want to explain my opinion
      here. At the end of the day it comes down to the question what are the real benefits
      an AppDomain can give you? In a later post, I will likely address AppDomains in more
      detail. For now it is sufficient to know that AppDomains can provide isolation; they
      are boundaries especially for
   </p>
        <ul>
          <li>
         assembly and type loading (and unloading)</li>
          <li>
         configuration</li>
          <li>
         CAS security assignments</li>
        </ul>
        <p>
      The first use-case for AppDoamins was ASP.NET. I think it is in fact fair to say,
      that many features of AppDomains only exist because the ASP.NET team needed them.
      However, this does not mean that these features are needed in all plug-in scenarios.
      Let’s take a look at each item mentioned above:
   </p>
        <p>
          <i>Assembly and type loading (and unloading)</i>: If you need hot-pluggable plug-ins
      (those that can be plugged in and out at runtime) you have to use AppDomains. AppDomains
      offer shadow copying of loaded assemblies which allows you to overwrite the assembly
      while it is loaded and, as explained <a href="http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx">here</a>,
      shutting down AppDomains is the only way to unload assemblies. However, for many pluggable
      applications, it is acceptable that a restart of the application is required to replace
      a plug-in.
   </p>
        <p>
          <i>Configuration</i>: While it can be convenient if each plug-in can have its own
      configuration file, it is seldom a strict requirement. For many applications, it is
      acceptable if the app and the plug-ins have to share a configuration file. In my experience,
      a plug-in typically receives its configuration as creation-parameters from the host
      application and not via configuration files.
   </p>
        <p>
          <i>CAS permission assignments</i>: For this aspect the answer is not that easy. Is
      it more secure if a plug-in is executed in a separate sandboxed application domain?
      Isn’t it sufficient if the host and the plug-in are executed in a sandboxed application
      domain in which the host’s code has full-trust permissions and the plug-in is executed
      with restricted permissions? Are there aspects that make it easier for a sandboxed
      plug-in assembly to exploit assemblies in its own application domain than to exploit
      assemblies in other application domains? I am not aware of such a case, but I do not
      dare to say “no” here. Maybe there is a CAS permission that I have not thought of,
      and maybe you can use it in a way that I have not considered yet. If such a permission
      exists and if this permission is granted to the sandboxed plug-in, it could bypass
      CAS. However, if your sandbox has only the permission to execute type-safe code (SecurityPermissionFlag.Execute)
      and if everything else the plug-in needs is provided by an types that the host application
      provides to the plug-in developer, the plug-in would not have such a permission. Therefore
      my personal answer to this question is: For a plug-in that has only the execution
      permission, I consider it safe to have the application and the plug-in executing in
      the same sandboxed application domain. If you disagree with me, I would be more than
      happy if you could tell me your opinion (my email address alias is my firstname the
      server name is heege.net).
   </p>
        <p>
      If you agree with me, it is time to discuss how to create a sandboxed application
      domain. One option is to use the <a href="http://msdn.microsoft.com/en-us/library/ms130766.aspx"> simple
      sandboxing API</a>, however, there are two disadvantages in this case:
   </p>
        <ul>
          <li>
         You would have to name each and every non-GACed assembly that should have full-trust
         permissions. For realistic applications this list could be quite long.</li>
          <li>
         As discussed <a href="http://www.heege.net/blog/PermaLink,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx">here</a>,
         it is easy to write code that causes unintended switches to the (full-trusted) default
         application domain</li>
        </ul>
        <p>
      Key to solving the latter issue is sandboxing the default application domain: If the
      default application domain is sandboxed, so that a plug-in executes only with the
      permission to execute type-safe code, and if the plug-in as well as the host application
      execute in the same application domain, there is no need to create another application
      domain and thread-promotion automatically ends up in the right application domain.
   </p>
        <p>
      Sandboxing the default application domain requires a custom AppDomainManager implementation.
      In this implementation you can to specify a HostSecurityManager. This HostSecurityManager
      could then grant full-trust permissions to all assemblies with your public key and
      execution-only permissions to all other assemblies. (Notice that assemblies from the
      GAC are always full-trust assemblies). The following C# code shows how to implement
      and AppDomainsManager:
   </p>
        <p style="font-size:10.0pt;font-family:&quot;Courier New&quot;">
          <span style="color:green">// AppDomainSandboxer.cs</span>
          <br />
          <span style="color:green">// compile with: csc /t:library /keyfile:keyfile.snk AppDomainSandboxer.cs</span>
          <br />
          <br />
          <span style="color:blue">using</span> System;<br /><span style="color:blue">using</span> System.Reflection;<br /><span style="color:blue">using</span> System.Security;<br /><span style="color:blue">using</span> System.Security.Policy;<br /><span style="color:blue">using</span> System.Security.Permissions;<br /><br /><span style="color:blue">namespace</span> AppDomainSandboxer<br />
      {<br />
        <span style="color:blue">public class</span><span style="color:#2B91AF">SandboxingAppDomainManager</span> : <span style="color:#2B91AF">AppDomainManager</span><br />
        {<br />
          <span style="color:#2B91AF">SandboxingHostSecurityManager</span> hostSecurityManager
      =<br />
                   <span style="color:blue">new</span><span style="color:#2B91AF">SandboxingHostSecurityManager</span>();<br /><br />
          <span style="color:blue">public</span><span style="color:blue">override</span><span style="color:#2B91AF">HostSecurityManager</span> HostSecurityManager<br />
          {<br />
            <span style="color:blue">get</span><br />
            {<br />
              <span style="color:blue">return</span> hostSecurityManager;<br />
            }<br />
          }<br />
        }<br /><br />
        <span style="color:blue">public class</span><span style="color:#2B91AF">SandboxingHostSecurityManager</span> : <span style="color:#2B91AF">HostSecurityManager</span><br />
        {<br />
          <span style="color:blue">private static</span><span style="color:#2B91AF">PermissionSet</span> psExecute;<br /><br />
          <span style="color:blue">private static</span><span style="color:#2B91AF">PermissionSet</span> psFullTrust;<br /><br />
          <span style="color:blue">private static</span><span style="color:#2B91AF">StrongNamePublicKeyBlob</span> publicKeyBlob;<br /><br />
          <span style="color:blue">static</span> SandboxingHostSecurityManager()<br />
          {<br />
            psExecute = <span style="color:blue">new</span><span style="color:#2B91AF">PermissionSet</span>( <span style="color:#2B91AF">PermissionState</span>.None);<br />
            psExecute.AddPermission( <span style="color:blue">new</span><span style="color:#2B91AF">SecurityPermission</span>(<br />
                                           <span style="color:#2B91AF">SecurityPermissionFlag</span>.Execution));<br />
            psFullTrust = <span style="color:blue">new</span><span style="color:#2B91AF">PermissionSet</span>( <span style="color:#2B91AF">PermissionState</span>.Unrestricted);<br />
            <span style="color:blue">foreach</span> ( <span style="color:blue">object</span> evObj <span style="color:blue">in</span><span style="color:#2B91AF">Assembly</span>.GetExecutingAssembly().Evidence)<br />
            {<br />
              <span style="color:#2B91AF">StrongName</span> sn
      = evObj <span style="color:blue">as</span><span style="color:#2B91AF">StrongName</span>;<br />
              <span style="color:blue">if</span> (sn
      != <span style="color:blue">null</span>)<br />
              {<br />
                publicKeyBlob = sn.PublicKey;<br />
                <span style="color:blue">return</span>;<br />
              }<br />
            }<br />
            <span style="color:blue">throw</span><span style="color:blue">new</span><span style="color:#2B91AF">Exception</span>( <span style="color:#A31515">"No
      public key found in AppDomainSandboxer assembly"</span>);<br />
          }<br /><br />
          <span style="color:blue">public override</span><span style="color:#2B91AF">HostSecurityManagerOptions</span> Flags<br />
          {<br />
            <span style="color:blue">get</span><br />
            {<br />
              <span style="color:blue">return</span><span style="color:#2B91AF">HostSecurityManagerOptions</span>.HostResolvePolicy;<br />
            }<br />
          }<br /><br />
          <span style="color:blue">public override</span><span style="color:#2B91AF">PermissionSet</span> ResolvePolicy( <span style="color:#2B91AF">Evidence</span> evidence)<br />
          {<br />
            <span style="color:blue">foreach</span> ( <span style="color:blue">object</span> evObj <span style="color:blue">in</span> evidence)<br />
            {<br />
              <span style="color:#2B91AF">StrongName</span> sn
      = evObj <span style="color:blue">as</span><span style="color:#2B91AF">StrongName</span>;<br />
              <span style="color:blue">if</span> (sn
      != <span style="color:blue">null</span>)<br />
              {<br />
                <span style="color:blue">if</span> (sn.PublicKey.Equals(publicKeyBlob))<br />
                {<br />
                  <span style="color:blue">return</span> psFullTrust;<br />
                }<br />
                <span style="color:blue">return</span> psExecute;<br />
              }<br />
            }<br />
            <span style="color:blue">return</span> psExecute;<br />
          }<br />
        }<br />
      }<br /></p>
        <p>
      There are two options to use this SandboxingAppDomainManager inside an application:
      You can either start the application with two special environment variables named
      APPDOMAIN_MANAGER_ASM and APPDOMAIN_MANAGER_TYPE as described <a href="http://msdn.microsoft.com/en-us/library/system.appdomainmanager.aspx">here</a>,
      or you can create a native application that hosts the CLR.
   </p>
        <img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=ae4f5285-9d04-4999-9765-1d7fcf6b2da2" />
      </body>
      <title>Sandboxed execution and performance</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,ae4f5285-9d04-4999-9765-1d7fcf6b2da2.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,ae4f5285-9d04-4999-9765-1d7fcf6b2da2.aspx</link>
      <pubDate>Thu, 15 Oct 2009 20:40:45 GMT</pubDate>
      <description>&lt;p&gt;
   In the last post, I have covered an aspect of sandboxing – unexpected AppDomain switches
   caused by thread promotion. In this post, I will focus on sandboxing, too. However,
   this time the primary focus is not security but performance. Nevertheless, at the
   end of this post, I will present an idea that might cause you less pain if you think
   about the thread-promotion issue.
&lt;/p&gt;
&lt;p&gt;
   So what are the performance issues of executing plug-ins in sandboxed AppDomains?
   Creating and managing AppDomains internally is by far not the most expensive part
   here. Typically, calls across application domains have much more impact on performance.
   There are different options for calling across application domains:
&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;
      AppDomain.DoCallback&lt;/li&gt;
   &lt;li&gt;
      Calling objects in other application domains via transparent proxies&lt;/li&gt;
   &lt;li&gt;
      ICLRRuntimeHost::ExecuteInAppDomain (a COM-based API internally used by msclr/appdomain.h
      and its various call_in_appdomain templates)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   Compared to calls inside an appdomain, all of these options are dark slow. Even if
   you use an optimization described &lt;a href="http://www.codeproject.com/KB/dotnet/FastAppDomainMarshal.aspx"&gt;here&lt;/a&gt;,
   there is a significant cost involved in cross AppDomain calls. For scenarios that
   require a lot of calls between the host application and the plug-in and vice versa,
   this is often not acceptable.
&lt;/p&gt;
&lt;p&gt;
   A customer of mine recently came up with a simple but very interesting idea that I
   have not considered so far: Why should the plug-in be executed in a different AppDomain?
   Can’t we create a sandboxed AppDomain in which only our assemblies and system assemblies
   have full-trust permissions whereas the plug-ins can only use a restricted permission-set?
&lt;/p&gt;
&lt;p&gt;
   Like most interesting questions, this question is not easy to answer. I do not claim
   that I have the ultimate answer to this question, but I want to explain my opinion
   here. At the end of the day it comes down to the question what are the real benefits
   an AppDomain can give you? In a later post, I will likely address AppDomains in more
   detail. For now it is sufficient to know that AppDomains can provide isolation; they
   are boundaries especially for
&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;
      assembly and type loading (and unloading)&lt;/li&gt;
   &lt;li&gt;
      configuration&lt;/li&gt;
   &lt;li&gt;
      CAS security assignments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   The first use-case for AppDoamins was ASP.NET. I think it is in fact fair to say,
   that many features of AppDomains only exist because the ASP.NET team needed them.
   However, this does not mean that these features are needed in all plug-in scenarios.
   Let’s take a look at each item mentioned above:
&lt;/p&gt;
&lt;p&gt;
   &lt;i&gt;Assembly and type loading (and unloading)&lt;/i&gt;: If you need hot-pluggable plug-ins
   (those that can be plugged in and out at runtime) you have to use AppDomains. AppDomains
   offer shadow copying of loaded assemblies which allows you to overwrite the assembly
   while it is loaded and, as explained &lt;a href="http://blogs.msdn.com/jasonz/archive/2004/05/31/145105.aspx"&gt;here&lt;/a&gt;,
   shutting down AppDomains is the only way to unload assemblies. However, for many pluggable
   applications, it is acceptable that a restart of the application is required to replace
   a plug-in.
&lt;/p&gt;
&lt;p&gt;
   &lt;i&gt;Configuration&lt;/i&gt;: While it can be convenient if each plug-in can have its own
   configuration file, it is seldom a strict requirement. For many applications, it is
   acceptable if the app and the plug-ins have to share a configuration file. In my experience,
   a plug-in typically receives its configuration as creation-parameters from the host
   application and not via configuration files.
&lt;/p&gt;
&lt;p&gt;
   &lt;i&gt;CAS permission assignments&lt;/i&gt;: For this aspect the answer is not that easy. Is
   it more secure if a plug-in is executed in a separate sandboxed application domain?
   Isn’t it sufficient if the host and the plug-in are executed in a sandboxed application
   domain in which the host’s code has full-trust permissions and the plug-in is executed
   with restricted permissions? Are there aspects that make it easier for a sandboxed
   plug-in assembly to exploit assemblies in its own application domain than to exploit
   assemblies in other application domains? I am not aware of such a case, but I do not
   dare to say “no” here. Maybe there is a CAS permission that I have not thought of,
   and maybe you can use it in a way that I have not considered yet. If such a permission
   exists and if this permission is granted to the sandboxed plug-in, it could bypass
   CAS. However, if your sandbox has only the permission to execute type-safe code (SecurityPermissionFlag.Execute)
   and if everything else the plug-in needs is provided by an types that the host application
   provides to the plug-in developer, the plug-in would not have such a permission. Therefore
   my personal answer to this question is: For a plug-in that has only the execution
   permission, I consider it safe to have the application and the plug-in executing in
   the same sandboxed application domain. If you disagree with me, I would be more than
   happy if you could tell me your opinion (my email address alias is my firstname the
   server name is heege.net).
&lt;/p&gt;
&lt;p&gt;
   If you agree with me, it is time to discuss how to create a sandboxed application
   domain. One option is to use the &lt;a href="http://msdn.microsoft.com/en-us/library/ms130766.aspx"&gt; simple
   sandboxing API&lt;/a&gt;, however, there are two disadvantages in this case:
&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;
      You would have to name each and every non-GACed assembly that should have full-trust
      permissions. For realistic applications this list could be quite long.&lt;/li&gt;
   &lt;li&gt;
      As discussed &lt;a href="http://www.heege.net/blog/PermaLink,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx"&gt;here&lt;/a&gt;,
      it is easy to write code that causes unintended switches to the (full-trusted) default
      application domain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   Key to solving the latter issue is sandboxing the default application domain: If the
   default application domain is sandboxed, so that a plug-in executes only with the
   permission to execute type-safe code, and if the plug-in as well as the host application
   execute in the same application domain, there is no need to create another application
   domain and thread-promotion automatically ends up in the right application domain.
&lt;/p&gt;
&lt;p&gt;
   Sandboxing the default application domain requires a custom AppDomainManager implementation.
   In this implementation you can to specify a HostSecurityManager. This HostSecurityManager
   could then grant full-trust permissions to all assemblies with your public key and
   execution-only permissions to all other assemblies. (Notice that assemblies from the
   GAC are always full-trust assemblies). The following C# code shows how to implement
   and AppDomainsManager:
&lt;/p&gt;
&lt;p style='font-size:10.0pt;font-family:"Courier New"'&gt;
   &lt;span style='color:green'&gt;// AppDomainSandboxer.cs&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style='color:green'&gt;// compile with: csc /t:library /keyfile:keyfile.snk AppDomainSandboxer.cs&lt;/span&gt;
   &lt;br /&gt;
   &lt;br /&gt;
   &lt;span style='color:blue'&gt;using&lt;/span&gt;&amp;nbsp;System;&lt;br /&gt;
   &lt;span style='color:blue'&gt;using&lt;/span&gt;&amp;nbsp;System.Reflection;&lt;br /&gt;
   &lt;span style='color:blue'&gt;using&lt;/span&gt;&amp;nbsp;System.Security;&lt;br /&gt;
   &lt;span style='color:blue'&gt;using&lt;/span&gt;&amp;nbsp;System.Security.Policy;&lt;br /&gt;
   &lt;span style='color:blue'&gt;using&lt;/span&gt;&amp;nbsp;System.Security.Permissions;&lt;br /&gt;
   &lt;br /&gt;
   &lt;span style='color:blue'&gt;namespace&lt;/span&gt;&amp;nbsp;AppDomainSandboxer&lt;br /&gt;
   {&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;public class&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;SandboxingAppDomainManager&lt;/span&gt; : &lt;span style='color:#2B91AF'&gt;AppDomainManager&lt;/span&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:#2B91AF'&gt;SandboxingHostSecurityManager&lt;/span&gt; hostSecurityManager
   =&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='color:blue'&gt;new&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;SandboxingHostSecurityManager&lt;/span&gt;();&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;public&lt;/span&gt; &lt;span style='color:blue'&gt;override&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;HostSecurityManager&lt;/span&gt; HostSecurityManager&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;get&lt;/span&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;return&lt;/span&gt; hostSecurityManager;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;public class&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;SandboxingHostSecurityManager&lt;/span&gt; : &lt;span style='color:#2B91AF'&gt;HostSecurityManager&lt;/span&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;private static&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;PermissionSet&lt;/span&gt; psExecute;&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;private static&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;PermissionSet&lt;/span&gt; psFullTrust;&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;private static&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;StrongNamePublicKeyBlob&lt;/span&gt; publicKeyBlob;&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;static&lt;/span&gt; SandboxingHostSecurityManager()&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;psExecute = &lt;span style='color:blue'&gt;new&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;PermissionSet&lt;/span&gt;( &lt;span style='color:#2B91AF'&gt;PermissionState&lt;/span&gt;.None);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;psExecute.AddPermission( &lt;span style='color:blue'&gt;new&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;SecurityPermission&lt;/span&gt;(&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style='color:#2B91AF'&gt;SecurityPermissionFlag&lt;/span&gt;.Execution));&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;psFullTrust = &lt;span style='color:blue'&gt;new&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;PermissionSet&lt;/span&gt;( &lt;span style='color:#2B91AF'&gt;PermissionState&lt;/span&gt;.Unrestricted);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;foreach&lt;/span&gt; ( &lt;span style='color:blue'&gt;object&lt;/span&gt; evObj &lt;span style='color:blue'&gt;in&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;Assembly&lt;/span&gt;.GetExecutingAssembly().Evidence)&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:#2B91AF'&gt;StrongName&lt;/span&gt; sn
   = evObj &lt;span style='color:blue'&gt;as&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;StrongName&lt;/span&gt;;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;if&lt;/span&gt; (sn
   != &lt;span style='color:blue'&gt;null&lt;/span&gt;)&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;publicKeyBlob = sn.PublicKey;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;return&lt;/span&gt;;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;throw&lt;/span&gt; &lt;span style='color:blue'&gt;new&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;Exception&lt;/span&gt;( &lt;span style='color:#A31515'&gt;&amp;quot;No
   public key found in AppDomainSandboxer assembly&amp;quot;&lt;/span&gt;);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;public override&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;HostSecurityManagerOptions&lt;/span&gt; Flags&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;get&lt;/span&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;return&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;HostSecurityManagerOptions&lt;/span&gt;.HostResolvePolicy;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;public override&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;PermissionSet&lt;/span&gt; ResolvePolicy( &lt;span style='color:#2B91AF'&gt;Evidence&lt;/span&gt; evidence)&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;foreach&lt;/span&gt; ( &lt;span style='color:blue'&gt;object&lt;/span&gt; evObj &lt;span style='color:blue'&gt;in&lt;/span&gt; evidence)&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:#2B91AF'&gt;StrongName&lt;/span&gt; sn
   = evObj &lt;span style='color:blue'&gt;as&lt;/span&gt; &lt;span style='color:#2B91AF'&gt;StrongName&lt;/span&gt;;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;if&lt;/span&gt; (sn
   != &lt;span style='color:blue'&gt;null&lt;/span&gt;)&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;if&lt;/span&gt; (sn.PublicKey.Equals(publicKeyBlob))&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;return&lt;/span&gt; psFullTrust;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;return&lt;/span&gt; psExecute;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style='color:blue'&gt;return&lt;/span&gt; psExecute;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   }&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;
   There are two options to use this SandboxingAppDomainManager inside an application:
   You can either start the application with two special environment variables named
   APPDOMAIN_MANAGER_ASM and APPDOMAIN_MANAGER_TYPE as described &lt;a href="http://msdn.microsoft.com/en-us/library/system.appdomainmanager.aspx"&gt;here&lt;/a&gt;,
   or you can create a native application that hosts the CLR.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=ae4f5285-9d04-4999-9765-1d7fcf6b2da2"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx</pingback:target>
      <title>Dangers of /clr and /clr:pure in sandboxed execution scenarios: Thread-promotion can bypass the sandbox!</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx</link>
      <pubDate>Fri, 09 Oct 2009 16:53:23 GMT</pubDate>
      <description>    &lt;p&gt;
   &lt;span&gt;One of the benefits of managed code is sandboxed execution: To avoid that malicious
   code is executed by plug-ins, an application does not need to use a separate language
   with restricted features. Plug-ins can be written in any .NET language, because the
   host can execute them in a sandbox with restricted permissions. Implementing a library
   that can be called by sandboxed code requires the infamous AllowPartiallyTrustedCallers
   attribute. With this attribute, you explicitly state that you are confident that your
   library does not have security vulnerabilities. If your library has to interoperate
   with native code, you should surely know about a pitfall that can easily allow a user
   of your library to bypass the sandbox. This potential vulnerability can be caused
   by a CLR interop feature called &lt;i&gt;thread promotion&lt;/i&gt;. In this post, I will explain
   this pitfall and how to avoid it in your libraries. However, before you can understand
   the impacts of thread promotion for CAS, I have to explain a little bit more about
   sandboxing first.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;To execute code in a sandbox, the CLR offers an API called the &lt;/span&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/ms130766.aspx"&gt; &lt;span&gt;simple
   sandboxing API&lt;/span&gt;&lt;/a&gt;&lt;span&gt;. This API creates a new AppDomain in which only assemblies
   form the GAC and a set of explicitly specified assemblies are executed with full-trust
   permissions. All other assemblies are executed with permissions specified in a permission-set
   that is passed to this API.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;Obviously, the permission-set that is granted to plug-ins should not contain
   several permissions. These include the skip-verification permission which allows you
   to execute code that is not proven to be type-safe and the permission to execute unmanaged
   code. Both permissions could be used to bypass the sandbox. The more permissions an
   app grants to a sandbox, the more features can be used by the plug-in. In my opinion,
   most sandboxes should only have the permission to execute code. All other features
   it needs should be provided by custom libraries that the host application implements.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;Many libraries that are called by plug-ins have to call native code. If the
   native code called by such a library uses threads that have not executed managed code
   so far (native-only threads) or if you use technologies that can automatically switch
   to other threads (like COM), you have to consider &lt;i&gt;thread promotion&lt;/i&gt;. Thread
   promotion is done when a native-only thread invokes a native-&amp;gt;mananaged thunk.
   Normally, native-&amp;gt;managed thunks simply stay in the AppDomain that the managed
   thread is executing. (Due to the &lt;i&gt;.retainappdomain&lt;/i&gt; flag of the &lt;i&gt;.vtfixup&lt;/i&gt; metadata
   in the assembly manifest.) However, when a native-&amp;gt;managed thunk promotes a native-only
   thread to a managed thread, it has to pick an AppDomain. Because in this case the
   CLR does not have any information about which AppDomain is supposed to execute the
   managed function, the thread starts its managed life in the default AppDomain (the
   first AppDomain, which is created automatically when the CLR starts). Typically the
   default AppDomain executes all assemblies with full-trust. Therefore, the managed
   code executes with full-trust permissions now. If the libraries code calls back into
   the plug-in e. g. via a delegate, an event or via a virtual function call, the plug-in
   is now executing with full-trust permissions and not in its sandbox any more.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;The following code demonstrates this unintended switch to the default AppDomain.
   Notice that in main, a new AppDomain called child is created and that the method Program::ExecuteInChildDomain
   is called in this new AppDomain. ExecuteInChildDomain calls a native function fNative
   and passes a pointer to a native callback method named fNativeCallback. Now fNative
   creates a new native thread which invokes a managed function. When created, the new
   thread is a native-only thread. When the thunk is invoked to call the managed function,
   the native-only thread is promoted to a managed thread that executes in the default
   domain, not in the child domain that created the thread.&lt;/span&gt;
&lt;/p&gt;
&lt;p style="font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;"&gt;
   &lt;span style="color:green;"&gt;// DangersOfNativThreadsInSandboxedAppDomains.cpp : main
   project file.&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:green;"&gt;// cl /clr DangersOfNativThreadsInSandboxedAppDomains.cpp&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:green;"&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;#include&lt;/span&gt;&lt;span &gt; &lt;span style="color:#A31515"&gt;&amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:#A31515;"&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;typedef&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; (&lt;span style="color:blue"&gt;__stdcall&lt;/span&gt;*PFN_NATIVECALLBACK)();&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;void&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;_stdcall&lt;/span&gt; fNative(PFN_NATIVECALLBACK
   pfnCallback);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;void&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;_stdcall&lt;/span&gt; fNativeCallback();&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;DWORD WINAPI ThreadMain(LPVOID pfnCallback);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;using&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;namespace&lt;/span&gt; System;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;ref&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;class&lt;/span&gt; Program&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;internal&lt;/span&gt;&lt;span &gt;:&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue"&gt;static&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; DumpAppDomainInfo(String^
   method)&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;AppDomain^ current = AppDomain::CurrentDomain;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Console::WriteLine(&lt;span style="mso-tab-count:1"&gt; &lt;/span&gt; &lt;span style="color:#A31515"&gt;&amp;quot;Method:
   {0}, AppDomain: {1}&amp;quot;&lt;/span&gt;,&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;method,&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;current-&amp;gt;IsDefaultAppDomain()
   ? &lt;span style="color:#A31515"&gt;&amp;quot;(default AppDomain)&amp;quot;&lt;/span&gt; &lt;/span&gt; 
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;:
   current-&amp;gt;FriendlyName);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue"&gt;static&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; Main()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Program::DumpAppDomainInfo(&lt;span style="color:#A31515"&gt;&amp;quot;Program::Main&amp;quot;&lt;/span&gt;);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;AppDomain^ child = AppDomain::CreateDomain(&lt;span style="color:#A31515"&gt;&amp;quot;childDomain&amp;quot;&lt;/span&gt;);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;child-&amp;gt;DoCallBack(&lt;span style="color:blue"&gt;gcnew&lt;/span&gt; CrossAppDomainDelegate(&amp;amp;ExecuteInChildDomain));&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue"&gt;static&lt;/span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; ExecuteInChildDomain()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Program::DumpAppDomainInfo(&lt;span style="color:#A31515"&gt;&amp;quot;Program::ExecuteInChildDomain&amp;quot;&lt;/span&gt;);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;fNative(&amp;amp;fNativeCallback);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;};&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;void&lt;/span&gt;&lt;span &gt; main()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;Program::Main();&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;void&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;__stdcall&lt;/span&gt; ManagedFunctionCalledByNativeCallback()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;Program::DumpAppDomainInfo(&lt;span style="color:#A31515"&gt;&amp;quot;::ManagedFunctionCalledByNativeCallback&amp;quot;&lt;/span&gt;);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;#pragma&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;unmanaged&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;DWORD WINAPI ThreadMain(LPVOID pfnCallback);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;void&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;_stdcall&lt;/span&gt; fNative(PFN_NATIVECALLBACK
   pfnCallback)&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; &lt;span style="color:green"&gt;// this new thread starts as
   a native-only thread and gets promoted&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; &lt;span style="color:green"&gt;// when the new thread calls
   a managed function for the first time&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;HANDLE hThread = ::CreateThread(NULL, 0, &amp;amp;ThreadMain,
   pfnCallback, 0, 0);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;::WaitForSingleObject(hThread, 1000);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;::CloseHandle(hThread);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;DWORD WINAPI ThreadMain(LPVOID pfnCallback)&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; ((PFN_NATIVECALLBACK)pfnCallback)();&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue"&gt;return&lt;/span&gt; 0;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;void&lt;/span&gt;&lt;span &gt; &lt;span style="color:blue"&gt;_stdcall&lt;/span&gt; fNativeCallback()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; ManagedFunctionCalledByNativeCallback();&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;}&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;Now that we know about the problem, it is time to think about a solution: How
   can a native library that calls managed functions from native code ensure that its
   managed functions end up in the right application domain? There are two fundamentally
   different approaches that I would like to mention here: one that is based on an explicit
   switch of the application domain, and another one that is based on a switch that the
   CLR can do implicitly. &lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;Explicitly switching application domains can be done either via AppDomain::DoCallback
   or with helper functions defined in a Visual C++ header file called &amp;lt;msclr/appdomain.h&amp;gt;.
   This header defines several overloads of a function called call_in_appdomain, each
   of these functions take the identifier of the application id you want to call and
   a function pointer. Various overloads exist for the different calling conventions
   and for different numbers of arguments. To use this, you could modify your implementation
   of fNative as follows: &lt;/span&gt; 
&lt;/p&gt;
&lt;p style="font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;;"&gt;
   &lt;span &gt;DWORD WINAPI ThreadMain(LPVOID pvCallbackInfo);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;struct&lt;/span&gt;&lt;span&gt; CallbackInfo&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;PFN_NATIVECALLBACK pfnCallback;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue"&gt;int&lt;/span&gt; appDomainId;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;};&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;void&lt;/span&gt;&lt;span&gt; &lt;span style="color:blue"&gt;_stdcall&lt;/span&gt; fNative(PFN_NATIVECALLBACK
   pfnNativeCallback)&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;DWORD appDomainId;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;HRESULT hr = msclr::_detail::get_clr_runtime_host()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;-&amp;gt;GetCurrentAppDomainId(&amp;amp;appDomainId);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;hr; &lt;span style="color:green"&gt;// error handling ignored
   for simplicity here&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:green;"&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;CallbackInfo callbackInfo = { pfnNativeCallback, appDomainId
   };&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; &lt;span style="color:green"&gt;// this newly create thread
   starts as a native-only thread and gets &lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; &lt;span style="color:green"&gt;// promoted when the new thread
   calls a managed function for the first time&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;HANDLE hThread = ::CreateThread(NULL, 0, &amp;amp;ThreadMain,
   &amp;amp;callbackInfo , 0, 0);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;::WaitForSingleObject(hThread, 1000);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;::CloseHandle(hThread);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;DWORD WINAPI ThreadMain(LPVOID pvCallbackInfo)&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;CallbackInfo* pCallbackInfo = (CallbackInfo*)pvCallbackInfo;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;msclr::call_in_appdomain(pCallbackInfo-&amp;gt;appDomainId, &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;pCallbackInfo-&amp;gt;pfnCallback);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue"&gt;return&lt;/span&gt; 0;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;}&lt;/span&gt;&lt;code&gt;&lt;span style="font-size:10.0pt;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US"&gt; &lt;/span&gt;&lt;/code&gt; &lt;span&gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;This implementation passes not only the function pointer of the callback function
   to the thread, but a pointer to a structure that contains the callback function pointer
   as well as an integer value identifying the callback application domain. The thread
   then uses this information to invoke the callback function in the right application
   domain.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span&gt;As I mentioned, there is a second approach which makes sure that the CLR automatically
   marshals the call to the right application domain. This approach is based on a method
   that you have probably used before. It is called &lt;/span&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getdelegateforfunctionpointer(VS.85).aspx"&gt; &lt;span&gt; Marshal::GetDelegateForFunctionPointer&lt;/span&gt;&lt;/a&gt;&lt;span style="mso-ansi-language:EN-US"&gt;.
   This method generates a thunk that can be called by native code via a function pointer.
   Notice that in contrast to other thunks, this thunk is aware of the application domain
   where it was created. Therefore, it can automatically switch to the right application
   domain even when this thunk is called by a thread that has just been promoted to a
   managed thread. The following code shows how to use this method:&lt;/span&gt;
&lt;/p&gt;
&lt;p style="font-size:10.0pt;font-family:&amp;quot;Courier New&amp;quot;;"&gt;
   &lt;span &gt;[System::Runtime::InteropServices::UnmanagedFunctionPointer(&lt;/span&gt;
   &lt;br /&gt;
   &lt;span &gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;System::Runtime::InteropServices::CallingConvention::StdCall)]&lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;delegate&lt;/span&gt;&lt;span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; CallbackDelegate();&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;static&lt;/span&gt;&lt;span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; ManagedCallback()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;Program::DumpAppDomainInfo(&lt;span style="color:#A31515"&gt;&amp;quot;Program::ManagedCallback&amp;quot;&lt;/span&gt;);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;}&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:blue;"&gt;static&lt;/span&gt;&lt;span&gt; &lt;span style="color:blue"&gt;void&lt;/span&gt; ExecuteInChildDomain()&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;{&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;Program::DumpAppDomainInfo(&lt;span style="color:#A31515"&gt;&amp;quot;Program::ExecuteInChildDomain&amp;quot;&lt;/span&gt;);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;CallbackDelegate^ cb = &lt;span style="color:blue"&gt;gcnew&lt;/span&gt; CallbackDelegate(&amp;amp;ManagedCallback);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue"&gt;using&lt;/span&gt; System::Runtime::InteropServices::Marshal;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; &lt;span style="color:green"&gt;// this call generates a thunk
   that can be called by native code&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;IntPtr fnPtr = Marshal::GetFunctionPointerForDelegate(cb);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;fNative((PFN_NATIVECALLBACK)fnPtr.ToPointer());&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
   &lt;br /&gt;
   &lt;span style="color:green;"&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;// the delegate’s lifetime determines
   the lifetime of the generated thunk&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt; &lt;span style="color:green"&gt;// =&amp;gt; keep the delegate alife
   as long as native code needs the thunk&lt;/span&gt;&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;&lt;span &gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; &lt;span&gt;GC::KeepAlive(cb);&lt;/span&gt;
   &lt;br /&gt;
   &lt;span&gt;}&lt;/span&gt;
   &lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;
   In this post I have explained an issue that you have to understand if you want to
   write assemblies that use C++/CLI interop and allow partially trusted callers at the
   same time. In one of my next posts I will describe a safty net that you can implement
   in your pluggable application that ensures that no undesired bypassing of the sandbox
   can occur even if your plugin uses assemblies that are not aware of this issue. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=62340fe1-8ab5-443a-b49e-2b37bbf15c24"&gt;</description>
      <category>C++/CLI</category>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,d3b405c1-73d4-4d04-934f-3e2ee2b5f589.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,d3b405c1-73d4-4d04-934f-3e2ee2b5f589.aspx</pingback:target>
      <title>Deploying native DLLs with managed wrapper assemblies into the GAC</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,d3b405c1-73d4-4d04-934f-3e2ee2b5f589.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,d3b405c1-73d4-4d04-934f-3e2ee2b5f589.aspx</link>
      <pubDate>Wed, 30 Sep 2009 16:47:19 GMT</pubDate>
      <description>&lt;p&gt;
   Recently, a customer came up with a straightforward deployment problem:
&lt;/p&gt;
&lt;i&gt;I want to deploy an assembly that wraps a native DLL in the GAC. Deploying the
wrapped native assembly in System32 is to error prone, deploying the wrapped assembly
in WinSxS is too much of an overhead. How can I ensure that the managed wrapper can
load the native assembly?&lt;/i&gt; 
&lt;p&gt;
   I have thought about a solution to this problem some times, but I have to admit, even
   though my first idea was right, so far I never found the time to prove that my guess
   really works. Today I took the time to take a closer look at the solution.
&lt;/p&gt;
&lt;p&gt;
   Here is was my initial idea: 
&lt;p&gt;
   From inspecting mscorlib with ILDASM, I knew that an assembly can have links to other
   files.
&lt;/p&gt;
&lt;p&gt;
   &lt;code&gt; .assembly mscorlib&lt;br /&gt;
   {&lt;br /&gt;
   … attributes ignored here …&lt;br /&gt;
   .file nometadata sortkey.nlp&lt;br /&gt;
   .hash = (6E 30 2E 50 36 FB 60 2C 8E 50 C0 83 54 8B CC EA)&lt;br /&gt;
   .file nometadata sorttbls.nlp&lt;br /&gt;
   .hash = (F9 04 A8 31 CD FB 23 72 95 63 5D 14 9A A0 66 8E)&lt;br /&gt;
   … other .file entries ignored here …&lt;br /&gt;
   .mresource public sortkey.nlp&lt;br /&gt;
   {&lt;br /&gt;
   .file sortkey.nlp at 0x00000000&lt;br /&gt;
   }&lt;br /&gt;
   .mresource public sorttbls.nlp&lt;br /&gt;
   {&lt;br /&gt;
   .file sorttbls.nlp at 0x00000000&lt;br /&gt;
   }&lt;br /&gt;
   } &lt;/code&gt;
&lt;/p&gt;
Furthermore you can see that the files are installed together with mscorlib.dll in
the GAC:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; dir c:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089&lt;br /&gt;
   4.550.656 mscorlib.dll&lt;br /&gt;
   262.148 sortkey.nlp&lt;br /&gt;
   20.320 sorttbls.nlp&lt;br /&gt;
   … other files ignored here …&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
&gt;
My assumption was that if you can install native DLLs in the same way in the GAC,
they can be magically found when needed. Creating assemblies with .file references
is easy. Assume the following simple native DLLs:&lt;br /&gt;
nativedll2.cpp, compile with CL /LD /EHs nativedll2.cpp&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; #include 
   &lt;iostream&gt;
      &lt;br /&gt;
      using namespace std;&lt;br /&gt;
      &lt;br /&gt;
      void __declspec(dllexport) fNative2()&lt;br /&gt;
      {&lt;br /&gt;&lt;&lt; "fNative2 called." &lt;&lt; endl;&lt;br/&gt;
      cout }&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
nativedll.cpp, compile with CL /LD /EHs nativedll.cpp&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; #include 
   &lt;iostream&gt;
      &lt;br /&gt;
      #include 
      &lt;windows.h&gt;
         &lt;br /&gt;
         &lt;br /&gt;
         using namespace std;&lt;br /&gt;
         &lt;br /&gt;
         #pragma comment(lib, "nativeDll2.lib")&lt;br /&gt;
         void __declspec(dllimport) fNative2();&lt;br /&gt;
         &lt;br /&gt;
         void __declspec(dllexport) fNative()&lt;br /&gt;
         {&lt;br /&gt;&lt;&lt; "fNative called." &lt;&lt; endl;&lt;br/&gt;
         cout fNative2();&lt;br /&gt;
         }&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
A wrapper assembly for nativedll.cpp can be created with this source code&lt;br /&gt;
testasm.dll:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; using namespace System;&lt;br /&gt;
   &lt;br /&gt;
   #pragma comment(lib, "nativedll.lib")&lt;br /&gt;
   void __declspec(dllimport) fNative();&lt;br /&gt;
   &lt;br /&gt;
   public ref class Test&lt;br /&gt;
   {&lt;br /&gt;
   public:&lt;br /&gt;
   void DoSth()&lt;br /&gt;
   {&lt;br /&gt;
   Console::WriteLine("Test.DoSth called. Calling native DLL now.");&lt;br /&gt;
   fNative();&lt;br /&gt;
   }&lt;br /&gt;
   };&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
To compile it with the two native DLLs as linked files, use the following command
line:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; cl /LD /clr testasm.cpp /link /keyfile:..\keyfile.snk /assemblylinkresource:nativedll.dll
   /assemblylinkresource:nativedll2.dll&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
Notice that the linker flag /assemblylinkresource adds the .file entries to the assembly
manifest:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; .file nometadata nativedll.dll&lt;br /&gt;
   .hash = (EA 16 B4 08 D1 C4 D2 C0 77 CB 00 C7 93 A0 85 4A 41 BC F2 52 )&lt;br /&gt;
   .file nometadata nativedll2.dll&lt;br /&gt;
   .hash = (9D D1 39 D0 4C F9 08 7E 33 2F CD D2 8B C3 3E 55 BD E1 81 27 )&lt;br /&gt;
   .mresource public nativedll.dll&lt;br /&gt;
   {&lt;br /&gt;
   .file nativedll.dll at 0x00000000&lt;br /&gt;
   }&lt;br /&gt;
   .mresource public nativedll2.dll&lt;br /&gt;
   {&lt;br /&gt;
   .file nativedll2.dll at 0x00000000&lt;br /&gt;
   }&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
Given that the DLL is signed, it can be placed into the GAC:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; Gacutil –i testasm.dll&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
Notice the .hash metadata for each .file entry. According to my tests, this metadata
is not used for assembly validation (e. g. via SN.EXE –v testasm.dll), but during
the installation of the assembly into the GAC. If you modify a linked file before
adding the assembly to the GAC, GACUtil will report the following error:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; Failure adding assembly to the cache: One or more modules were streamed in
   which did not match those specified by the manifest. The hash of one or more modules
   found does not match the hash recorded in the manifest.&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
Inspecting the assembly’s GAC_32 subdirectory after successfully installing it to
the GAC shows the following files:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; 105.472 nativedll.dll&lt;br /&gt;
   105.472 nativedll2.dll&lt;br /&gt;
   24.064 testasm.dll&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
Obviously, the native DLLs are now installed into the GAC. The interesting question
is: Are they really loaded from the GAC? The answer is yes. To prove this, use the
following simple client application:&lt;br /&gt;
&lt;br /&gt;
Testapp.cpp (should be in a different directory)&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; using namespace System;&lt;br /&gt;
   &lt;br /&gt;
   int main()&lt;br /&gt;
   {&lt;br /&gt;
   Console::WriteLine("calling Test.DoSth now");&lt;br /&gt;
   Test t;&lt;br /&gt;
   t.DoSth();&lt;br /&gt;
   Console::WriteLine("Press enter to stop app");&lt;br /&gt;
   Console::ReadLine();&lt;br /&gt;
   }&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
You can compile this file with the following command line:&lt;br /&gt;
&lt;div style="margin-left:20pt; margin-top:10pt;"&gt;
   &lt;code&gt; cl /clr testapp.cpp /FU …relative path to testasm.dll …&lt;br /&gt;
   &lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
Executing testapp.exe should work even when nativedll.dll and nativedll2.dll are not
in a location that LoadLibrary normally uses; they are loaded from the GAC. If you
want to verify this, compile all sources as shown, run testapp.exe and attach a debugger
while the app is waiting at Console::ReadLine. In the debugger, you can see where
dependent DLLs are loaded from (via the WinDBG command “lm –v” or the VS modules window). 
&lt;br /&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=d3b405c1-73d4-4d04-934f-3e2ee2b5f589"&gt;</description>
      <category>C++/CLI</category>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,94167d73-7954-4a5c-a745-dc60d352cdef.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,94167d73-7954-4a5c-a745-dc60d352cdef.aspx</pingback:target>
      <title>Marshalling native function pointers</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,94167d73-7954-4a5c-a745-dc60d352cdef.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,94167d73-7954-4a5c-a745-dc60d352cdef.aspx</link>
      <pubDate>Fri, 06 Apr 2007 09:13:08 GMT</pubDate>
      <description>&lt;p&gt;
   Now that the book is written and all urgent tasks I had to defer due to the book are
   done, I find some time to blog about technical topics.
&lt;/p&gt;
&lt;p&gt;
   Recently, a customer asked me how to marshal function pointers across managed / unmanaged
   interop boundaries. If you know a simple API and two attributes and if you are aware
   of a pitfall specific to marshaling function pointers, the job can be quite easy.
&lt;/p&gt;
&lt;p&gt;
   To discuss this topic, consider the following simple API:
&lt;/p&gt;
&lt;code&gt; namespace NativeAPI&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;struct CallbackData&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double d;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;};&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;typedef void (*PFNCallback)(CallbackData* p);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;class SampleClass&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PFNCallback _pfn;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SampleClass(PFNCallback pfn);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void F();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;};&lt;br /&gt;
}&lt;br /&gt;
&lt;/code&gt; 
&lt;p&gt;
   In my book I focus on wrapping class libraries that use virtual functions for callbacks
   instead of function pointers, because virtual functions are the typical C++-like approach
   for callbacks. But obviously, a lot of C++ class libraries have their roots in C which
   can force you to care about arguments of function pointer types.
&lt;/p&gt;
&lt;p&gt;
   The managed equivalent to a native function pointer is a delegate. There are different
   ways to map between delegates and function pointers. The following code shows a delegate
   that can be mapped to the native function pointer of type &lt;code&gt;PFNCallback&lt;/code&gt;:
&lt;/p&gt;
&lt;code&gt; namespace ManagedWrapper { &amp;nbsp;&amp;nbsp;using namespace System::Runtime::InteropServices;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;[StructLayout(LayoutKind::Sequential)]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public value struct CallbackData&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double d;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;};&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;[UnmanagedFunctionPointer(CallingConvention::Cdecl)]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public delegate void CallbackDelegate(CallbackData% p);&lt;br /&gt;
} &lt;/code&gt; 
&lt;p&gt;
   Notice that I first define a managed wrapper type for CallbackData that has the same
   binary layout as its native counterpart. This is done with the StructLayout attribute.
   The attribute is only used for documentation purposes, because sequential layout is
   the default setting for custom value types defined in C++/CLI (and C#). The delegate
   type has the UnmanagedFunctionPointerAttribute, which is not optional in this case.
   Using this attribute, you can specify the calling convention of the native function
   pointer type. In the native API's header file, the &lt;code&gt;PFNCallback&lt;/code&gt; is defined
   without an explicit calling convention specification – this is not recommended, but
   it occurs quite often. In this case, the function pointer type has the default calling
   convention, which depends on compiler switches. If no compiler switch is used, the
   default calling convention for C-style function pointers is &lt;code&gt;__cdecl&lt;/code&gt;.
   Using the compiler switches /Gz or /Gr, the default calling convention can be changed
   to &lt;code&gt;__stdcall&lt;/code&gt; or &lt;code&gt;__fastcall&lt;/code&gt;. In the concrete scenario that
   my customer faced, neither /Gz nor /Gr are used. To express that the &lt;code&gt;CallbackDelegate&lt;/code&gt; should
   be marshaled to a &lt;code&gt;__cdecl&lt;/code&gt; function pointer, the UnmanagedFunctionPointerAttribute
   is necessary. If the native function pointer is a &lt;code&gt;__fastcall&lt;/code&gt; function,
   you can not provide a simple mapping, because calling &lt;code&gt;__fastcall&lt;/code&gt; functions
   from managed code is not supported by the current version (2.0) of the CLR. Once you
   have properly defined the delegate, you can use the function &lt;code&gt;Marshal::GetFunctionPointerForDelegate&lt;/code&gt; to
   receive a pointer to a native-&gt;managed thunk for the delegate. This pointer can then
   be passed to native code. If native code uses this pointer for function calls, the
   thunk performs the native-&amp;gt;managed transition and invokes the delegate. To wrap &lt;code&gt;NativeAPI::SampleClass&lt;/code&gt;,
   you can implement the following wrapper class: 
&lt;/p&gt;
&lt;code&gt; namespace ManagedWrapper&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public ref class SampleClass&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NativeAPI::SampleClass* _pWrappedObject;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CallbackDelegate^ _callbackDelegate;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;public:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SampleClass(CallbackDelegate^ cbd);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;void F();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;~SampleClass();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;};&lt;br /&gt;
}&lt;br /&gt;
&lt;/code&gt; 
&lt;p&gt;
   In the constructor of this wrapper class, you can use &lt;code&gt;Marshal::GetFunctionPointerForDelegate&lt;/code&gt; to
   determine the function pointer that is passed to the constructor of &lt;code&gt;NativeLib::SampleClass&lt;/code&gt;.
   The following code shows the implementation of &lt;code&gt;ManagedWrapper::SampleClass&lt;/code&gt;. 
&lt;/p&gt;
&lt;code&gt; namespace ManagedWrapper&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;SampleClass::SampleClass(CallbackDelegate^ callbackDelegate)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;: _callbackDelegate(callbackDelegate),&lt;br /&gt;
&amp;nbsp;&amp;nbsp;_pWrappedObject(nullptr)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IntPtr p = Marshal::GetFunctionPointerForDelegate(_callbackDelegate);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_pWrappedObject = new NativeAPI::SampleClass((NativeAPI::PFNCallback)p.ToPointer());&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!_pWrappedObject)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw gcnew OutOfMemoryException("Could not allocate
memory on C++ free store");&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;void SampleClass::F()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_pWrappedObject-&gt;F();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;SampleClass::~SampleClass()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;NativeAPI::SampleClass* pWrappedObject = _pWrappedObject;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_pWrappedObject = nullptr;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delete _pWrappedObject;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
}&lt;br /&gt;
&lt;/code&gt; 
&lt;p&gt;
   Notice that in the member initialization list of the constructor, I first store a
   handle to the target delegate in a member variable. This is important, to control
   the lifetime of the thunk. At the first view, one might think that the thunk manages
   a tracking handle to the target delegate, which would keep the delegate alive as long
   as the thunk exists. However, the opposite is the case. It is not the thunk that keeps
   the delegate alive; the delegate keeps the thunk alive: The thunk is guaranteed to
   exist only as long as the delegate exists. The thunk only contains a weak reference
   to the target delegate which it can use for invocation if the delegate is not garbage
   collected. Due to this implementation, the following code would definitely be a bug: 
&lt;/p&gt;
&lt;code&gt; SampleClass::SampleClass(CallbackDelegate^ callbackDelegate)&lt;br /&gt;
: _pWrappedObject(nullptr)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;IntPtr p = Marshal::GetFunctionPointerForDelegate(callbackDelegate);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;_pWrappedObject = new NativeAPI::SampleClass((NativeAPI::PFNCallback)p.ToPointer());&lt;br /&gt;
&amp;nbsp;&amp;nbsp;if (!_pWrappedObject)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw gcnew OutOfMemoryException("Could not allocate memory
on C++ free store");&lt;br /&gt;
}&lt;br /&gt;
&lt;/code&gt; 
&lt;p&gt;
   Since the delegate that was used to create the thunk (and the function pointer referring
   to the thunk) is not stored in a member variable, it can be GCed unless other references
   to the delegate exist. When this delegate is GCed, the thunk can be removed as well.
   Notice that the thunk is not automatically removed when its target delegate is deleted,
   because the thunk and the delegate are created on different heaps: the delegate is
   instantiated on the GC heap, whereas the thunk is created on a heap that I like to
   call the CLR's code heap. An important difference of these heaps is that the code
   heap consists of memory pages that have the attribute PAGE_EXECUTE_READWRITE. The
   following code shows you some internals about Marshal::GetDelegateForFunctionPointer 
&lt;/p&gt;
&lt;code&gt; // GFPFDTests.cpp&lt;br /&gt;
// build with "CL /clr GFPFDTests.cpp"&lt;br /&gt;
&lt;br /&gt;
#include "windows.h"&lt;br /&gt;
&lt;br /&gt;
using namespace System;&lt;br /&gt;
using namespace System::Diagnostics;&lt;br /&gt;
using namespace System::Runtime::InteropServices;&lt;br /&gt;
&lt;br /&gt;
typedef void (__cdecl* PFN)();&lt;br /&gt;
&lt;br /&gt;
[UnmanagedFunctionPointer(CallingConvention::Cdecl)]&lt;br /&gt;
public delegate void PFNDelegate();&lt;br /&gt;
&lt;br /&gt;
// managed function has __cdecl calling convention&lt;br /&gt;
// therefore, a PFN can point to it.&lt;br /&gt;
void __cdecl F()&lt;br /&gt;
{&lt;br /&gt;
Console::WriteLine("::F called");&lt;br /&gt;
}&lt;br /&gt;
int main(array&lt;System::String ^&gt; ^args)&lt;br /&gt;
   {&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;PFNDelegate^ d1 = gcnew PFNDelegate(F);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;IntPtr p1 = Marshal::GetFunctionPointerForDelegate(d1);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;IntPtr p2 = Marshal::GetFunctionPointerForDelegate(d1);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;// calling M::GFPFD twice for same delegate returns same thunk&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;Debug::Assert(p1 == p2);&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;PFNDelegate^ d2 = gcnew PFNDelegate(F);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;p2 = Marshal::GetFunctionPointerForDelegate(d2);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;// calling M::GFPFS twice for different delegates returns&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;// different thunks even if delegate target is the same&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;Debug::Assert(p1 != p2);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;MEMORY_BASIC_INFORMATION mbi;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;VirtualQuery(p1.ToPointer(), &amp;mbi, sizeof(mbi));&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;// thunks are allocated on a heap that consits of pages &amp;nbsp;&amp;nbsp;//
   with the PAGE_EXECUTE_READWRITE flag&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;Debug::Assert((mbi.Protect &amp; PAGE_EXECUTE_READWRITE) ==&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PAGE_EXECUTE_READWRITE);&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;void* pD1 = *(void**)&amp;d1; // hack to get native pointer to delegate&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;VirtualQuery(pD1, &amp;mbi, sizeof(mbi));&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;// .NET objects are allocated on the GC heap which consists of&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;// pages with the PAGE_READWRITE flag&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;Debug::Assert((mbi.Protect &amp; PAGE_READWRITE) ==&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PAGE_READWRITE);&lt;br /&gt;
   &lt;br /&gt;
   &amp;nbsp;&amp;nbsp;PFN pfn = (PFN)p1.ToPointer();&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;pfn();&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;WeakReference wr(d1);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;d1 = nullptr;&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;GC::Collect(2);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;Debug::Assert(!wr.IsAlive);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;try&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pfn();&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// since the target delegate does not exist any more,&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// an exception is thrown here and the line below is&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// not executed&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// if you execute this in a debugger, you will likely see&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// a "Managed Debugging Assistant" instead.&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// MDAs are CLR internal assertion-like constructs &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Debug::Assert(FALSE);&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;catch (System::AccessViolationException^ ex)&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;{&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Debug::WriteLine("Expected exception");&lt;br /&gt;
   &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
   }&lt;br /&gt;

&lt;/code&gt; 
&lt;p&gt;
   In this post I have discussed how to treat marshal delegates to native function pointers.
   However, I have not discussed what you should do if the signature of the native function
   requires parameter marshalling. This will be addressed in my next post. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=94167d73-7954-4a5c-a745-dc60d352cdef"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,0440bf0e-243d-4900-a81f-16aee3f4b89c.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,0440bf0e-243d-4900-a81f-16aee3f4b89c.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">A long project is comming to an end soon.
   After one year of writing, my <a href="http://www.amazon.com/Expert-Visual-C++-CLI/dp/1590597567/ref=pd_sim_b_4/104-6627705-3354307">book</a> will
   be finished soon. 3 chapters need some minor changes. All other chapters of my book
   are now going to be copy edited. The book will summarize essentail parts of my research
   on C++/CLI in the last two years. Notice that the announcement in amazon.com is not
   100% correct. The title of the book will be "Expert C++/CLI: .NET for Visual C++ programmers"
   and the release date will be Mid March. <img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=0440bf0e-243d-4900-a81f-16aee3f4b89c" /></body>
      <title>Finishing my book</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,0440bf0e-243d-4900-a81f-16aee3f4b89c.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,0440bf0e-243d-4900-a81f-16aee3f4b89c.aspx</link>
      <pubDate>Sat, 13 Jan 2007 09:00:07 GMT</pubDate>
      <description>A long project is comming to an end soon. After  one year of writing, my &lt;a href="http://www.amazon.com/Expert-Visual-C++-CLI/dp/1590597567/ref=pd_sim_b_4/104-6627705-3354307"&gt;book&lt;/a&gt; will
be finished soon. 3 chapters need some minor changes. All other chapters of my book
are now going to be copy edited. The book will summarize essentail parts of my research
on C++/CLI in the last two years. Notice that the announcement in amazon.com is not
100% correct. The title of the book will be "Expert C++/CLI: .NET for Visual C++ programmers"
and the release date will be Mid March. &lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=0440bf0e-243d-4900-a81f-16aee3f4b89c"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,31643b9e-124b-4a57-82c6-08acb6a09f5f.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,31643b9e-124b-4a57-82c6-08acb6a09f5f.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      1) Since April, 1st I am an MVP for Visual C++.
   </p>
        <p>
      2) My first article in the MSDN Magazine has been published: <a href="http://msdn.microsoft.com/msdnmag/issues/06/05/MixAndMatch/default.aspx">http://msdn.microsoft.com/msdnmag/issues/06/05/MixAndMatch/default.aspx</a></p>
        <img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=31643b9e-124b-4a57-82c6-08acb6a09f5f" />
      </body>
      <title>Some personal things</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,31643b9e-124b-4a57-82c6-08acb6a09f5f.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,31643b9e-124b-4a57-82c6-08acb6a09f5f.aspx</link>
      <pubDate>Tue, 11 Apr 2006 12:15:43 GMT</pubDate>
      <description>&lt;p&gt;
   1) Since April, 1st I am an MVP for Visual C++.
&lt;/p&gt;
&lt;p&gt;
   2) My first article in the MSDN Magazine has been published: &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/05/MixAndMatch/default.aspx"&gt;http://msdn.microsoft.com/msdnmag/issues/06/05/MixAndMatch/default.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=31643b9e-124b-4a57-82c6-08acb6a09f5f"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,13f270f4-a0fb-4439-8467-0e56ec4d7aef.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,13f270f4-a0fb-4439-8467-0e56ec4d7aef.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In <a href="news://msnews.microsoft.com/microsoft.public.dotnet.languages.vc">news://msnews.microsoft.com/microsoft.public.dotnet.languages.vc</a> Edward
      Diener asked an <a href="news://msnews.microsoft.com/microsoft.public.dotnet.languages.vc">very
      interesting question</a>: Why can't I call a function having arguments of a native
      type like std::string from another assembly? 
   </p>
        <div>Assume you have some code like this one:
   </div>
        <div> 
   </div>
        <div>
          <div>
            <font face="Courier New">// Conversions.cpp</font>
          </div>
          <div>
            <font face="Courier New">// compile with "CL /clr /LD conversions.cpp"</font>
          </div>
          <div>
            <font face="Courier New">// output: mixed code assembly Conversions.dll</font>
          </div>
          <div>
            <font face="Courier New">#include &lt;string&gt;</font>
          </div>
          <div>
            <font face="Courier New">
            </font> 
      </div>
          <div>
            <font face="Courier New">public ref class Conversions<br />
         {<br />
         public:<br />
           static void S2S(System::String^ s1, std::string&amp; s2) { /* ... */ }<br />
         };</font>
          </div>
          <div> 
      </div>
        </div>
        <div>This code should compile as expected, however, it would not give you the expected
      result!
   </div>
        <div> 
   </div>
        <div>The code below looks like a suitable client:
   </div>
        <div> 
   </div>
        <div>
          <font face="Courier New">// ConversionsClient.cpp</font>
        </div>
        <div>
          <font face="Courier New">// compile with "CL /clr ConversionsClient.cpp"</font>
        </div>
        <div>
          <font face="Courier New">#using "Conversions.dll" </font>
        </div>
        <div>
          <font face="Courier New">#include &lt;string&gt;</font>
        </div>
        <div>
          <font face="Courier New">int main()<br />
      {<br />
        std::string s;<br />
        Conversions::S2S("asdf", s);<br />
      }</font>
        </div>
        <div>
          <div> 
      </div>
          <div>If you try to compile this code, you will get a disappointing error message: 
      </div>
          <div> 
      </div>
          <div>error C3767: 'Conversions::S2S': candidate function(s) not accessible
      </div>
          <div> 
      </div>
          <div>Why is a public static function S2S of a public type Convesions not accessible?
      </div>
          <div> 
      </div>
        </div>
        <div>To use the native type std::string in managed code, the compiler generates a managed
      value type std::string in the assembly where std::string is used. This managed wrapper
      value type is private, therefore, the Conversions::S2S cannot be called from
      outside the assembly even though it is a public function of a public type.
   </div>
        <div> 
   </div>
        <div>At the first view it seems, key to the solution is to make sure the compiler
      generates a public type for std::string, in theory this is possible, however it would
      not help to solve the problem. In fact the native wrapper type has been defined as
      a private type for some good reasons.
   </div>
        <div> 
   </div>
        <div>Assume the native wrapper type for std::string was public. To call S2S, one would
      have to pass a tracking handle to a System::String, defined in mscolib.dll, and a
      value of the type std::string defined in the assembly Conversions.dll. The std::string
      type that we pass in ConversionsClient.cpp is a different one! It is the native wrapper
      type defined in ConversionsClient.cpp - not the native wapper type defined in Conversions.dll.
      Therefore, the parameters would not match.
   </div>
        <div> 
   </div>
        <div>So how can we solve this problem?
   </div>
        <div> 
   </div>
        <div>The origin of the problem is the fact, that type identity rules of .NET do not
      allways mix well with the type identity rules of native C++. To solve this problem,
      you can switch back to the world of native code sharing without loosing you managed
      code features. Simply create a mixed code static library:
   </div>
        <div> 
   </div>
        <div>Create a static mixed code library from the code :
   </div>
        <div> 
   </div>
        <div>
          <div>
            <font face="Courier New">// ConversionsLib.cpp</font>
          </div>
          <div>
            <font face="Courier New">// compile with "CL /c /clr ConversionsLib.cpp"</font>
          </div>
          <div>
            <font face="Courier New">// make lib with "LIB ConversionsLib.obj"</font>
          </div>
          <div>
            <font face="Courier New">// output: mixed code static library ConversionsLib.lib</font>
          </div>
          <div>
            <font face="Courier New">
            </font> 
      </div>
          <div>
            <font face="Courier New">#include &lt;string&gt;</font>
          </div>
          <div>
            <font face="Courier New">void S2S(System::String^ s1, std::string&amp; s2) {
         /* ... */ }<br /></font>
          </div>
        </div>
        <div>Create a client from the code below.
   </div>
        <div> 
   </div>
        <div>
          <font face="Courier New">// ConversionsLibClient.cpp</font>
        </div>
        <div>
          <font face="Courier New">// compile with "CL /clr ConversionsLibClient.cpp"</font>
        </div>
        <div>
          <font face="Courier New">#include &lt;string&gt;</font>
        </div>
        <div>
          <font face="Courier New">
          </font> 
   </div>
        <div>
          <font face="Courier New">#pragma comment (lib, "ConversionsLib.lib")</font>
        </div>
        <div>
          <font face="Courier New">void S2S(System::String^ s1, std::string&amp; s2);</font>
        </div>
        <div>
          <font face="Courier New">
          </font> 
   </div>
        <div>
          <font face="Courier New">int main()<br />
      {<br />
        std::string s;<br />
        S2S("asdff", s);<br />
      }</font>
        </div>
        <div> 
   </div>
        <div>Conclusion: Beware the different type identity rules. Native types are identifies
      by their namespace-qualified typename, managed types are identified by their assembly-
      and namespace-qualifies typename. If you need native type identity rules, use native
      code sharing features, if you need managed type identity, use managed code sharing
      features.
   </div>
        <img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=13f270f4-a0fb-4439-8467-0e56ec4d7aef" />
      </body>
      <title>Mixed mode DLLs: Problem with public functions using native types as arguments</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,13f270f4-a0fb-4439-8467-0e56ec4d7aef.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,13f270f4-a0fb-4439-8467-0e56ec4d7aef.aspx</link>
      <pubDate>Tue, 21 Mar 2006 17:36:54 GMT</pubDate>
      <description>&lt;p&gt;
   In &lt;a href="news://msnews.microsoft.com/microsoft.public.dotnet.languages.vc"&gt;news://msnews.microsoft.com/microsoft.public.dotnet.languages.vc&lt;/a&gt;&amp;nbsp;Edward
   Diener asked an &lt;a href="news://msnews.microsoft.com/microsoft.public.dotnet.languages.vc"&gt;very
   interesting question&lt;/a&gt;: Why can't I call a function having arguments of a native
   type like std::string from another assembly? 
&lt;/p&gt;
&lt;div&gt;Assume you have some code like this one:
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;// Conversions.cpp&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;// compile with "CL /clr /LD conversions.cpp"&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;// output: mixed code assembly Conversions.dll&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;#include &amp;lt;string&amp;gt;&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;nbsp;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;public ref class Conversions&lt;br&gt;
      {&lt;br&gt;
      public:&lt;br&gt;
      &amp;nbsp; static void S2S(System::String^ s1, std::string&amp;amp; s2) { /* ... */ }&lt;br&gt;
      };&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&amp;nbsp;
   &lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;This code should compile as expected, however, it would not give you the expected
   result!
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;The code below looks like a suitable client:
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;// ConversionsClient.cpp&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;// compile with "CL /clr ConversionsClient.cpp"&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;#using "Conversions.dll"&amp;nbsp;&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;#include &amp;lt;string&amp;gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;int main()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; std::string s;&lt;br&gt;
   &amp;nbsp; Conversions::S2S("asdf", s);&lt;br&gt;
   }&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;
   &lt;div&gt;&amp;nbsp;
   &lt;/div&gt;
   &lt;div&gt;If you try to compile this code, you will get a disappointing error message: 
   &lt;/div&gt;
   &lt;div&gt;&amp;nbsp;
   &lt;/div&gt;
   &lt;div&gt;error C3767: 'Conversions::S2S': candidate function(s) not accessible
   &lt;/div&gt;
   &lt;div&gt;&amp;nbsp;
   &lt;/div&gt;
   &lt;div&gt;Why is a public static function S2S of a public type Convesions not accessible?
   &lt;/div&gt;
   &lt;div&gt;&amp;nbsp;
   &lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;To use the native type std::string in managed code, the compiler generates a&amp;nbsp;managed
   value type std::string in the assembly where std::string is used. This managed wrapper
   value type is private, therefore, the&amp;nbsp;Conversions::S2S cannot be called from
   outside the assembly even though it is a public function of a public type.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;At the first view it seems, key to the solution is to make sure the compiler
   generates a public type for std::string, in theory this is possible, however it would
   not help to solve the problem. In fact the native wrapper type has been defined as
   a private type for some good reasons.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;Assume the native wrapper type for std::string was public. To call S2S, one would
   have to pass a tracking handle to a System::String, defined in mscolib.dll, and a
   value of the type std::string defined in the assembly Conversions.dll. The std::string
   type that we pass in ConversionsClient.cpp is a different one! It is the native wrapper
   type defined in ConversionsClient.cpp - not the native wapper type defined in Conversions.dll.
   Therefore, the parameters would not match.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;So how can we solve this problem?
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;The origin of the problem is the fact, that type identity rules of .NET do not
   allways mix well with the type identity rules of native C++. To solve this problem,
   you can switch back to the world of native code sharing without loosing you managed
   code features. Simply create a mixed code static library:
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;Create a static mixed code library from the code :
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;// ConversionsLib.cpp&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;// compile with "CL /c /clr ConversionsLib.cpp"&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;// make lib with "LIB ConversionsLib.obj"&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;// output: mixed code static library&amp;nbsp;ConversionsLib.lib&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;nbsp;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;#include &amp;lt;string&amp;gt;&lt;/font&gt;
   &lt;/div&gt;
   &lt;div&gt;&lt;font face="Courier New"&gt;void S2S(System::String^ s1, std::string&amp;amp; s2) {
      /* ... */ }&lt;br&gt;
      &lt;/font&gt;
   &lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;Create a client from the code below.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;// ConversionsLibClient.cpp&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;// compile with "CL /clr ConversionsLibClient.cpp"&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;#include &amp;lt;string&amp;gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;#pragma comment (lib, "ConversionsLib.lib")&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;void S2S(System::String^ s1, std::string&amp;amp; s2);&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;&lt;font face="Courier New"&gt;int main()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; std::string s;&lt;br&gt;
   &amp;nbsp; S2S("asdff", s);&lt;br&gt;
   }&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;Conclusion: Beware the different type identity rules. Native types are identifies
   by their namespace-qualified typename, managed types are identified by their assembly-
   and namespace-qualifies typename. If you need native type identity rules, use native
   code sharing features, if you need managed type identity, use managed code sharing
   features.
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=13f270f4-a0fb-4439-8467-0e56ec4d7aef"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,589239d3-b21b-430e-911b-7b355eef8b63.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,589239d3-b21b-430e-911b-7b355eef8b63.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.mybadhairday.com/cppcliinstall.html">http://www.mybadhairday.com/cppcliinstall.html</a>
        </p>
        <img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=589239d3-b21b-430e-911b-7b355eef8b63" />
      </body>
      <title>Reflector Add-In for C++/CLI available</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,589239d3-b21b-430e-911b-7b355eef8b63.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,589239d3-b21b-430e-911b-7b355eef8b63.aspx</link>
      <pubDate>Fri, 20 Jan 2006 11:07:12 GMT</pubDate>
      <description>&lt;p&gt;
   &lt;a href="http://www.mybadhairday.com/cppcliinstall.html"&gt;http://www.mybadhairday.com/cppcliinstall.html&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=589239d3-b21b-430e-911b-7b355eef8b63"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      When a cpp file is compiled with /clr, a managed object file is created. In most scenarios,
      such a managed object file contains only managed code. However, there are two scenarios
      that end up in a managed object file with managed and native code:
   </p>
        <ol>
          <li>
         When #pragma unmanaged is used 
      </li>
          <li>
         When the C++ file contains a function with C++ constructs that are not mappable to
         IL code.</li>
        </ol>
        <p>
      Managed object files with native code imply a certain danger: They can end up in uninitialized
      state, as shown in the following sample:
   </p>
        <p>
      In the code below, i is a global variable initialized with the return value of getValue().
      There are two exported functions that simply return i. One is the managed function
      fManaged and the other one is the unmanaged function fUnmanaged.<br /></p>
        <p>
          <font face="Courier New">&lt;code language=”C++/CLI” filename=”MixedLib.cpp” compileWith=”CL
      /LD /clr MixedLib.cpp”&gt;<br />
      #pragma unmanaged<br />
      __declspec(noinline) int getValue() {<br />
        return 42;<br />
      }</font>
        </p>
        <p>
          <font face="Courier New">int i = getValue();</font>
        </p>
        <p>
          <font face="Courier New">__declspec(dllexport) int fUnmanaged()<br />
      {<br />
        return i;<br />
      }</font>
        </p>
        <p>
          <font face="Courier New">#pragma managed<br />
      __declspec(dllexport) int fManaged()<br />
      {<br />
        return i;<br />
      }<br />
      &lt;/code&gt;</font>
        </p>
        <p>
      Before fManaged is executed the first time, the module constructor is called. The
      module constructor calls getValue to initialize the global variable i. However, if
      fUnmanaged is called before fManaged is called the first time, the variable i will
      be returned before it is initialized. To reproduce this scenario, you can use the
      client application below.
   </p>
        <p>
          <font face="Courier New">&lt;code language=”C++/CLI” filename=”TestApp.cpp” compileWith=”CL
      /clr TestApp.cpp”&gt;<br />
      #include &lt;stdio.h&gt;</font>
        </p>
        <p>
          <font face="Courier New">#pragma comment(lib, "testlib.lib")</font>
        </p>
        <p>
          <font face="Courier New">__declspec(dllimport) int fUnmanaged();<br />
      __declspec(dllimport) int fManaged();</font>
        </p>
        <p>
          <font face="Courier New">int main()<br />
      {<br />
        printf("fUnmanaged returns %d\n", fUnmanaged());<br />
        printf("fManaged returns %d\n", fManaged());<br />
        printf("fUnmanaged returns %d\n", fUnmanaged());<br />
      }<br />
      &lt;/code&gt;</font>
        </p>
        <p>
      If you start TestApp.exe, you will get the following output:
   </p>
        <p>
      fUnmanaged returns 0<br />
      fManaged returns 42<br />
      fUnmanaged returns 42
   </p>
        <p>
      The easiest way to avoid these problems is to make sure that files compiled with /clr
      contain only managed code and to leave the native code in cpp files compiled without
      /clr. If you consider using #pragma unmanaged or unmappable C++ constructs in files
      compiled with /clr, you should be aware that all global variables and static member
      variables of that file, are initialized by the module initializer. This is even true
      if the variable is of a native type.
   </p>
        <p>
      The compiler's ability to automatically compile a function with unmappable C++ constructs
      to native code can cause a scenario where you get mixed code object files without
      even realizing it. Fortunately a compiler warning C4793 can be emitted in this scenario.
      C4793 is a level 2 warning. To get it, you either have to set the warning level to
      2, or you have to use a compiler switch to make it a level 1 warning, as shown in
      the following code.
   </p>
        <p>
          <font face="Courier New">&lt;code language="C++/CLI" 
      <br />
           filename=" UnmappableConstructs.cpp" 
      <br />
           compileWith="cl /c /clr /w14793 UnmappableConstructs.cpp"&gt;<br />
      void f()<br />
      {<br />
        __asm int 3;<br />
      }<br />
      &lt;/code&gt;</font>
        </p>
        <p>
      When you compile this code, the C++ compiler will emit the warning C4793 with the
      following message:
   </p>
        <p>
      UnmappableConstructs.cpp(3) : warning C4793: '__asm' : causes native code generation
      for function 'void f(void)'<br />
              UnmappableConstructs.cpp(1) : see declaration
      of 'f'<br /></p>
        <img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e" />
      </body>
      <title>Avoid native code in managed object files (".obj" files)</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e.aspx</link>
      <pubDate>Thu, 12 Jan 2006 15:29:45 GMT</pubDate>
      <description>&lt;p&gt;
   When a cpp file is compiled with /clr, a managed object file is created. In most scenarios,
   such a managed object file contains only managed code. However, there are two scenarios
   that end up in a managed object file with managed and native code:
&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;
      When #pragma unmanaged is used 
   &lt;li&gt;
      When the C++ file contains a function with C++ constructs that are not mappable to
      IL code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
   Managed object files with native code imply a certain danger: They can end up in uninitialized
   state, as shown in the following sample:
&lt;/p&gt;
&lt;p&gt;
   In the code below, i is a global variable initialized with the return value of getValue().
   There are two exported functions that simply return i. One is the managed function
   fManaged and the other one is the unmanaged function fUnmanaged.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;&amp;lt;code language=”C++/CLI” filename=”MixedLib.cpp” compileWith=”CL
   /LD /clr MixedLib.cpp”&amp;gt;&lt;br&gt;
   #pragma unmanaged&lt;br&gt;
   __declspec(noinline) int getValue() {&lt;br&gt;
   &amp;nbsp; return 42;&lt;br&gt;
   }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;int i = getValue();&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;__declspec(dllexport) int fUnmanaged()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; return i;&lt;br&gt;
   }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;#pragma managed&lt;br&gt;
   __declspec(dllexport) int fManaged()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; return i;&lt;br&gt;
   }&lt;br&gt;
   &amp;lt;/code&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   Before fManaged is executed the first time, the module constructor is called. The
   module constructor calls getValue to initialize the global variable i. However, if
   fUnmanaged is called before fManaged is called the first time, the variable i will
   be returned before it is initialized. To reproduce this scenario, you can use the
   client application below.
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;&amp;lt;code language=”C++/CLI” filename=”TestApp.cpp” compileWith=”CL
   /clr TestApp.cpp”&amp;gt;&lt;br&gt;
   #include &amp;lt;stdio.h&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;#pragma comment(lib, "testlib.lib")&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;__declspec(dllimport) int fUnmanaged();&lt;br&gt;
   __declspec(dllimport) int fManaged();&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;int main()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; printf("fUnmanaged returns %d\n", fUnmanaged());&lt;br&gt;
   &amp;nbsp; printf("fManaged returns %d\n", fManaged());&lt;br&gt;
   &amp;nbsp; printf("fUnmanaged returns %d\n", fUnmanaged());&lt;br&gt;
   }&lt;br&gt;
   &amp;lt;/code&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   If you start TestApp.exe, you will get the following output:
&lt;/p&gt;
&lt;p&gt;
   fUnmanaged returns 0&lt;br&gt;
   fManaged returns 42&lt;br&gt;
   fUnmanaged returns 42
&lt;/p&gt;
&lt;p&gt;
   The easiest way to avoid these problems is to make sure that files compiled with /clr
   contain only managed code and to leave the native code in cpp files compiled without
   /clr. If you consider using #pragma unmanaged or unmappable C++ constructs in files
   compiled with /clr, you should be aware that all global variables and static member
   variables of that file, are initialized by the module initializer. This is even true
   if the variable is of a native type.
&lt;/p&gt;
&lt;p&gt;
   The compiler's ability to automatically compile a function with unmappable C++ constructs
   to native code can cause a scenario where you get mixed code object files without
   even realizing it. Fortunately a compiler warning C4793 can be emitted in this scenario.
   C4793 is a level 2 warning. To get it, you either have to set the warning level to
   2, or you have to use a compiler switch to make it a level 1 warning, as shown in
   the following code.
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;&amp;lt;code language="C++/CLI" 
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; filename=" UnmappableConstructs.cpp" 
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; compileWith="cl /c /clr /w14793 UnmappableConstructs.cpp"&amp;gt;&lt;br&gt;
   void f()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; __asm int 3;&lt;br&gt;
   }&lt;br&gt;
   &amp;lt;/code&amp;gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   When you compile this code, the C++ compiler will emit the warning C4793 with the
   following message:
&lt;/p&gt;
&lt;p&gt;
   UnmappableConstructs.cpp(3) : warning C4793: '__asm' : causes native code generation
   for function 'void f(void)'&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UnmappableConstructs.cpp(1) : see declaration
   of 'f'&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,8d076332-4fb0-44b5-a829-4c4d653de2d6.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,8d076332-4fb0-44b5-a829-4c4d653de2d6.aspx</pingback:target>
      <title>Interesting new feature in .NET: Type identity mapping.</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,8d076332-4fb0-44b5-a829-4c4d653de2d6.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,8d076332-4fb0-44b5-a829-4c4d653de2d6.aspx</link>
      <pubDate>Sat, 26 Nov 2005 11:06:15 GMT</pubDate>
      <description>&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;.NET
   has a very interesting new feature regarding type identity. When I tested this feature
   the last time (I think it was with the RC, it did not work, so it is likely you have
   not yet heared about it). But let's start from the beginning:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Type
   identity is a very important concept of a programming infrastructure. In classic C++,
   types are identified by their names. COM uses GUIDs to identitfy types. To achieve
   a strong type safety, type identity in .NET is bound to assembly identity and assembly
   identity can be bound to developers using a public/private key pair. Type identity
   is bound to assembly identity means that 2 types with the same name in two different
   assemblies have two different identities. Assembly identity can be bound to developers
   using a public/private key pair means that developers can&amp;nbsp;use unique public/private
   key pairs to give their assemblies unique and uncloneable names. This also gives all
   types in the assembly unique and uncloneable names.&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;The
   following expression&amp;nbsp;returns a string containing the unique and uncloneable type
   identity, Microsoft has given to the 32 bit signed integer type:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;int::typeid-&amp;gt;AssemblyQualifiedName&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;If
   you are not familiar with the chosen language, the equivalent C# expression would
   be &lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;typeof(int).AssemblyQualifiedName&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;.&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;While
   this type identity is very helpful to achieve verifiability, it is also had a drawback:
   This assembly bound type identity ment that a type&amp;nbsp;could not leave the assembly
   where it was defined in without losing it's identity. You can define a type from exactly
   the same code in another assembly, but to the runtime, it would be a different type.
   To understand this, let's have a look at the following example.&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Let's
   assume you have an assembly lib1.dll created from the following code:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;public
   ref class TheType {};&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Let's
   further assume, you have a client application like this one:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;#using
   "lib1.dll"&lt;br&gt;
   int main() {&lt;br&gt;
   &amp;nbsp; using namespace System;&lt;br&gt;
   &amp;nbsp; Console::WriteLine(TheType().GetType()-&amp;gt;AssemblyQualifiedName);&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;&amp;nbsp;
   using System::Reflection::Assembly;&lt;br&gt;
   &amp;nbsp; for each (Assembly^ a in AppDomain::CurrentDomain-&amp;gt;GetAssemblies())&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; Console::WriteLine(a-&amp;gt;FullName); 
   &lt;br&gt;
   }&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Notice
   the elegant way to add an assembly reference inside your code, and the neat alternative
   for creating a temporary object of type TheType - two out of so many reasons why I
   call C++/CLI the &lt;em&gt;&lt;span style="FONT-FAMILY: Verdana"&gt;chosen&lt;/span&gt;&lt;/em&gt; language.&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;If
   you run the application, you will see that TheType is defined in Lib1 and that the
   assemblies mscorlib, app, and lib1 are loaded.&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Let's
   further assume that for the next version, you are&amp;nbsp;redesigning your application
   and you find out, that TheType would now better fit into another assembly. Due to
   the type identity rules I have mentioned, this would mean that TheType would get another
   identity.&amp;nbsp;Therefore this would be a breaking change for lib1.dll: The new version
   of Lib1 would not be backwards compatible with the old one, since it didn't have the
   public type TheType any more.&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Using
   the type identity mapping feature in 2.0, you can reorganize your libraries without
   causing a backwards incompatibility in your new lib1.dll. To&amp;nbsp;explain the mechanics,
   let's assume&amp;nbsp;the source for lib2.dll now contains &lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;TheType&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;//lib2.cs&lt;br&gt;
   public ref&amp;nbsp;class TheType {};&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;To
   allow the old version of app.exe to execute even though &lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;TheType&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;&amp;nbsp;is
   no longer in the assembly where it is expected (lib1), you&amp;nbsp;can define &lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;TheType&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;&amp;nbsp;in
   lib1.dll with a type identity mapping to the type in lib2.dll. These two lines are
   enough to achieve this:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;#using
   "lib2.dll"&lt;br&gt;
   [assembly: TypeForwardedTo(TheType::typeid)];&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Notice
   that this code creates lib1.dll with an assembly depencency to lib2.dll that defines &lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;TheType&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;. &lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;When
   using this code, the compiler emits the folowing metadata for &lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;TheType&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt; in
   lib1.dll:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;.class
   extern forwarder TheType&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; .assembly extern lib2&lt;br&gt;
   &amp;nbsp; .class 0x02000002&lt;br&gt;
   }&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;.class
   0x02000002&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt; is
   to the metadata token for TheType in lib2.dll.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Almost
   the same metadata can be&amp;nbsp;emitted by C#, too; however there is a slight difference:&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;&lt;font face="Courier New"&gt;[assembly:
   System.Runtime.CompilerServices.TypeForwardedTo(typeof(TheType))]&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;C#
   expects you to use the pseudo custom attribute System::Runtime::CompilerServices::TypeForwardedToAttribute,
   whereas C++/CLI uses a compiler-internal attriubte TypeForwardedTo. The philosophies
   of the two languages differ here: C# tries to be consistent in the way attributes
   are used. Regarding attributes,&amp;nbsp;C++/CLI has different roots anyway:&amp;nbsp;.NET
   attributes are, attributed ATL are two examples. Instead of trying to be consistent
   with one or the other attribute model, C++/CLI tries to avoid that the programmer
   has to explicitly use features of the runtime that are intended to be used by compiler
   builders only.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-GB"&gt;Whatever
   language you use, this simple attribute allows you to reorganize your libraries without
   breaking compatibility with old applications.&lt;/span&gt;&lt;span lang=EN-GB style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=8d076332-4fb0-44b5-a829-4c4d653de2d6"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,65c852a9-3735-4e48-90c7-8c76003d28c5.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,65c852a9-3735-4e48-90c7-8c76003d28c5.aspx</pingback:target>
      <title>How to use app.config files in Visual C++ 2005 projects</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,65c852a9-3735-4e48-90c7-8c76003d28c5.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,65c852a9-3735-4e48-90c7-8c76003d28c5.aspx</link>
      <pubDate>Fri, 11 Nov 2005 23:34:30 GMT</pubDate>
      <description>&lt;p&gt;
   &lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;For
   most Visual Studio .NET language integrations, app.config files are treated specially.
   Before the target application is started, (with or without a debug session), the language
   package ensures that the app.config file is automaticallly copied to the target application's
   configuration file. Visual C++ does not have this feature, however it is easy to get
   the same:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;Add
   a file named app.coinfig to a Visial C++ project and choose the following project
   settings:&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;Command
   line: type app.config &lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;&amp;gt;&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt; "$(TargetPath).config"&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;Description:
   "Updating target's configuration file"&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;Outputs:
   "(TargetPath).config"&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: #003300; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;Notice
   that the file is copied via the command type and piping. I prefer this to using the
   copy command here, sbecause this command ensures that the date of the compiled file
   is automatically adapted whenever the file is copied.&lt;/span&gt;&lt;span lang=EN-US style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Verdana; mso-ansi-language: EN-US"&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
   &lt;span lang=EN-US style="mso-ansi-language: EN-US"&gt;
   &lt;o:p&gt;
      &lt;font face="Times New Roman" color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=65c852a9-3735-4e48-90c7-8c76003d28c5"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,48daf2ff-41c8-4312-9d80-bdfa8c55058d.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,48daf2ff-41c8-4312-9d80-bdfa8c55058d.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      On <a href="news:microsoft.public.dotnet.languages.vc">microsoft.public.dotnet.languages.vc</a>,
      bonk has asked this interesting question. This blog entry gives you a simple example
      and explains why this is possible. In further blogs I will discuss when this
      can be dangerous.
   </p>
        <p>
      Your idea is possible, but there may be some issues. Let's start with a simple sample
   </p>
        <p>
      &lt;code language="CPPCLI" file="test.cpp" compileWith="CL /LD /clr test.cpp"&gt;<br />
      // pragma managed is the default 
      <br />
      extern "C" __declspec(dllexport) void __stdcall f() 
      <br />
      {<br />
        System::Console::WriteLine("I am f(), a managed function that test.dll exports
      to native clients");<br />
      }<br />
      &lt;/code&gt;
   </p>
        <p>
      "dumpbin /exports test.dll" will show you that there is indeed a native exported function:
   </p>
        <p>
          ordinal hint RVA      name
   </p>
        <p>
                1    0 00001020
      _f@0
   </p>
        <p>
      What is going on here? How can unmanaged code can call managed code?
   </p>
        <p>
      To answer this question, let's have a look at a simple application that calls managed
      code from unmanaged code:
   </p>
        <p>
      &lt;code language="CPPCLI" file="testApp.cpp" compileWith="CL /clr testapp.cpp"&gt;<br />
      void f() 
      <br />
      {<br />
        System::Console::WriteLine("I am f(), a managed function that can be called
      by native clients");<br />
      }
   </p>
        <p>
      void f2() 
      <br />
      {<br />
        System::Console::WriteLine("I am f2(), a managed function that can be called
      by native clients");<br />
      }
   </p>
        <p>
      #pragma unmanaged<br />
      int main() {<br />
        f();<br />
        f2();<br />
      }<br />
      &lt;/code&gt;
   </p>
        <p>
      The native function main can not call f  without some magic that is going on
      under the hood: Think of a scenario, where f has not even been jit compiled. On the
      one hand, the call "f()" is compiled to a call to an address local to the exe file,
      on the other hand, the code that should really be executed, is JIT compiled. So what
      is going on here?
   </p>
        <p>
      "f()" and "f2()" are indeed calls a local addresses. This is an excerpt from the disassembly
      window:
   </p>
        <p>
        f();<br />
      00401053  call        f (401030h) 
      <br />
        f2();<br />
      00401058  call        f2 (401040h) 
   </p>
        <p>
      Notice that the calling addresses (00401053) and the called addresses (401030) are
      both belong to testApp.exe's code.
   </p>
        <p>
      Here is what the disassembly window tells us about the called addresses:
   </p>
        <p>
      f:<br />
      00401030  jmp         dword ptr [__mep@?f@@$$FYAXXZ
      (409000h)] 
   </p>
        <p>
      f2:<br />
      00401040  jmp         dword ptr [__mep@?f2@@$$FYAXXZ
      (409004h)] 
   </p>
        <p>
      "jmp dword ptr [...x...]" is an indirect jump. It means: at the address ...x..., is
      the address the address you have to jump to.
   </p>
        <p>
      Here is what these addresses are in my debugger's memory window:<br />
      0x00409000:  00 CB 00 12<br />
      0x00409004:  00 CB 00 4E
   </p>
        <p>
      Both addresses are far away from testApp.exe's base address, so they are clearly outside
      testApp's code. This is runtime generated code, but we have not yet reached JIT compiled
      code. What we see here are runtime generated unmanaged -&gt; managed thunks. These
      thunks perform the managed / unmanaged transition call the managed functions (f, or
      f2) in the end.
   </p>
        <p>
      As I have mentioned, these functions are runtime generated: How does the runtime know
      that at address 0x00409000 should be a pointer to the unmanaged -&gt; managed thunk
      for f() and at address 0x00409004 should be a pointer to the thunk for f2()?
   </p>
        <p>
      Well the new linker is much smarter than you may expect: The linker generates .NET
      metadata that tells the runtime exactly that! If you view testApp.exe in ILDASM and
      inspect the assembly's manifest, you will find so called vtFixups at the end of the
      manifest. Here is an expert:
   </p>
        <p>
      .imagebase 0x00400000<br />
      .subsystem 0x0003       // WINDOWS_CUI<br />
      .corflags 0x00000000<br />
      .vtfixup [1] int32 retainappdomain at D_00009000 // 06000001<br />
      .vtfixup [1] int32 retainappdomain at D_00009004 // 06000002<br />
      ...many other vtfixups elided for clarity here ...
   </p>
        <p>
      Note that these lines contain familiar numbers: 00009000 and 00009004. If you add
      the .imagebase to these numbers, you will get:
   </p>
        <p>
      00409000 and 00409004. Does this ring the bell? Using these addresses, the compiled
      code finds the managed -&gt; unmanaged thunks.
   </p>
        <p>
      So what is the other part of the vtfixup 06000001 and 06000002?
   </p>
        <p>
      Well these are metadata tokens. Metadata starting with the 06 are always method tokens
      and now it is not very difficult to guess what is going on: 06000001 is the metadata
      token for the managed function f() and 06000002 is the metatdata token for f2(). You
      can prove this by adding the following code to f() and f2():
   </p>
        <p>
      System::Console::WriteLine("{0:x8}", (gcnew System::Diagnostics::StackTrace())-&gt;GetFrame(0)-&gt;GetMethod()-&gt;MetadataToken);
   </p>
        <p>
      The .vtfixup metadata tells the runtime: 
      <br />
      When the assembly is loaded:<br />
        Generate a unmanaged-&gt;managed thunk for the method f() and store a pointer
      to it in 00409000 and<br />
        generate another unmanaged-&gt;managed thunk for method f2() and store a pointer
      to it in 00409004.
   </p>
        <p>
      Since this is done, the unmanaged function main can call the managed functions f and
      f2 as if they were native functions.
   </p>
        <p>
      In the testApp.exe sample there is a simplification, that is not true for the test.dll
      I have disused right at the beginning: Since testApp.exe is an exe it is guaranteed
      that the CLR has been initialized already. (The CLR will be initialized automatically
      when the EXE application starts.) This assumption is not true for managed functions
      exported via DLLs: The DLL's client may be a native client. To handle this case, a
      small stub is exported. This small stub ensures that the CLR is initialized properly
      and that the assembly is loaded properly into the default appdomain, before the unmanaged
      -&gt; managed stub is called. This is often called delayed CLR initialization.
   </p>
        <p>
      Although all this sounds nice there are still some things to discuss:
   </p>
        <p>
      * Issues when combining exported managed functions with #pragma managed
   </p>
        <p>
      * Turning the generation of managed / unmanaged thunks off in cases where they are
      not needed
   </p>
        <p>
      * What happens if managed code calls a managed entry point via P/Invoke?
   </p>
        <p>
      I hope I will find some time to discuss these things in the next days.
   </p>
        <p>
       
   </p>
        <img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=48daf2ff-41c8-4312-9d80-bdfa8c55058d" />
      </body>
      <title>Can DLLs export managed functions to native clients?</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,48daf2ff-41c8-4312-9d80-bdfa8c55058d.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,48daf2ff-41c8-4312-9d80-bdfa8c55058d.aspx</link>
      <pubDate>Wed, 19 Oct 2005 21:58:59 GMT</pubDate>
      <description>&lt;p&gt;
   On &lt;a href="news:microsoft.public.dotnet.languages.vc"&gt;microsoft.public.dotnet.languages.vc&lt;/a&gt;,
   bonk has asked this interesting question. This blog entry gives you a simple example
   and explains why this is possible. In further blogs I will&amp;nbsp;discuss when this
   can be dangerous.
&lt;/p&gt;
&lt;p&gt;
   Your idea is possible, but there may be some issues. Let's start with a simple sample
&lt;/p&gt;
&lt;p&gt;
   &amp;lt;code language="CPPCLI" file="test.cpp" compileWith="CL /LD /clr test.cpp"&amp;gt;&lt;br&gt;
   // pragma managed is the default 
   &lt;br&gt;
   extern "C" __declspec(dllexport) void __stdcall f() 
   &lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; System::Console::WriteLine("I am f(), a managed function that test.dll exports
   to native clients");&lt;br&gt;
   }&lt;br&gt;
   &amp;lt;/code&amp;gt;
&lt;/p&gt;
&lt;p&gt;
   "dumpbin /exports test.dll" will show you that there is indeed a native exported function:
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; ordinal hint RVA&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 00001020
   _f@0
&lt;/p&gt;
&lt;p&gt;
   What is going on here? How can unmanaged code can call managed code?
&lt;/p&gt;
&lt;p&gt;
   To answer this question, let's have a look at a simple application that calls managed
   code from unmanaged code:
&lt;/p&gt;
&lt;p&gt;
   &amp;lt;code language="CPPCLI" file="testApp.cpp" compileWith="CL /clr testapp.cpp"&amp;gt;&lt;br&gt;
   void f() 
   &lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; System::Console::WriteLine("I am f(), a managed function that can be called
   by native clients");&lt;br&gt;
   }
&lt;/p&gt;
&lt;p&gt;
   void f2() 
   &lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; System::Console::WriteLine("I am f2(), a managed function that can be called
   by native clients");&lt;br&gt;
   }
&lt;/p&gt;
&lt;p&gt;
   #pragma unmanaged&lt;br&gt;
   int main() {&lt;br&gt;
   &amp;nbsp; f();&lt;br&gt;
   &amp;nbsp; f2();&lt;br&gt;
   }&lt;br&gt;
   &amp;lt;/code&amp;gt;
&lt;/p&gt;
&lt;p&gt;
   The native function main can not call f&amp;nbsp; without some magic that is going on
   under the hood: Think of a scenario, where f has not even been jit compiled. On the
   one hand, the call "f()" is compiled to a call to an address local to the exe file,
   on the other hand, the code that should really be executed, is JIT compiled. So what
   is going on here?
&lt;/p&gt;
&lt;p&gt;
   "f()" and "f2()" are indeed calls a local addresses. This is an excerpt from the disassembly
   window:
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp; f();&lt;br&gt;
   00401053&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f (401030h) 
   &lt;br&gt;
   &amp;nbsp; f2();&lt;br&gt;
   00401058&amp;nbsp; call&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f2 (401040h) 
&lt;/p&gt;
&lt;p&gt;
   Notice that the calling addresses (00401053) and the called addresses (401030) are
   both belong to testApp.exe's code.
&lt;/p&gt;
&lt;p&gt;
   Here is what the disassembly window tells us about the called addresses:
&lt;/p&gt;
&lt;p&gt;
   f:&lt;br&gt;
   00401030&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dword ptr [__mep@?f@@$$FYAXXZ
   (409000h)] 
&lt;/p&gt;
&lt;p&gt;
   f2:&lt;br&gt;
   00401040&amp;nbsp; jmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dword ptr [__mep@?f2@@$$FYAXXZ
   (409004h)] 
&lt;/p&gt;
&lt;p&gt;
   "jmp dword ptr [...x...]" is an indirect jump. It means: at the address ...x..., is
   the address the address you have to jump to.
&lt;/p&gt;
&lt;p&gt;
   Here is what these addresses are in my debugger's memory window:&lt;br&gt;
   0x00409000:&amp;nbsp; 00 CB 00 12&lt;br&gt;
   0x00409004:&amp;nbsp; 00 CB 00 4E
&lt;/p&gt;
&lt;p&gt;
   Both addresses are far away from testApp.exe's base address, so they are clearly outside
   testApp's code. This is runtime generated code, but we have not yet reached JIT compiled
   code. What we see here are runtime generated unmanaged -&amp;gt; managed thunks. These
   thunks perform the managed / unmanaged transition call the managed functions (f, or
   f2) in the end.
&lt;/p&gt;
&lt;p&gt;
   As I have mentioned, these functions are runtime generated: How does the runtime know
   that at address 0x00409000 should be a pointer to the unmanaged -&amp;gt; managed thunk
   for f() and at address 0x00409004 should be a pointer to the thunk for f2()?
&lt;/p&gt;
&lt;p&gt;
   Well the new linker is much smarter than you may expect: The linker generates .NET
   metadata that tells the runtime exactly that! If you view testApp.exe in ILDASM and
   inspect the assembly's manifest, you will find so called vtFixups at the end of the
   manifest. Here is an expert:
&lt;/p&gt;
&lt;p&gt;
   .imagebase 0x00400000&lt;br&gt;
   .subsystem 0x0003&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // WINDOWS_CUI&lt;br&gt;
   .corflags 0x00000000&lt;br&gt;
   .vtfixup [1] int32 retainappdomain at D_00009000 // 06000001&lt;br&gt;
   .vtfixup [1] int32 retainappdomain at D_00009004 // 06000002&lt;br&gt;
   ...many other vtfixups elided for clarity here ...
&lt;/p&gt;
&lt;p&gt;
   Note that these lines contain familiar numbers: 00009000 and 00009004. If you add
   the .imagebase to these numbers, you will get:
&lt;/p&gt;
&lt;p&gt;
   00409000 and 00409004. Does this ring the bell? Using these addresses, the compiled
   code finds the managed -&amp;gt; unmanaged thunks.
&lt;/p&gt;
&lt;p&gt;
   So what is the other part of the vtfixup 06000001 and 06000002?
&lt;/p&gt;
&lt;p&gt;
   Well these are metadata tokens. Metadata starting with the 06 are always method tokens
   and now it is not very difficult to guess what is going on: 06000001 is the metadata
   token for the managed function f() and 06000002 is the metatdata token for f2(). You
   can prove this by adding the following code to f() and f2():
&lt;/p&gt;
&lt;p&gt;
   System::Console::WriteLine("{0:x8}", (gcnew System::Diagnostics::StackTrace())-&amp;gt;GetFrame(0)-&amp;gt;GetMethod()-&amp;gt;MetadataToken);
&lt;/p&gt;
&lt;p&gt;
   The .vtfixup metadata tells the runtime: 
   &lt;br&gt;
   When the assembly is loaded:&lt;br&gt;
   &amp;nbsp; Generate a unmanaged-&amp;gt;managed thunk for the method f() and store a pointer
   to it in 00409000 and&lt;br&gt;
   &amp;nbsp; generate another unmanaged-&amp;gt;managed thunk for method f2() and store a pointer
   to it in 00409004.
&lt;/p&gt;
&lt;p&gt;
   Since this is done, the unmanaged function main can call the managed functions f and
   f2 as if they were native functions.
&lt;/p&gt;
&lt;p&gt;
   In the testApp.exe sample there is a simplification, that is not true for the test.dll
   I have disused right at the beginning: Since testApp.exe is an exe it is guaranteed
   that the CLR has been initialized already. (The CLR will be initialized automatically
   when the EXE application starts.) This assumption is not true for managed functions
   exported via DLLs: The DLL's client may be a native client. To handle this case, a
   small stub is exported. This small stub ensures that the CLR is initialized properly
   and that the assembly is loaded properly into the default appdomain, before the unmanaged
   -&amp;gt; managed stub is called. This is often called delayed CLR initialization.
&lt;/p&gt;
&lt;p&gt;
   Although all this sounds nice there are still some things to discuss:
&lt;/p&gt;
&lt;p&gt;
   * Issues when combining exported managed functions with #pragma managed
&lt;/p&gt;
&lt;p&gt;
   * Turning the generation of managed / unmanaged thunks off in cases where they are
   not needed
&lt;/p&gt;
&lt;p&gt;
   * What happens if&amp;nbsp;managed code calls a managed entry point via P/Invoke?
&lt;/p&gt;
&lt;p&gt;
   I hope I will find some time to discuss these things in the next days.
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=48daf2ff-41c8-4312-9d80-bdfa8c55058d"&gt;</description>
    </item>
    <item>
      <trackback:ping>http://www.heege.net/blog/Trackback,guid,e998baf7-390f-4d59-bbd1-fc5c1adbec2f.aspx</trackback:ping>
      <pingback:server>http://www.heege.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.heege.net/blog/PermaLink,guid,e998baf7-390f-4d59-bbd1-fc5c1adbec2f.aspx</pingback:target>
      <body xmlns="http://www.w3.org/1999/xhtml">A long time of research will come
   to an end soon. I have spent the last months writing the <a href="http://www.develop.com/training/course.aspx?id=323">Essential
   C++/CLI class</a> for <a href="http://www.develop.com/">DevelopMentor</a>. I still
   have 8 labs to write and some slides need a redesign, but at least I am able to spend
   some time sharing important details about C++/CLI, "It Just Works", and .NET in General.<img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=e998baf7-390f-4d59-bbd1-fc5c1adbec2f" /></body>
      <title>My Essential C++/CLI Seminar</title>
      <guid>http://www.heege.net/blog/PermaLink,guid,e998baf7-390f-4d59-bbd1-fc5c1adbec2f.aspx</guid>
      <link>http://www.heege.net/blog/PermaLink,guid,e998baf7-390f-4d59-bbd1-fc5c1adbec2f.aspx</link>
      <pubDate>Wed, 19 Oct 2005 20:39:05 GMT</pubDate>
      <description>A long time of research&amp;nbsp;will come to an end soon. I have spent the last months writing the &lt;a href="http://www.develop.com/training/course.aspx?id=323"&gt;Essential
C++/CLI class&lt;/a&gt; for &lt;a href="http://www.develop.com/"&gt;DevelopMentor&lt;/a&gt;. I still
have 8 labs to write and some slides need a redesign, but at least I am able to spend
some time sharing important details about C++/CLI, "It Just Works", and .NET in General.&lt;img width="0" height="0" src="http://www.heege.net/blog/aggbug.ashx?id=e998baf7-390f-4d59-bbd1-fc5c1adbec2f"&gt;</description>
    </item>
  </channel>
</rss>
