在.NET中使用COM组件

2023-05-16

在.NET中使用COM组件


文章目录

  • 在.NET中使用COM组件
  • 早期绑定COM对象
      • 为COM类型库生成互操作程序集
      • 使用COM组件
  • 后期绑定COM对象
  • 通过与非托管代码互操作创建COM对象
      • 通过平台调用创建COM对象
      • 通过C++ Interop包装COM对象
  • 封送处理
  • 错误处理
  • 提升性能


早期绑定COM对象

为COM类型库生成互操作程序集

  • 使用.NET Framework SDK中提供的COM Interop工具 (类型库导入程序TlbImp.exe)TlbImp

可以将COM类库的dll或tlb 转换为.NET程序可用的dll,互操作封送处理服务能从生成的dll中生成包装对象,这个包装对象能够在托管内存和非托管内存之间执行数据封送处理。

tlbImp sampleCom.tlb /out:sampleCom.Interop.dll /namespace:SampleCom.Interop

用VB6编写的COM组件 ,每次编译COM组件时,都 会更改COM组件的标识,使得类和接口的GUID每次都不一样,导致其他引用此COM的项目无法正常运行,解决方案是在.NET项目的PostBuild Event的CommandLine中添加脚本,自动调用TlbImp 命令行工具为COM类型库生成互操作程序集。

  • 也可以通过VS内置支持来完成COM类型库创建互操作程序集的工作,只需要引用COM组件即可,但这程方法缺乏灵活性,因为它使用默认的命名空间和程序集名称,如果使用的是VB6生成的COM,COM升级会导致引用失败,要删除重新添加。

使用COM组件

添加tlbimp生成的dll引用之后就可以使用COM对象的中的方法(注:如果COM是x86的,.NET程序要将生成的目标平台选为X86)

在托管代码中使用COM组件的主要步骤。
(1)为COM类型库生成一个互操作程序集。此程序集包含COM类型库中每个类和接口的RCW实现。
(2)在NET项目中添加对该互操作程序集的引用。
(3)创建RCW的实例,也创建了-一个COM对象的实例。
(4)使用RCW实例的方法或属性。
(5)当RCW被垃圾回收时,COM对象的实例也会随之被释放。

  • 还可以手写RCW实现,但代码复杂

后期绑定COM对象

可以使用反射 机制对COM对象进行后期绑定,要先知道COM对象的ProgID和CLSID ,以便使用其获得COM对象的类型。
后期绑定的步骤:
(1)使用COM对象的ProgID 或CLSID 获得COM对象的类型。这一步会用到System.Type类的静态方法GetTypeFromProgID或GetTypeFromCLSID.
(2)利用上一步获得的COM对象类型,使用Activator 类的静态方法CreateInstance创建此类型的实例。
(3)使用第1步获得的System.Type类型的实例的InvokeMember方法调用COM对象中暴露的方法或属性。

COM对象支持IDispatch接口,在运行时使用IDispatch的方法定位COM组件的方法或属性。
怎么获取ProgID或CLSID ?
可以通过查看COM组件源代码中的.rgs格式文件
或用OLEview查看看COM类型库信息
在vs开发人员命令提示符中输入oleview,打开程序
在这里插入图片描述
找到要使用的类 复制上面的UUID即为CLSID
在这里插入图片描述

using System.Reflection; //用于后期绑定
            Type comType = Type.GetTypeFromCLSID(clsid);
            Object comObj = Activator.CreateInstance(comType);
            Object[] methodArgs = { 6, 4 };

            Object result = comType.InvokeMember("Add", BindingFlags.InvokeMethod, null, comObj, methodArgs);
            Console.WriteLine("运算:{0}+{1}={2}", methodArgs[0], methodArgs[1], result);

选择那种绑定形式取决于具体情况。在一般情况下, 早期绑定应该是首选方法,因为早期绑定具有最好的性能。而对于在设计时不知道对象的具体接口的情况,后期绑定依然十分有用。比如需要按名称调用函数的情况,以及要解决多个版本的兼容性问题时,则使用后期绑定有助于解决这些问题。

通过与非托管代码互操作创建COM对象

通过平台调用创建COM对象

通过C++ Interop包装COM对象

封送处理

错误处理

提升性能

为了优化性能,在调用COM对象时,最好遵守下面的调用规则。
(1)避免跨单元调用。
(2)在ASP.NET中调用STA对象时必须设置ASPCOMPAT属性。
(3)在调用线程安全的对象时,使用多线程单元模型。
(4)尽量使用线程中立(neutral apartment)的COM组件,以避免线程切换。要避免跨单元调用发生,需要首先了解被调用的COM组件的线程模型,然后在托管代码中设置相同的运行环境。表5.5列出了组件线程模型和非托管线程之间的映射关系。

组件线程模型非托管线程类型
SingleSTA
ApartmentSTA
BothSTA MTA
NeutralSTA MTA
FreeMTA

在C#中,有两种设置线程类型的方法。
(1)声明:采用STAThread或MTAThread属性。
(2)程序:使用Thread.SetApartmentState方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在.NET中使用COM组件 的相关文章

随机推荐

  • 远程登录windows桌面蓝屏的解决方法

    1 windows 43 r xff0c 打开运行 xff0c 输入mstsc xff0c 回车 xff0c 输入对应的服务器登录 2 登陆后出现蓝屏 xff0c 无法显示桌面 xff0c Ctrl 43 Alt 43 End键 xff0c
  • ALM/QC11.0在win8/IE11下无法浏览

    页面显示要求安装插件 xff0c 安装ALM Platform Loader 11 msi 失败 xff0c 提示 cannot be installed on windows xp vista windows7 x64 UAC已关闭 xf
  • opengl实现俄罗斯方块

    include 34 Angel h 34 pragma comment lib 34 glew32 lib 34 include lt cstdlib gt include lt iostream gt include lt time h
  • Mysql学习日记:L20-insert(DML)

    目录 一 insert语法格式 二 insert插入日期 2 1 str to date函数 2 2 date format函数 2 3 date和datetime的区别 三 insert一次插入多条语句 一 insert语法格式 语法格式
  • 解决debian服务器中文显示乱码问题

    由于安装debian选择语言时选择了简体中文安装 xff0c 但内核没有中文字库 xff0c 导致某些字符显示为乱码 xff08 菱形 xff0c 方块 xff09 解决办法 xff1a 普通用户如果没有设置sudo权限 xff0c 首先切
  • 201609-3炉石传说——CCF试题2016年9月第三题

    问题描述 炉石传说 xff1a 魔兽英雄传 xff08 Hearthstone Heroes of Warcraft xff0c 简称炉石传说 xff09 是暴雪娱乐开发的一款集换式卡牌游戏 xff08 如下图所示 xff09 游戏在一个战
  • C语言打印宏定义/枚举变量 名称和变量值

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • File size exceeds....(文件大小超过限制处理)

    File size exceeds configured limit 2560000 Code insight features not available 原因 xff1a IDEA对能关联的文件大小做了限制 xff0c 主要是为了保护内
  • 第一章-介绍

    介绍 一般建议 什么是游戏引擎 什么是Godot 下载Godot 其他安装方法 Godot UI概述 Project Manager 选择文件名 编辑器窗口 关于节点和场景 Godot中的脚本 关于GDScript 总结 无论你是想要从事的
  • 安装ubuntu系统,报错WslRegisterDistribution failed with error: 0x8007019e

    在windows应用商店安装ubuntu系统 xff0c 报错WslRegisterDistribution failed with error 0x8007019e 1 报错 xff1a Installing this may take
  • 安装Anaconda后,发现文件缺少大量文件

    电脑崩溃修复后 xff0c 使用的Anaconda 居然也崩了 xff0c 重新安装后丢失很多文件 xff0c 然后就是重复的卸载 安装 卸载 xff0c 还是不行 xff0c 我的心态也快要崩了 xff0c 哎 xff0c 就下面图示一样
  • AutoMapping 9 使用入门

    AutoMapping 9语法更改 using AutoMapper using System using System Collections Generic using System Linq using System Text usi
  • Oracle在线练习

    oracle官方的服务 Live SQL xff0c 挺方便的 需要注册一个帐号 访问地址 xff1a https livesql oracle com apex livesql file index html https livesql
  • pyinstaller 打包取消命令行窗口弹出

    pyinstaller F w icon 61 photo ico test py w可以使得exe运行时不弹窗
  • c#有参构造函数中怎么调用其无参构造函数

    class A public A public A int A this 当A a 61 new A 1 时 会先调用无参数的构造函数 在调用有参数那个
  • 使用npm的一些问题

    npm切换为国内的数据源 npm config set registry https span class token punctuation span span class token operator span span class t
  • Caliburn.Micro将枚举 绑定到ComboBox

    参考 https stackoverflow com questions 47480725 caliburn micro enum binding in combobox 上面的文章详细地说明了CM的绑定原理和操作步骤 xff0c 但我需要
  • WPF DataGrid 获取多选项目

    解决方案 xff1a 先附上地址 xff1a https stackoverflow com questions 9880589 bind to selecteditems from datagrid or listbox in mvvm
  • 记一次netcore 3.1 发布失败

    VS版本 xff1a 2019 16 8 5 使用框架 xff1a netcore3 1 问题描述 xff1a 项目可以正常生成 xff0c 但部署模式为独立时 xff0c 不能发布 xff0c 部署模式为依赖框架 xff0c 可以发布 报
  • 在.NET中使用COM组件

    在 NET中使用COM组件 文章目录 在 NET中使用COM组件早期绑定COM对象为COM类型库生成互操作程序集使用COM组件 后期绑定COM对象通过与非托管代码互操作创建COM对象通过平台调用创建COM对象通过C 43 43 Intero