.NET Framework 2.0 组件和非托管代码与交互操作详解(转)

     .NET Framework 将促进与 COM 组件、COM+ 服务、外部类型库和许多操作系统服务的交互操作。在托管和非托管对象模型之间,数据类型、方法签名和错误处理机制都存在差异。为了简化 .NET Framework 组件和非托管代码之间的互用并便于进行移植,公共语言运行时将从客户端和服务器中隐藏这两种对象模型之间的差异。

      在运行时控制下执行的代码称作托管代码。相反,在运行时之外运行的代码称作非托管代码。COM 组件、ActiveX 接口和 Win32 API 函数都是非托管代码的示例。

  与非托管代码交互操作

NET Framework比其他开发平台多提供了很多先进技术, 然而, 很少公司能承受起重新设计和重新实现所有的代码. 微软意识到这点, 因此构建了CLR来提供一种机制允许应用程序可以包含托管代码和非托管的代码. 特别地, CLR支持三种交互场景:

   托管代码可以调用DLL中的非托管的函数: 托管代码可以很容易地调哟哦能够包含在DLL中的函数, 这是通过使用一种称为P/Invoke (Platform Invoke) 的机制来实现的. 毕竟, 定义在FCL中的很多类型都内部调用了Kernel32.dll, User32.dll等中的函数. 很多编程语言将暴露一种机制使得托管代码很容易调用包含在DLL中的非托管函数. 例如, 一个C#应用程序可以调用Kernel32.dll中的CreateSemaphore函数.

   托管代码可以使用COM组件(server): 很多公司已经实现了很多非托管的COM组件, 使用这些组件中的类型, 可以创建用于描述COM组件的托管的程序集, 托管的代码可以访问这些程序集中的托管的类型, 这就和访问其他托管类型一样. 参考与.NET Framework SDK一起发布的Tlbimp.exe工具. 有时候, 你可能没有一个类型库或者你想对TlbImp.exe产生的东西获得更多的控制, 这样, 你可以手动地构建一个类型, 让CLR可以使用这个类型来实现适当的互操作. 例如, 你可以在C#应用程序中使用DirectX COM组件.

   非托管的代码可以使用托管的类型(server): 很多现有的非托管的代码需要你提供COM组件才能让代码正常地工作. 很容易通过托管代码来实现这些组件, 这样你可避免代码必须处理引用计数和接口. 例如, 你可以用C#创建一个ActiveX控件或者shell extension. 参考TlbExp.exe和RegAsm.exe工具.

    
      除了这些场景, 微软的C++/CLI编译器(version 14)支持一个新的/clr命令行开关, 这个开关告诉编译器产生IL代码, 而不是native CPU指令. 如果你有大量已有的C++代码, 你可以使用这个新编译开关重新编译这些代码, 新的代码需要CLR才能执行, 你可以修改代码来充分利用CLR特有的功能.

但是对于下面的方法, /clr开关目前还不能将它们编译成IL代码: 包含内联汇编语言(通过关键字__asm实现); 接受可变数目参数的方法; 调用setjmp的方法; 包含一些内部程序(intrinsic routine)(例如__enable, __disable, __ReturnAddress, __AddressOfReturnAddress)的方法. 对于C++/CLI编译器不能编译成IL的完整列表, 可以参考关于编译器的文档. 当编译器不能编译成IL时, 它会将方法编译成x86代码, 使得应用程序仍然能运行.

记住尽管产生的IL代码是托管的, 但是数据并不是, 也就是说数据对象不是从托管堆上分配的, 因此它们不能使用垃圾回收机制. 实际上, 数据类型没有包含在metadata中, 并且这些类型的方法名仍然需要经过C++签名编码中转换(mangle).

下面的C代码调用了标准C运行时库函数printf, 也调用了System.Console.WriteLine方法, System.Console类型定义在FCL中, 因此C/C++代码可以使用.

#include <stdio.h> // For printf

#using <mscorlib.dll> // For managed types defined in this assembly

using namespace System; // Easily access System namespace types

// Implement a normal C/C++ main function

void main() {

// Call the C runtime library's printf function.

printf("Displayed by printf.\r\n");

// Call the FCL's System.Console's WriteLine method.

Console::WriteLine("Displayed by Console::WriteLine.");

}

编译这段代码不是很容易, 如果这个代码是在文件ManagedCApp.cpp中, 你会执行如下的命令来编译它:

cl /clr ManagedCApp.cpp

结果是ManagedCApp.exe程序集文件, 如果你运行ManagedCApp.exe, 你将会看到如下的输出:

C:\>ManagedCApp

Displayed by printf.

Displayed by Console::WriteLine.

如果你使用ILDasm.exe来检查这个文件, 你将会看到定义在这个程序集中的所有的全局函数和全局字段, 显然地, 编译器自动地产生了很多填充代码. 如果你双机Main函数, ILDasm会为你显示出IL代码.

.method assembly static int32

modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) main() cil managed

{

  .vtentry 70 : 1

  // Code size 23 (0x17)

  .maxstack 1

  IL_0000: ldsflda valuetype '<CppImplementationDetails>' .$ArrayType$$$BY0BH@$$CBD

                       modopt([mscorlib]System.Runtime.CompilerServices.IsConst)

                       '??_C@_0BH@GBHlFCOF@Displayed?5by?5printf?4?$AN?6?$AA@'

  IL_0005: call     vararg int32

                       modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)

                       printf(

                         int8

                         modopt(

                           [mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte)

                         modopt(

                           [mscorlib]System.Runtime.CompilerServices.IsConst)*

                        )

  IL_000a: pop

  IL_000b: ldstr "Displayed by Console::WriteLine"

  IL_0010: call void [mscorlib]System.Console::WriteLine(string)

  IL_0015: ldc.i4.0

  IL_0016: ret

} // end of method 'Global Functions'::main

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/libright/archive/2009/03/04/3957359.aspx

 

转载于:https://www.cnblogs.com/elock/archive/2009/09/02/1558902.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 删除远程分支和本地分支

删除远程分支和本地分支 https://www.cnblogs.com/luosongchao/p/3408365.html 将远程git仓库里的指定分支拉取到本地&#xff08;本地不存在的分支&#xff09; https://www.cnblogs.com/hamsterPP/p/6810831.html 转载于:https://www.cnblogs.com/mafeng/p/10619419.html

从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装

标题&#xff1a;从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装 作者&#xff1a;Lamond Lu 地址&#xff1a;https://www.cnblogs.com/lwqlun/p/11343141.html 源代码&#xff1a;https://github.com/lamondlu/Mystique 前情回顾 从零开始实现ASP.NET Core MVC的插…

立体导航翻转案例

<div class"box"><!-- 立方体 --><ul><li><img src"img1/1.jpg" alt""></li><li><img src"img1/2.jpg" alt""></li><li><img src"img1/3.jpg" a…

Uncontrolled memory mapping in camera driver (CVE-2013-2595)

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主同意不得转载。https://blog.csdn.net/hu3167343/article/details/34434235 /* 本文章由 莫灰灰 编写&#xff0c;转载请注明出处。 作者&#xff1a;莫灰灰 邮箱&#xff1a; minzhenfei163.com */ 1漏洞描写…

表格隔行变色

<body><table border"0" align"center" cellspacing"1" cellpadding"0"><caption>恭喜发财</caption><thead><tr><th>代码</th><th>名称</th><th>最新公布净值<…

启动Cognos时报0106错误

1. 问题描述 启动Cognos失败&#xff0c;报错代码为0106。 2. 问题分析 是jdk版本不兼容。 3. 解决方案 方案一&#xff1a;更换jdk1.6&#xff0c;可以使用免安装版&#xff0c;不需要卸载原有的jdk将java_home的路径替换成jdk1.6的路径。 方案二&#xff1a;使用Cognos自带jd…

项目管理的测试版发布

最近有时间将以前没有写完的项目管理程序进一步完善&#xff0c;加入了项目任务之间的关连。功能&#xff1a;1、任务的关连Start to finishStart to startFinish to startFinish to finish2、任务关连表环路检测3、采用MVC模式进行开发4、自动导出XML5、双击连接线可以设置、删…

剑指offer.机器人的运动范围

地上有一个 m 行和 n 列的方格&#xff0c;横纵坐标范围分别是 0∼m−1 和 0∼∼n−1。一个机器人从坐标0,0的格子开始移动&#xff0c;每一次只能向左&#xff0c;右&#xff0c;上&#xff0c;下四个方向移动一格。但是不能进入行坐标和列坐标的数位之和大于 kk 的格子。请问…

Tab栏切换布局分析

<body><div class"tab"><div class"tab_list"><ul><li class"current">商品介绍</li><li>规格与包装</li><li>售后包装</li><li>商品评价(50000)</li><li>手机社…

CLR基础,CLR运行过程,使用dos命令创建、编译、运行C#文件,查看IL代码

CLR是Common Language Runtime的缩写&#xff0c;是.NET程序集或可执行程序运行的一个虚拟环境。CLR用于管理托管代码&#xff0c;但是它本身是由非托管代码编写的&#xff0c;并不是一个包含了托管代码的程序集&#xff0c;所以不能使用IL DASM进行查看&#xff0c;但CLR以dll…

表单的全选取消全选

<div class"wrap"><table border"1" cellspacing"0" cellpadding"0"><caption>恭喜发财</caption><thead><tr><th><input type"checkbox" id"j_cbAll" checked&quo…

VUE 数据绑定模块渲染 computed(实现通过路由id 查询数据json结构,对应的值来放在面包屑中)...

异步请求的值放在vuex中&#xff0c;然后页面挂载该数据和渲染页面 computed 计算属性是基于它的依赖缓存的。计算属性在它的相关依赖发生改变时会重新取值&#xff0c;所以当ajax请求回来的数据发生变化时&#xff0c;计算属性的值会进行更新&#xff0c;相关的模板引用也会重…

ThinkJs笔记琐碎

ThinkJs笔记琐碎 记录一些琐碎的在使用ThinkJs遇到的问题 静态资源访问 ThinkJs默认production环境关闭对www下资源的相对路径的访问&#xff0c;官方建议通过nginx转向的地址的绝对路径访问&#xff0c;想要在production环境访问相对路径的话需要到src/config/middleware.js里…

js(Dom+Bom)第二天(1)

JavaScript-DOM操作 核心知识点 className操作标签样式style属性方式操作标签样式操作表单控件 学习目标 能够通过className方式给标签设置样式能够通过style方式给标签设置样式能够获取表单控件中的值 操作元素样式 语法&#xff1a;1.dom.className 类名;2.dom.style.属…

HDU 4339 Query

算法: 比赛时没有想到好的算法&#xff0c;暴力是O&#xff08; Q * N &#xff09;肯定超时。 赛后&#xff0c;线段树&#xff0c;树状数组&#xff0c;HASH都能AC&#xff0c;想了下&#xff0c;的确用树状数组 时间复杂度就可以优化到O&#xff08;Q * lgN * lgN) 2000msAC…

201904快速阅读术

在看过了几本数之后&#xff0c;发现原来培养读书的习惯好像也不太难&#xff0c;“将读书融入生活&#xff0c;框定读书时间” 生活中&#xff0c;我确实也是这样执行了。利用每天上下班的时间听书&#xff0c;有些觉得可以读快的书籍用了1.5倍速度在听&#xff0c;难懂的部分…

js(Dom+Bom)第二天(2)

webAPI 00-操作图片 知识点-获取图片src属性 图片对象.src ----> 获取图片路径注意: 1. 获取到的图片路径是一个绝对路径知识点-动态的给图片标签设置路径 图片对象.src 图片路径;注意: 1.可以设置绝对路径(不推荐) 2.可以设置相对路径课堂案例-切换图片案例 01-操作标…

javaScript今日总结

javascript简单介绍ECMAScript 1.语法 2.变量&#xff1a;只能使用var定义&#xff0c;如果在函数的内容使用var定义&#xff0c;那么它是一个局部变量&#xff0c;如果没有使用var它是一个全局的。弱类型&#xff01; 3.数据类型&#xff1a;原始数据类型(undefined/null/stri…

使用Connector / Python连接MySQL/查询数据

使用Connector / Python连接MySQL connect()构造函数创建到MySQL服务器的连接并返回一个 MySQLConnection对象 在python中有以下几种方法可以连接到MySQL数据库&#xff1a; 1.使用connect&#xff08;&#xff09;构造函数import mysql.connectorcnx mysql.connector.connect…

最简方式 表格编辑 基于 el-table

共下面5点1.新增一个显示和隐藏的参数2.在显示那边新增一个input框&#xff0c;用v-model绑定数据&#xff0c;用v-if来显示和隐藏3.给之前的显示的span标签添加v-else 和上面形成if else4.编辑和保存按钮同理&#xff0c;然后编辑按钮触发的任务将所有输入打开。即seen置为tru…