关于Dll、Com组件、托管dll和非托管dll
转自: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);
非托管使用
[DllImport("Kernel32.dll")]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组件
关于Dll、Com组件、托管dll和非托管dll的更多相关文章
- 如何让IntPtr指向一块内存,以及托管内存与非托管内存的相互转化
IntPtr idp= IntPtr.Zero; StringBuilder idata = new StringBuilder("000000"); string idata = ...
- C# using 三种使用方式 C#中托管与非托管 C#托管资源和非托管资源区别
1.using指令.using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到. ...
- C# 托管资源和非托管资源
托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收. 非托管资源指的是.NET不知道如何回 ...
- [转]在C#中使用托管资源和非托管资源的区别,以及怎样手动释放非托管资源:
托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收. 非托管资源指的是.NET不知道如何回 ...
- C# 托管资源与非托管资源
在.net 编程环境中,系统的资源分为托管资源和非托管资源. 托管资源: Net平台中,CLR为程序员提供了一种很好的内存管理机制,使得程序员在编写代码时不要显式的去释放自己使用的内存资源(这些在先前 ...
- C# 托管内存与非托管内存之间的转换
c#有自己的内存回收机制,所以在c#中我们可以只new,不用关心怎样delete,c#使用gc来清理内存,这部分内存就是managed memory,大部分时候我们工作于c#环境中,都是在使用托管内存 ...
- .net 资源释放(托管资源和非托管资源)
1.托管资源 像int.float.DateTime等都是托管资源:net中80%的资源都是托管资源: 托管资源的回收通过GC(垃圾回收器)自动释放分配给该对象的内存,但无法预测进行垃圾回收的时间,我 ...
- Azure 托管镜像和非托管镜像对比
目前中国区 Azure 也已经可以使用命令制作托管镜像了.但对于托管镜像和非托管镜像,就像托管磁盘和非托管磁盘一样,很多人可能一开始无法理解.这里就此进行了一个简单对比: 通过对比测试,这里总结了这两 ...
- C# 托管资源 与 非托管资源
C# 托管资源 与 非托管资源 托管资源一般是指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,.NET可以自动进行回收,主要是指托管堆上分配的内存资源.例如程序中分配的对象,作用域内的变量 ...
- .net托管资源与非托管资源
在项目当中用到的资源分为托管资源和非托管资源,托管资源无非就是什么int.string.datatime之类,托管资源不需要人为去管理,.net framework中有专门针对托管资源的管理机制(GC ...
随机推荐
- Azure Terraform(十)利用 Azure DevOps 的条件语句选择发布环境
一,引言 之前我讲过的所有的案例中,都是将整个Azure Resource 部署到同一个订阅下,没有做到灵活的在 Azure Pipeline 在运行前选择需要部署的环境.在实际的项目开发中,我们也会 ...
- golang中的sync
1. Go语言中可以使用sync.WaitGroup来实现并发任务的同步 package main import ( "fmt" "sync" ) func h ...
- gin中自定义http的配置
package main import ( "github.com/gin-gonic/gin" "net/http" "time" ) f ...
- java-异常-异常处理原则
1 异常处理的原则: 2 * 1,函数内部如果抛出需要检测的异常,那么函数上必须要声明. 3 * 否则必须在函数内用trycatch捕捉,否则编译失败. 4 * 5 * 2,如果调用到了声明异常的函数 ...
- cp 不提示按y
yes|cp index.html.j2 yml -rf \cp index.html.j2 yml/ 两个效果是一样的
- 在js中如何区分深拷贝与浅拷贝?
一.自我理解 简单来讲就是:深拷贝层层拷贝,浅拷贝只拷贝第一层. 在深拷贝中,新对象中的更改不会影响原对象,而在浅拷贝中,新对象中的更改,原对象中也会跟着改. 在深拷贝中,原对象与新对象不共享相同的属 ...
- python05day
之前代码总行数735+133=868 内容回顾 列表:容器型数据类型,可以承载大量的数据,有序的数据 增: append 追加 insert 插入,按索引增 extend 迭代着追加 删: pop 按 ...
- Java中Type接口及其子类
简介 Type是Java 编程语言中所有类型的公共高级接口,和Object不同,Object是所有类的父类,即Object是Type的父类. 分类 原始类型(Class):不仅仅包含我们平常所指的类, ...
- 【JS】函数提升变量提升以及函数声明和函数表达式的区别
今天看js的变量提升问题,里面提到了函数提升.然后发现自己之前一直把函数声明和函数表达式弄错,导致函数提升出错 一.变量提升 console.log(a) var a=100 //undefined ...
- APP一般使用哪种Activity启动模式【转】
感谢大佬:https://zhidao.baidu.com/question/1116547799060798099.html 刚好最近又梳理了一下,结合我的实际使用场景回答一下= = 有四种启动模式 ...