<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.3" xml:lang="en-us" xmlns="http://purl.org/atom/ns#">
  <title>Marcus' Blog</title>
  <link rel="alternate" type="text/html" href="http://www.heege.net/blog/" />
  <modified>2009-10-15T22:40:45.2647667+02:00</modified>
  <tagline>Random thoughts about C++/CLI, .NET/Native interop and other topics</tagline>
  <generator>newtelligence dasBlog 1.7.5016.2</generator>
  <author>
    <name>Marcus Heege</name>
  </author>
  <entry>
    <title>Sandboxed execution and performance</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,ae4f5285-9d04-4999-9765-1d7fcf6b2da2.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,ae4f5285-9d04-4999-9765-1d7fcf6b2da2.aspx</id>
    <issued>2009-10-15T22:40:45.2647667+02:00</issued>
    <modified>2009-10-15T22:40:45.2647667+02:00</modified>
    <created>2009-10-15T22:40:45.2647667+02:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
  <entry>
    <title>Dangers of /clr and /clr:pure in sandboxed execution scenarios: Thread-promotion can bypass the sandbox!</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,62340fe1-8ab5-443a-b49e-2b37bbf15c24.aspx</id>
    <issued>2009-10-09T18:53:23.2503777+02:00</issued>
    <modified>2009-10-09T18:53:23.2503777+02:00</modified>
    <created>2009-10-09T18:53:23.2503777+02:00</created>
  </entry>
  <entry>
    <title>Deploying native DLLs with managed wrapper assemblies into the GAC</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,d3b405c1-73d4-4d04-934f-3e2ee2b5f589.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,d3b405c1-73d4-4d04-934f-3e2ee2b5f589.aspx</id>
    <issued>2009-09-30T18:47:19.7309050+02:00</issued>
    <modified>2009-10-05T08:45:47.3604172+02:00</modified>
    <created>2009-09-30T18:47:19.7309050+02:00</created>
  </entry>
  <entry>
    <title>Marshalling native function pointers</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,94167d73-7954-4a5c-a745-dc60d352cdef.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,94167d73-7954-4a5c-a745-dc60d352cdef.aspx</id>
    <issued>2007-04-06T11:13:08.0994309+02:00</issued>
    <modified>2007-04-06T19:49:53.4792009+02:00</modified>
    <created>2007-04-06T11:13:08.0994309+02:00</created>
  </entry>
  <entry>
    <title>Finishing my book</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,0440bf0e-243d-4900-a81f-16aee3f4b89c.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,0440bf0e-243d-4900-a81f-16aee3f4b89c.aspx</id>
    <issued>2007-01-13T10:00:07.0903469+01:00</issued>
    <modified>2007-01-13T10:00:07.0903469+01:00</modified>
    <created>2007-01-13T10:00:07.0903469+01:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
  <entry>
    <title>Some personal things</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,31643b9e-124b-4a57-82c6-08acb6a09f5f.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,31643b9e-124b-4a57-82c6-08acb6a09f5f.aspx</id>
    <issued>2006-04-11T14:15:43.9646878+02:00</issued>
    <modified>2006-04-11T18:21:12.7021341+02:00</modified>
    <created>2006-04-11T14:15:43.9646878+02:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
  <entry>
    <title>Mixed mode DLLs: Problem with public functions using native types as arguments</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,13f270f4-a0fb-4439-8467-0e56ec4d7aef.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,13f270f4-a0fb-4439-8467-0e56ec4d7aef.aspx</id>
    <issued>2006-03-21T18:36:54.0418248+01:00</issued>
    <modified>2006-03-21T19:00:03.5485569+01:00</modified>
    <created>2006-03-21T18:36:54.0418248+01:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
  <entry>
    <title>Reflector Add-In for C++/CLI available</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,589239d3-b21b-430e-911b-7b355eef8b63.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,589239d3-b21b-430e-911b-7b355eef8b63.aspx</id>
    <issued>2006-01-20T12:07:12.6696347+01:00</issued>
    <modified>2006-01-20T12:07:12.6696347+01:00</modified>
    <created>2006-01-20T12:07:12.6696347+01:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
  <entry>
    <title>Avoid native code in managed object files (".obj" files)</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,d5e2c3da-ff4d-40bc-bea9-9da8ec9e091e.aspx</id>
    <issued>2006-01-12T16:29:45.5533982+01:00</issued>
    <modified>2006-01-21T15:53:42.9409045+01:00</modified>
    <created>2006-01-12T16:29:45.5533982+01:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
  <entry>
    <title>Interesting new feature in .NET: Type identity mapping.</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,8d076332-4fb0-44b5-a829-4c4d653de2d6.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,8d076332-4fb0-44b5-a829-4c4d653de2d6.aspx</id>
    <issued>2005-11-26T12:06:15.6683632+01:00</issued>
    <modified>2005-11-26T22:39:39.6277296+01:00</modified>
    <created>2005-11-26T12:06:15.6683632+01:00</created>
  </entry>
  <entry>
    <title>How to use app.config files in Visual C++ 2005 projects</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,65c852a9-3735-4e48-90c7-8c76003d28c5.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,65c852a9-3735-4e48-90c7-8c76003d28c5.aspx</id>
    <issued>2005-11-12T00:34:30.5013204+01:00</issued>
    <modified>2006-01-21T15:54:42.7065295+01:00</modified>
    <created>2005-11-12T00:34:30.5013204+01:00</created>
  </entry>
  <entry>
    <title>Can DLLs export managed functions to native clients?</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,48daf2ff-41c8-4312-9d80-bdfa8c55058d.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,48daf2ff-41c8-4312-9d80-bdfa8c55058d.aspx</id>
    <issued>2005-10-19T23:58:59.4021033+02:00</issued>
    <modified>2005-10-23T00:16:26.9729785+02:00</modified>
    <created>2005-10-19T23:58:59.4021033+02:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
  <entry>
    <title>My Essential C++/CLI Seminar</title>
    <link rel="alternate" type="text/html" href="http://www.heege.net/blog/PermaLink,guid,e998baf7-390f-4d59-bbd1-fc5c1adbec2f.aspx" />
    <id>http://www.heege.net/blog/PermaLink,guid,e998baf7-390f-4d59-bbd1-fc5c1adbec2f.aspx</id>
    <issued>2005-10-19T22:39:05.7792798+02:00</issued>
    <modified>2005-10-23T00:19:00.4573535+02:00</modified>
    <created>2005-10-19T22:39:05.7792798+02:00</created>
    <content type="text/html" mode="xml">
      <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>
    </content>
  </entry>
</feed>