传送门

C#互操作系列文章:

  1. C# 互操作性入门系列(一):C#中互操作性介绍
  2. C# 互操作性入门系列(二):使用平台调用调用Win32 函数
  3. C# 互操作性入门系列(三):平台调用中的数据封送处理
  4. C# 互操作性入门系列(四):在C#中调用COM组件

本专题概要:

  • 引言
  • 平台调用
  • C++ Interop(互操作)
  • COM Interop(互操作)

一、引言

这个系列是在C#基础知识中遗留下来的一个系列的,因为在C# 4.0中的一个新特性就是对COM互操作改进,然而COM互操作性却是.NET平台下其中一种互操作技术,为了帮助大家更好的了解.NET平台下的互操作技术,所以才有了这个系列。然而有些朋友们可能会有这样的疑问——“为什么我们需要掌握互操作技术的呢?” 对于这个问题的解释就是——掌握了.NET平台下的互操作性技术可以帮助我们在.NET中调用非托管的dll和COM组件。.NET是建立在操作系统的之上的一个开发框架,其中.NET 类库中的类也是对Windows API的抽象封装,然而.NET类库不可能对所有Windows API进行封装,当.NET中没有实现某个功能的类,然而该功能在Windows API被实现了,此时我们完全没必要去自己在.NET中自定义个类,这时候就可以调用Windows  API 中的函数来实现,此时就涉及到托管代码与非托管代码的交互,此时就需要使用到互操作性的技术来实现托管代码和非托管代码更好的交互。.NET 平台下提供了3种互操作性的技术:

  1. Platform Invoke(P/Invoke),即平台调用,主要用于调用C库函数和Windows API
  2. C++ Introp, 主要用于Managed C++(托管C++)中调用C++类库
  3. COM Interop, 主要用于在.NET中调用COM组件和在COM中使用.NET程序集。

下面就对这3种技术分别介绍下。

二、平台调用

使用平台调用的技术可以在托管代码中调用动态链接库(Dll)中实现的非托管函数,如Win32 Dll和C/C++ 创建的dll。看到这里,有些朋友们应该会有疑问——在怎样的场合我们可以使用平台调用技术来调用动态链接库中的非托管函数呢?

这个问题就如前面引言中说讲到的一样,当在开发过程中,.NET类库中没有提供相关API然而Win32 API 中提供了相关的函数实现时,此时就可以考虑使用平台调用的技术在.NET开发的应用程序中调用Win32 API中的函数;

然而还有一个使用场景就是——由于托管代码的效率不如非托管代码,为了提高效率,此时也可以考虑托管代码中调用C库函数。

2.1 在托管代码中通过平台调用来调用非托管代码的步骤

(1).  获得非托管函数的信息,即dll的名称,需要调用的非托管函数名等信息

(2). 在托管代码中对非托管函数进行声明,并且附加平台调用所需要属性

(3). 在托管代码中直接调用第二步中声明的托管函数

2.2 平台调用的调用过程

(1)  查找包含该函数的DLL,当需要调用某个函数时,当然第一步就需要知道包含该函数的DLL的位置,所以平台调用的第一步也就是查找DLL,其实在托管代码中调用非托管代码的调用过程可以想象成叫某个人做事情,首先我们要找到那个人在哪里(即查找函数的DLL过程),找到那个人之后需要把要做的事情告诉他(相当于加载DLL到内存中和传入参数),最后让他去完成需要完成的事情(相当于让非托管函数去执行任务)。

(2) 将找到的DLL加载到内存中。

(3) 查找函数在内存中的地址并把其参数推入堆栈,来封送所需的数据。CLR只会在第一次调用函数时,才会去查找和加载DLL,并查找函数在内存中的地址。当函数被调用过一次之后,CLR会将函数的地址缓存起来,CLR这种机制可以提高平台调用的效率。在应用程序域被卸载之前,找到的DLL都一直存在于内存中。

(4) 执行非托管函数。

平台调用的过程可以通过下图更好地理解:

三、C++ Interop

第二部分主要向大家介绍了第一种互操作性技术,然后我们也可以使用C++ Interop技术来实现与非托管代码进行交互。然而C++ Interop 方式有一个与平台调用不一样的地方,就是C++ Interop 允许托管代码和非托管代码存在于一个程序集中,甚至同一个文件中。C++ Interop 是在源代码上直接链接和编译非托管代码来实现与非托管代码进行互操作的,而平台调用是加载编译后生成的非托管DLL并查找函数的入口地址来实现与非托管函数进行互操作的。C++ Interop使用托管C++来包装非托管C++代码,然后编译生成程序集,然后再托管代码中引用该程序集,从而来实现与非托管代码的互操作。 关于具体的使用和与平台调用的比较,这里就不多介绍,我将会在后面的专题中具体介绍。

四、COM Interop

COM(Component Object Model,组件对象模型)是微软之前推荐的一个开发技术,由于微软过去十多年里面开发了大量的COM组件,然而不可能在使用.NET技术重写这些COM组件实现的功能,所以为了解决在.NET中的托管代码能够调用COM组件的问题,.NET 平台下提供了COM Interop,即COM互操作技术,COM Interop不仅支持在托管代码中使用COM组件,而且还支持想CMO组件功能托管对象。下面就这两种支持分别做一个介绍。

4.1 在.NET中使用COM组件

在.NET中使用COM对象,主要有3种方法:

      1. 使用TlbImp工具为COM组件创建一个互操作程序集来绑定早期的COM对象,这样就可以在程序中添加互操作程序集来调用COM对象
      2. 通过反射来后期绑定COM对象
      3. 通过P/Invoke创建COM对象或使用C++ Interop为COM对象编写包装类

但是我们经常使用的都是方法一,下面介绍下使用方法一在.NET 中使用COM对象的步骤:

  1. 找到要使用的COM 组件并注册它。使用 regsvr32.exe 注册或注销 COM DLL。
  2. 在项目中添加对 COM 组件或类型库的引用。

添加引用时,Visual Studio 会用到Tlbimp.exe(类型库导入程序),Tlbimp.exe程序将生成一个 .NET Framework 互操作程序集。该程序集又称为运行时可调用包装 (RCW),其中包含了包装COM组件中的类和接口。Visual Studio 将生成组件的引用添加至项目。

3. 创建RCW中类的实例,这样就可以使用托管对象一样来使用COM对象。

下面通过一个图更好地说明在.NET中使用COM组件的过程:

4.2 在COM中使用.NET程序集

.NET 公共语言运行时通过COM可调用包装(COM Callable Wrapper,即CCW)来完成与COM类型库的交互。CCW可以使COM客户端认为是在与普通的COM类型交互,同时使.NET组件认为它正在与托管应用程序交互。在这里CCW是非托管COM客户端与托管对象之间的一个代理。 CCW既可以维护托管对象的生命周期,也负责数据类型在COM和.NET之间的相互转换。实现在COM使用.NET 类型的基本步骤如:

1. 在C#项目中添加互操作特性

可以修改C#项目属性使程序集对COM可见。右键解决方案选择属性,在“应用程序标签”中选择“程序集信息”按钮,在弹出的对话框中选择 “使程序集COM可见” 选项,如下图所示:

2. 生成COM类型库并对它进行注册以供COM客户端使用

在“生成”标签中,选中 “为COM互操作注册”选项,如下图:

勾选“为COM互操作注册”选项后,Visual Studio会调用类型库导出工具(Tlbexp.exe)为.NET程序集生成COM类型库再使用程序集注册工具(Regasm.exe)来完成对.NET程序集和生成的COM类型库进行注册,这样COM客户端可以使用CCW服务来对.NET对象进行调用了。

五、总结

介绍到这里,本专题的内容就结束,本专题主要对.NET 提供的互操作的技术做了一个总的概括,在后面的专题中将会对具体的技术进行详细的介绍和给出一些简单的使用例子。

[转]C# 互操作性入门系列(一):C#中互操作性介绍的更多相关文章

  1. C# 互操作性入门系列(三):平台调用中的数据封送处理

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  2. [转]C# 互操作性入门系列(三):平台调用中的数据封送处理

    参考网址:https://www.cnblogs.com/FongLuo/p/4512738.html C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列( ...

  3. [转]C# 互操作性入门系列(四):在C# 中调用COM组件

    传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...

  4. C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  5. [转]C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...

  6. 【转载】 [unreal4入门系列之七] UE4中的Actor类和Pawn类

    原文地址: http://www.52vr.com/article-558-1.html 现在我们开始进入UE4的代码开发工作.首先,UE4的类框架是非常庞大的,看起来有点让人措手不及.不过正因为UE ...

  7. Maven入门系列(一):Eclipse中使用Maven

    Maven下载和安装 在使用Maven之前首先先要下载Mavne的免安装包,下载地址:http://maven.apache.org/download.cgi 想看源码的可以下载src版本,使用的下载 ...

  8. STM32入门系列-库目录及文件介绍

    已经介绍了过了CMSIS标准,ST公司按照这个标准设计了一套基于STM32F10x的固件库,我们可以直接在ST公司的官网进行下载,现在给大家STM32最新固件库v3.5,在网盘上给大家提供了下载包,链 ...

  9. ABP入门系列之1——ABP总体介绍

    ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点, ...

随机推荐

  1. P4827「国家集训队」 Crash 的文明世界

    「国家集训队」 Crash 的文明世界 提供一种不需要脑子的方法. 其实是看洛谷讨论版看出来的( (但是全网也就这一篇这个方法的题解了) 首先这是一个关于树上路径的问题,我们可以无脑上点分治. 考虑当 ...

  2. Linux系统引导过程及排除启动故障

    一.Linux操作系统引导过程二.系统初始化进程1.init进程2.Systemd3.Systemd单元类型三.排除启动类故障[1].修复MBR扇区故障(含实验过程)[2].修复GRUB引导故障●方法 ...

  3. 将已经基本完成的项目推送到gitee上管理

    1,首先在gitee上创建仓库,保留一个.gitigonore就行,这样就得到一个远程仓库地址 2,仓库有文件,那么就需要先将这个文件pull下来: 在本地的项目目录中执行:git init git ...

  4. MySQL8.0.26安装与卸载

    一.安装 1.官网下载 百度进入官网,学习用社区版够了,我下的是压缩版点这直达下载页 据说8.X版本性能优化,比5.7版本快2倍! 接着,不登录直接下载 2.创建配置 下载完后,建议解压到一个没有中文 ...

  5. PAT甲级:1136 A Delayed Palindrome (20分)

    PAT甲级:1136 A Delayed Palindrome (20分) 题干 Look-and-say sequence is a sequence of integers as the foll ...

  6. 【模拟】选数 luogu-1037

    AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...

  7. java跨平台性说明

    一.举例说明 我们知道,只要是用标准C开发的程序,使用不同的编译器编译后的可执行文件是可以在对应平台运行的,比如windows可以使用VC编译,那编译后的exe文件就可以在windows下运行:liu ...

  8. Qt Creator内qmake配置静态编译

    起因 利用QT Creator编写一些纯C/C++应用,默认配置下是动态编译 解决 解决起来很简单,这里只是附上配置备忘;-) msvc: { QMAKE_CFLAGS_RELEASE += /MT ...

  9. 在Mac上安装Istio并使用,有丰富的监控Kiali、Grafana、Jaeger

    我最新最全的文章都在南瓜慢说 www.pkslow.com,文章更新也只在官网,欢迎大家来喝茶~~ 1 简介 之前在文章<服务网格Istio入门-详细记录Kubernetes安装Istio并使用 ...

  10. ElasticSearch进阶检索

    ElasticSearch进阶检索 入门检索中讲了如何导入elastic提供的样本测试数据,下面我们用这些数据进一步检索 一.SearchAPI ES 支持两种基本方式检索 : 1.一种是通过使用 R ...