转自:https://blog.csdn.net/black_bad1993/article/details/53906252

Com组件

1.线程模型是干嘛用的?
解决”多个线程”“同时”调用你的COM组件的并发控制。客户没有你的COM的源代码,它不知道你的组件是怎么写的,是不是线程安全的(是否用CriticalSection或Mutex保护了临界资源),所以要有一种机制来声明组件的线程安全性,你开发时指定了组件的线程模型,客户端一看,哦,它就知道该怎么写调用的代码。
2.啥时候用操心线程模型?
全看客户端是单线程还是多线程,单线程不用操心,怎么调都没事,多线程就来事了,跨线程调用时就要考虑。
3.线程模型的一堆概念都是哪跟哪啊?
首先一分为二:客户端和组件。客户端用CoInitializeEx进入一种套间,Apartment、Free是指的客户端进入的套间种类;组件要向注册表写入自己兼容什么样的客户端套间,是Apartment,还是Free,还是两种都兼容(Both)。
4.客户端的线程套间和组件的不一致了咋办,难道我调个COM组件还得查注册表看看兼容什么线程模型?
不一致时以组件为主。客户端建的是Apartment,组件兼容Free,那COM背地里会在客户端建一个Free套间,把组件放进去。反之,会建一个Apartment套间把组件放进去。总之以组件为主,这是关键,只有这样,你才不用关心组件的线程安全性,COM服务替你在后台办妥了。
5.听说过列集这个名词,是什么啊,啥时候用?
记死了,跨线程调用组件就得列集,没的商量。传出接口的线程列集,使用接口的线程散列。列集说白了就是不让你直接调用组件的接口,而是调用接口的代理。COM服务在中间插一杠子,干啥,实现COM线程安全那一揽子事呗,它不拦截你的调用它怎么实现啊,所以就给你个代理,所以就列集了呗。
内容来源:https://www.cxybb.com/article/crybird/80808960

COM最酷的一点是,允许把本地的RPC转化成In-Process Procedure Call(进程内过程调用)。这点极大地优化了性能,而且使得COM成为了有史以来最强的RPC方案

Com组件和dll区别:

1.普通dll不能通过regsvr32.exe来注册,而Com组件能通过regsvr32.exe注册。

2.Com组件是微软的一个协议,满足com组件协议的dll文件就是com组件,这种协议为了跨语言、跨平台使用,dll组件需要编译后使用,而Com组件注册后即可使用。

而dll是动态链接库,是一个可以导出函数的集合。

3.Com组件可以是exe也可以是dll文件。

托管dll/Com组件和非托管dll/Com组件:

1.非托管Com组件是用非运行库代码编写的,如C++,用C#编写的Com组件为托管Com组件,托管Com组件是用.netFramwork运行库编写的。

2.COM组件是以前微软推荐的;

COM组件是非托管对象,可以不需要.net框架而直接运行。

.NET组件是现在微软推荐的;

.NET组件是托管对象,必须有.net框架才能运行。

托管dll和非托管dll调用方式:

托管dll:Assembly ass = Assembly.LoadFile(dllPath);加载,

非托管: [DllImport("Kernel32.dll")]

private static extern IntPtr LoadLibrary(string path);调用

疑问:

托管的dll一定是Com组件吗?

错:托管dll只能说是使用运行库代码编写的dll文件,并非一定是Com组件。

非托管的dll一定不是Com组件吗?

错:只用满足Com协议的就是Com组件,与编写的语言无关。

C#调用dll方式与是否是Com组件无关?

对:托管dll,目标代码是C#,使用: Assembly ass = Assembly.LoadFile(dllPath);加载,

非托管dll,目标代码VB6,C++,使用:

[DllImport("Kernel32.dll")]
 
private static extern IntPtr LoadLibrary(string path);调用
 
C:\Windows\Microsoft.NET\Framework\v4.0.30319

注册Com组件的两种方式:

RegAsm.exe:托管注册,使用NET自带工具用来注册COM Interop,.NET下注册Com组件的工具,注册表允许COM 客户程序以透明方式创建.NET

Framework类。

regsvr32.exe:非托管注册,这是用于注册的COM DLL,也可以理解用于注册非托管代码控件注册为Com组件。

补充说明:

运行库为目标的代码称为托管代码,而不以运行库为目标的代码称为非托管代码。

NET Framework 具有两个主要组件:公共语言运行库和 .NET Framework 类库。公共语言运行库是 .NET Framework 的基础。

c#写的Com组件编译为符合.net标准托管类库,添加了COM Interop 层代码。(C#写的com组件需要注册后使用,COM当然还是非托管的,但是c#写的托管代码是可以通过 COM

接口来调用的。)

E:\DllDemo\DllDemo\DllDemo\bin\Debug:

应用:

C#调用外部Com组件:

步骤1:先判断是否是Com组件,使用regasm.exe和regsvr32.exe注册方式判断是否能注册(使用RegAsm.exe注意高版本能注册低版本,低版本不能注册高版本)

步骤2:判断是托管Com组件还是非托管Com组件。

步骤3:托管Com组件使用用, Assembly ass = Assembly.LoadFile(dllPath);

非托管使用

  1. [DllImport("Kernel32.dll")]
  2. private static extern IntPtr LoadLibrary(string path);调用

其他网友的补充:

DLL:这个只是程序打包的表现形式,是早期windows为了解决代码公用而使用的一种技术,这个库文件只能被调用运行到一个执行文件进程中

COM:主要是为了解决二进制程序间的公用的技术,既可以使用独立进程COM服务,如Office的COM模型,其他程序可以任意调用;也可以是DLL的形式,运行时需要依赖执行进程,相比DLL有很大的优越性,都是基于接口和系列的规范进行,一定程度上解决了DLL的版本问题

如上在.net时代前,主要是C/C++进行编写

托管:这个是后来微软推出.net后,有了.net虚拟环境,因此所有的程序都叫做托管了

托管COM:进入.net时代后,微软以前的COM技术有大量的历史遗留软件,因此为了兼容,必然就有这个托管的COM问题,主要涉及2个方面:托管程序和历史的COM交互[interop];另外也可以使用C#等托管语言实现COM组件

最新文章

  1. margin小结
  2. Android开发--adb,SQLite数据库运用
  3. IT智力题
  4. Objective-C 【完整OC项目-购票系统-系统分析-代码实现】
  5. 关于python多线程编程中join()和setDaemon()的一点儿探究
  6. tortoisegit安装使用
  7. Js监控回车事件
  8. POJ 1019 Number Sequence 解读
  9. Android之利用正则表达式校验邮箱、手机号、密码、身份证号码等
  10. javascript 获取随机数
  11. Leetcode 4.28 Tree Easy
  12. shell中的EOF用法
  13. Shell命令-文件及内容处理之more、less
  14. tidb集群某个节点报错之:node_exporter-9100.service failed
  15. 如何用html把文本框外观格式设为只显示底部的横线
  16. Python 实现进程间通信(网络编程)
  17. HDU 4745 Two Rabbits 区间dp_回文序列
  18. 用AutoHotkey实现Excel从表B提取匹配数据到表A
  19. Python导入模块-Import
  20. PowerDesigner教程系列(二)概念数据模型

热门文章

  1. gorm链接mysql的初始化配置和连接池的使用
  2. python3爬虫超简单实例
  3. MySQL基本使用(开机自启动-环境变量-忘记密码-统一编码)
  4. linux中sort命令全面解析
  5. Info.plist常见的设置
  6. MySQL 数据库高级操作 (配图)
  7. STP的究极进化MSTP
  8. LeetCode随缘刷题之字符串转换整数
  9. linux_5
  10. 稳过!华为微认证ModelArts实现智能花卉识别稳过!