天下

记录修行的印记

Double Thunking


By default, when compiling with /clr (not /clr:pure), the definition of a managed function causes the compiler to generate a managed entry point and a native 

entry point. This allows the managed function to be called from native and managed call sites. However, when a native entry point exists, it can be the entry 
point for all calls to the function. If a calling function is managed, the native entry point will then call the managed entry point. In effect, two calls 
are required to invoke the function (hence, double thunking). For example, virtual functions are always called through a native entry point.
One resolution is to tell the compiler not to generate a native entry point for a managed function, that the function will only be called from a managed 
context, by using the __clrcall calling convention.
Similarly, if you export (dllexport, dllimport) a managed function, a native entry point is generated and any function that imports and calls that function 
will call through the native entry point. To avoid double thunking in this situation, do not use native export/import semantics; simply reference the 
metadata via #using (see The #using Directive).
In Visual C++ 2005 the compiler was updated to reduce unnecessary double thunking. For example, any function with a managed type in the signature (including 
return type) will implicitly be marked as __clrcall. For more information on double thunk elimination, see 
http://msdn.microsoft.com/msdnmag/issues/05/01/COptimizations/default.aspx.
Example
The following sample demonstrates double thunking. When compiled native (without /clr), the call to the virtual function in main generates one call to T's 
copy constructor and one call to the destructor. Similar behavior is achieved when the virtual function is declared with /clr and __clrcall. However, when 
just compiled with /clr, the function call generates a call to the copy constructor but there is another call to the copy constructor due to the 
native-to-managed thunk.
纯 MSIL 程序集可以调用非托管函数,但不能由非托管函数调用。因此,与非托管函数使用的服务器代码相比,纯 MSIL 更适合于使用非托管函数的客户端代码。
当我们使用/clr选项(不是/clr:pure)进行编译的时候,一个托管函数(managed function),会导致编译器生成一个托管的入口点(managed entry point)和一个原生的入口点
(native entry point),这样可以使得托管函数既可以被托管代码调用,也可以被原生代码调用。但是,当一个原生的入口点存在的时候,它将成为所有调用的入口点。也就是说
如果调用者是托管的,它还是会先去调用原生入口点,然后原生的入口点再去调用托管的入口点,这就意味着调用了两次函数入口点(Double Thunking)。 



c++ cli 标准

posted on 2015-12-01 11:14 天下 阅读(301) 评论(0)  编辑 收藏 引用 所属分类: C#


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2015年12月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(4)

随笔分类(378)

随笔档案(329)

链接

最新随笔

搜索

最新评论