欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表

.net本质论第十章:非托管模块

创建时间:2013年06月02日 23:43  阅读次数:(4202)
分享到:
前面一节有关unmanaged方法的讨论是假定方法驻留在其他托管模块和程序集中。CLR还支持在非托管模块中调用代码,允许使用传统的C DLL文件和API函数。CLR通过一种称为P/Invoke的技术公开了这种能力。

P/Invoke是前面讲述的托管和非托管转换的超集。P/Invoke提供了丰富的类型转换工具,用于处理传统C DLL和CLR之间的固有差异。除了前面谈到的实现执行模式开关,P/Invoke履行安全权限的要求,确保系统的安全不受到损害.与执行非验证代码相似,调用传统C DLL同样被认为是具有很高特权的操作。为此,P/Invoke引擎将请求UnmanagedCode权限使用P/Invcke的组件必须被显式地授予这种权限.并且,对于大量使用P/Invoke的组件在调用p/Invoke例程之前,要调用IStackWalkAssert,这么做不仅提高了性能,还保证了P/Invoke调用是成功的,而不管哪个代码路径导致当前方法被调用。更好的优化是向类型或者方法中添加System.Security.SuppressUnmanagedCodeSecurity特性,这个特性的存在抑制了CLR的安全要求(事实上提供了具有UnmanagedCode权限的程序集),然而,你应该小心地使用这个特性,因为这是一个相当粗糙的解决办法,并且,如果使用不当将会削弱整个系统的安全性。

使用P/Invuke非常简单。P/lnvoke允许你将方法标记为由传统的前CLR DLL导人的。P/Invoke需要从非托管模块中导出C函数,然后在托管模块中使用特别的元数据指令进行重新声明。这些指令标明DLL的文件名和DLL中入口项的符号名。p/Invoke引擎在调用批注的方法之前,使用这两个字符串依次调用LcadLibrary和GetProcAddress。

可以通过使用语言无关(language-neutral)的System.Runtime.InteropServices.DllImport伪定制特性制定使用P/Invoke的方法。必须用DllImport特性标记方法为extern(外部的),并且使用与外部DLL中的目标标函数匹配的方法签名来声明它们。最后,每一个P/Invoke方法都
有两个签名。显式签名是托管代码调用时可见的:隐式签名则是外部DLL函数预期的。P/Invoke引擎将根据默认的映射规则和定制特性,推断出非托管签名。

DllImport特性采用多种参数定制外部方法和签名如何被导入和解析。如表10.1所示,DllImport特性至少需要你提供一个文件名。运行时,于分发方法调用之前使用这个文件名,调用LoadLibrary,除非EntryPoint参数被传蛤DllImport,否则用于GetProcAddress的字符串将是方法符号化后的名字。
DllImport特性参数

下面的C#程序段展示了在kernel32.dll中调用Sleep方法的两种方式:
using System.Runtime.InteropServices;
public class K32Wrapper{
[DllImport(“kernel32.dll”)]
public extern static void Sleep(uint msec);
[DllImport(“kernel32.dll”,EntryPoint=”Sleep”)]
public extern static void Doze(uint msec);
}

第一个示例依赖于C#函数名与DLL中符号名之间的匹配。第一个示例则依赖于EntryPoint特性参数。
 
姑且不论入口点名字是如何指定的,你不得小处理多种凌乱的命名模式,以标明调用约定和字符集。除非将ExactSpelling参数为true,否则,P/Invoke将使用多种试探方式,在外部DLL中查找匹配的入口点。当使用这些字符串的P/Invoke力法被调用时,入口点名字将自动冠吧“w”或者“A”的后缀,选取决于底层平台是Unicode还是基于ANST的。如果入口点仍然没有找到,运行时将使用etdcall约定合成名字(例如Sleep将成为Sleep@4)。y
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 65+41=? 的结果(结果是:106)
结  果: