C#程序设计_课件_15.ppt_第1页
C#程序设计_课件_15.ppt_第2页
C#程序设计_课件_15.ppt_第3页
C#程序设计_课件_15.ppt_第4页
C#程序设计_课件_15.ppt_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、基于C#的 .NET Framework程序设计,第1章 Microsoft .NET Framework概述 第2章 托管执行环境的介绍 第3章 使用组件 第4章 部署与版本控制 第5章 通用类型系统 第6章 类型的使用 第7章 字符串、数组和集合 第8章 委托和事件 第9章 内存和资源管理,第10章 数据流和文件 第11章 Internet访问 第12章 序列化 第13章 远程处理和XML Web Service 第14章 线程和异步编程 第15章 托管代码与非托管代码之间的互操作 第16章 使用Microsoft ADO.NET 访问数据 第17章 属性,第15章 托管代码与非托管代码之

2、间的互操作,集成服务 平台调用 在托管代码中调用COM对象 在COM对象中调用.NET对象,集成服务,平台调用介绍 介绍COM的互操作性 Interop 封送处理概述,15.1 集成服务,平台调用介绍,允许托管代码调用在DLL中实现的非托管方法 为下列功能提供机制 定位实现指定函数的DLL,加载DLL到内存中 发现和调用非托管函数 在托管和非托管代码之间进行参数的封送处理,15.1.1 平台调用介绍,介绍COM的互操作性,COM和 .NET的不同之处 生命期管理 COM:引用计数 对 .NET: 垃圾回收 服务发现 COM:查询接口 对 .NET:反射 对象内存 COM:固定的 对 .NET:

3、 可以移动的 运行库可调用包装 (RCW) 使用托管客户端调用COM对象上的方法 COM可调用包装 (CCW) 使用COM客户端调用托管对象上的方法,15.1.2 介绍COM的互操作性,Interop 封送处理概述,互操作封送处理控制在方法调用时如何在托管和非托管内存间传递数据 互操作封送处理是CLR封送处理服务执行的运行时活动 Blittable数据类型对托管和非托管内存是一样的,不需要转换数据类型(C#关键字) System.Byte (byte)System.SByte (sbyte) System.Int16 (short)System.UInt16 (ushort) System.I

4、nt32 (int)System.UInt32 (uint) System.Int64 (long) System.IntPtr System.UIntPtr,15.1.3 Interop 封送处理概述,Interop 封送处理概述(续),Non-blittable 类型是那些在托管和非托管内存具有不同表现的类型,需要进行转换 例如,托管字符串就是non-blittable类型 标准RCW和CCW通常为跨COM和.NET边界调用提供了合适的封送处理 可以使用自定义属性选择性地调整运行库表示托管和非托管代码的形式,15.1.3 Interop 封送处理概述,集成服务 平台调用 在托管代码中调用C

5、OM对象 在COM对象中调用.NET对象,第15章 托管代码与非托管代码之间的互操作,平台调用,平台调用工作方式 从托管代码中调用 Win32 API 调用非托管函数 钉住操作 封送处理 平台调用的性能问题及局限性,15.2 平台调用,平台调用工作方式,平台调用工作过程 定位包含被调用方法的DLL 把该DLL加载到内存 查找函数在内存中的地址并将其参数压入堆栈,以封送所需的数据 把控制权移交给非托管函数,15.2.1 平台调用工作方式,平台调用工作方式(续),15.2.1 平台调用工作方式,从托管代码中调用Win32 API,用static和extern C#关键字声明方法 导入实现非托管函数

6、的DLL,15.2.2 从托管代码中调用Win32 API,DllImport(, EntryPoint=, CharSet=,从托管代码中调用Win32 API(续),用自定义封送处理信息来覆盖 .NET Framework提供默认的封送处理,15.2.2 从托管代码中调用Win32 API,调用非托管函数,有两种方法可调用非托管DLL中的方法 使用DLLImport属性 导入System.Runtime.InteropServices命名空间 声明一个静态方法来调用非托管方法,不用提供方法实现 使用DllImport属性标注方法,指定输出非托管方法的DLL的名称,15.2.3 调用非托管函

7、数,using System.Runtime.InteropServices; DllImport(msvcrt.dll, CharSet=CharSet.Ansi) public static extern int puts(String str);,钉住操作,数据被临时锁定在当前内存位置,防止被CLR的垃圾回收器重新分配 数据在托管和非托管代码之间传递时,执行锁定操作 如果对象有固定的布局,在托管和非托管内存中数据表现形式一样,则通过指针进行封送 有固定布局,但数据在托管和非托管内存中表现不一致,通过引用来封送 如果对象没有固定的布局,通过值或者引用传递,如System.String和Sy

8、stem.StringBuffer对象,15.2.4 钉住操作,封送处理,大多数数据类型在托管和非托管内存中都有公共的表示形式,而不需要封送拆收器的特殊处理,称为可直接复制到本机结构中的类型 非直接复制到本机结构中的类型在托管和非托管语言中具有不同的或不明确的表示形式。当被封送时,这些类型可能需要转换 用MarshalAs属性来指定自定义封送处理,15.2.5 封送处理,public static extern int MessageBoxW( int h, MarshalAs(UnmanagedType.LPWStr) string m, );,平台调用的性能问题及局限性,平台调用只支持带整

9、数参数的回调函数 平台调用不对所有类型提供支持 平台调用只支持调用从DLL导出的全局函数 当以引用传递数组类型的参数时,返回的数组大小被调整为 1,15.2.6 平台调用的性能问题及局限性,实验A 调用 Win32 API 函数,练习1 在托管代码中调用 Win32 API 函数,集成服务 平台调用 在托管代码中调用COM对象 在COM对象中调用.NET对象,第15章 托管代码与非托管代码之间的互操作,在托管代码中调用COM对象,运行库可调用包装 生成运行库可调用包装 线程模型 签名转换和错误处理 封送处理 性能和安全问题 最佳实践,15.3 在托管代码中调用COM对象,运行库可调用包装,15

10、.3.1 运行库可调用包装,生成运行库可调用包装,用如下3个方法产生运行库可调用包装 在Visual Studio .NET工程中添加COM组件的引用 使用类型库导入器 创建自定义包装,15.3.2 生成运行库可调用包装,线程模型,COM组件使用单元来同步对托管资源的访问 当调用COM对象时,运行库创建并初始化一个COM单元 确保应用程序的主线程是 STA 模式,15.3.3 线程模型,using System.Threading; using APTOBJLib; Thread.CurrentThread.ApartmentState = ApartmentState.STA; AptSim

11、ple obj = new AptSimple (); obj.Counter = 1;, STAThread static void Main() ,签名转换和错误处理,15.3.4 签名转换和错误处理,封送处理,对于将数据封送处理到COM和从COM中封送处理数据的支持是广泛的,并几乎总是提供正确的封送处理行为 表格显示了C#类型和相应COM类型的比较 用MarshalAsAttribute属性来改变数据封送行为 用两种方法自定义RCW来处理类型 编辑互操作程序集 手动创建包装类,15.3.5 封送处理,public void M1 (MarshalAs(UnmanagedType.LPWS

12、tr)String msg);,性能和安全问题,托管和非托管互操作时的转换会造成每次调用10到40个指令的系统消耗 限制代码中出现的转换次数 一次进行多个API调用 在创建COM对象前,设置ApartmentState来阻止代理和存根的创建 对可信任代码,当托管代码调用非托管代码时,使用SuppressUnmanagedCodeSecurity属性防止安全检查,15.3.6 性能和安全问题,最佳实践,使用Ildasm.exe来检查已产生程序集的命名空间和类的名称 在Visual Basic 6.0或者C+的引用参数在VB.NET将产生一个用ref关键字修饰的参数,15.3.7 最佳实践,实验B

13、 调用 COM 对象,练习1在托管代码中调用COM对象,集成服务 平台调用 在托管代码中调用COM对象 在COM对象中调用.NET对象,第15章 托管代码与非托管代码之间的互操作,从COM对象中调用.NET对象,COM可调用包装 导出过程 在系统注册表中注册.NET Framework类 使用 ClassInterfaceAttribute 在COM中使用.NET Framework 类型 托管和非托管事件 最佳实践,15.4 从COM对象中调用.NET对象,COM可调用包装,15.4.1 COM可调用包装,导出过程,程序集中的任何公有类都被转换为类型库中的 coclass 将显式实现的接口输

14、出到类型库 托管代码 类型库,15.4.2 导出过程,public interface IShape void Draw(); void Move(int x, int y); class Circle : IShape void Draw(); void Move(int x, int y); void Enlarge(int x); , uuid(), dual, odl, oleautomation interface IShape : IDispatch HRESULT Draw(); HRESULT Move(int x, int y); uuid() coclass Circle

15、interface IShape; ,在系统注册表中注册.NET Framework类,使用Regasm.exe在系统注册表中注册.NET Framework类 注册.NET Framework类会在系统 注册表中添加如下注册项 Hkey_Classes_RootCLSID注册键中.NET Framework类的CLSID 两个存根键:HKCRCLSIDclass_ID键下的Implemented Categories和InprocServer32 HKCRCLSID 键的默认值为类的 ProgID InprocServer32 默认被设置为包含公共语言运行库的DLL的名称,15.4.3 在系

16、统注册表中注册.NET Framework类,使用 ClassInterfaceAttribute,类接口提供.NET Framework对象显式公开的所有公共方法、属性、字段和事件 阻止创建类接口 创建一个 dispatch 接口 创建一个双绑定接口,15.4.4 使用ClassInterfaceAttribute,在COM中使用.NET Framework 类型,在非托管代码中使用.NET Framework类 设置对描述.NET Framework类的类型库的引用 在 Visual Basic 6.0中,使用引用对话框来设置引用 在 Visual C+ 6.0中,使用 #import 指令来引用类型库 创建和使用类型库中定义的类对象,15.4.5 在COM中使用.NET Framework 类型,托管和非托管事件,.NET事件模型和COM中的事件模型不同 托管事件是基于委托的,但是COM中的非托管事件是基于连接点的 关于下列话题的更多内容,请查看 .NET FrameworkSDK 文档 处理来自COM源引发的事件 引发COM接收器处理的事件,15.4.6 托管和非托管事件,最佳实践,为COM客户端定义一个显式接口,而不生成类接口 因为对托管类的改动会改变类接口的布局 可以使用ClassInter

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论