首页 新闻 会员 周边 捐助

关于Dll、Com组件、托管dll和非托管dll的理解,请教高手看我的理解是否正确(如用代码回复请用C#)

0
悬赏园豆:10 [已解决问题] 解决于 2016-01-07 10:55

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);调用

Lasthelloworld的主页 Lasthelloworld | 初学一级 | 园豆:92
提问于:2015-11-24 10:33
< >
分享
最佳答案
0

如上理解的基本正确
这几个概念针对的内容不同,面向的方面不一样

DLL:这个只是程序打包的表现形式,是早期windows为了解决代码公用而使用的一种技术,这个库文件只能被调用运行到一个执行文件进程中
COM:主要是为了解决二进制程序间的公用的技术,既可以使用独立进程COM服务,如Office的COM模型,其他程序可以任意调用;也可以是DLL的形式,运行时需要依赖执行进程,相比DLL有很大的优越性,都是基于接口和系列的规范进行,一定程度上解决了DLL的版本问题
如上在.net时代前,主要是C/C++进行编写

托管:这个是后来微软推出.net后,有了.net虚拟环境,因此所有的程序都叫做托管了
托管COM:进入.net时代后,微软以前的COM技术有大量的历史遗留软件,因此为了兼容,必然就有这个托管的COM问题,主要涉及2个方面:托管程序和历史的COM交互[interop];另外也可以使用C#等托管语言实现COM组件【这种方式不推荐,毕竟是淘汰的技术,.net下完成类似的事情已经提供了更好的手段】

收获园豆:10
2012 | 高人七级 |园豆:21445 | 2015-11-24 11:03

太感谢了,DLL,COM,托管,非托管,看了几天了,有了个初步了解,得到园友的肯定很高兴。

后面还想看下其他园友的看法,比如:拿到一个dll判断是com组件还是dll文件,其次是如何判断一个dll文件是托管的还是非托管的,主要是程序上如何实现。

Lasthelloworld | 园豆:92 (初学一级) | 2015-11-24 14:42

@Lasthelloworld: 一个dll如果是com组件,一般都会有DllRegisterClass这类com专用的接口,或者regsvr32 regasm能注册的就是com

dll是否为托管,一个方法是使用depends.exe看看是否有依赖core*.dll的微软.net库;另一个看看PE文件的结构,我记得有个文件头标识位可以知道,或者C#LoadAssembly无法加载的就是不同dll

2012 | 园豆:21445 (高人七级) | 2015-11-25 11:47
其他回答(1)
0

2023年了,感谢总结

Abagnate | 园豆:202 (菜鸟二级) | 2023-08-07 14:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册