亚洲 C#中COM操作(一)---实例化[1]
C#中COM操作(一)---实例化[1]
用C#做WinForm程序 时间长了难免会遇到和组件打交道的地方 用什么方式创建对象也成了我们必须面对的一个问题 据我所知道的创建对象的方法一共有以下几种:
使用 NET包装组件
这是最简单的就是导入组件所在的DLL 让IDE生成 NET一个IL包装加到项目中 这样原来里面所有实现了IDispatch Dual的类型及其相关类型就可以直接在 NET程序里面使用 比如以前在 时代 想要写自己的基于IE的浏览器 就得手动加入与IWebBrowser 接口相关的DLL 这种方式是大家最常用的 也是最傻瓜化的 因此也没什么可解释的
但是这种方式有个至命的缺点——不是所有的对象都能用这种方式导出 正如前面所说的 只有实现了IDispatch Dual类型的接口才支持被导出 而且面对不同版本的或许会生成不一样的导出DLL 比如说A机器上写代码时导入了一个Jet 版本的包装DLL 代码编译了拿到B机器上去运行 但是B机器上的Jet版本是 的 就可能会出现运行时错误
用反射动态创建
![亚洲 C#中COM操作(一)---实例化[1]](http://img.zhputi.com/uploads/ff59/ff593eb6552e523dc8ead4a6f4ec3dba30474.jpg)
包括使用Type GetTypeFromCLSID和Type GetFromProgID两种方法获取对象的Type再创建 这种方式也好理解 就是说使用这两个方法之前 必须得知道对象的GUID或ProgID 好在这也不是什么难事 一般我们要使一个对象 多多少少都了解一些这个对象的GUID或ProgID信息 用这种方获取到了一个Type对象后 就可以用 NET里面通用的反射创建对象的方法来做了
这里给出一个创建JetEngine 的对象的代码实例:
public object GetActiveXObject(Guid clsid) { Type t = Type GetTypeFromCLSID(clsid); if (t == null) return null; return Activator CreateInstance(t); } Guid g = new Guid( DE C FF C D BB F C FAE DA ); // JetEngine object jet = GetActiveXObject(g);是不是觉得最后调用GetActiveXObject(g)的地方和IE里面Javascript里面用new ActiveXOjbect创建对象的方法很相像?
声明CoCreateInstance外部函数 用这个函数去创建相应的实例
M$在 里面包装的WebBrowser控件内部就是用这个函数去创建的 使用这种方式创建 就跟在C++里面不什么两样了 有一点需要说明的是 一般我们在代码中引入外部方法的时候 方法的参数和返回值的类型不一定是唯一的一种 只要在逻辑上相互能转化 一般都可以使用
比如说如下几种声明都是正确的:
[return: MarshalAs(UnmanagedType Interface)] [DllImport( ole dll ExactSpelling=true PreserveSig=false)] public static extern object CoCreateInstance([In] ref Guid clsid [MarshalAs(UnmanagedType Interface)] object punkOuter int context [In] ref Guid iid); [DllImport( ole dll ExactSpelling=true PreserveSig=false)] public static extern IntPtr CoCreateInstance([In] ref Guid clsid IntPtr punkOuter int context [In] ref Guid iid); [DllImport( ole dll ExactSpelling=true)] public static extern int CoCreateInstance([In] ref Guid clsid IntPtr punkOuter int context [In] ref Guid iid [Out] out IntPtr pVoid); [DllImport( ole dll ExactSpelling=true)] public static extern int CoCreateInstance([In] ref Guid clsid [MarshalAs(UnmanagedType Interface)] object punkOuter int context [In] ref Guid iid [MarshalAs(UnmanagedType Interface) Out] out object pVoid);甚至于当你有里面对应的接口类型的声明的时候 完全可以把上面的object或IntPtr换成相应的接口类型 前提是你的接口类型的声明一定要正确 读者中用C++做过的一定对这种方式记忆犹新吧 只不过这里不再需要什么CoInitialize和CoUninitialize NET内部自己帮你搞定了 顺便提一下 上面例子中的object与IntPtr声明是相通的 我们可以用Marshal GetObjectForIUnknown和Marshal GetIUnknownForObject这两个方法在object和IntPtr之间互转 前题当然是这两种方式所指向的都是对象才行 这种方式提供的传入参数最多 创建对象也最灵活
lishixinzhi/Article/program/net/201311/15280- 上一篇
disease和sickness 英语谚语:By the side of sickness health becomes sweet 中文翻译是什么?
英语谚语:By the ide of ick e health ecome weet 中文翻译是什么? 英语谚语:By the ide of ick e health ee weet中文意思:和疾病相
- 下一篇
abc本的区别 公务员考试ABC类是什么有什么区别!
公务员考试ABC类是什么有什么区别 公务员考试A,B,C类也就是就是三个不同的选拔模式,A类主要针对县级以上单位,考三门;B类面向省垂直单位的,考两门,C类面向乡镇机关的。职位范围的区别:A类职位主要