C#编程之C# 非托管代码
小标 2018-10-22 来源 : 阅读 1812 评论 0

摘要:本文主要向大家介绍了C#编程之C# 非托管代码,通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

本文主要向大家介绍了C#编程之C# 非托管代码,通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

.Net Framework 是由彼此独立又相关的两部分组成:CLR 和 类库, CLR是它为我们提供的服务,类库是它实现的功能..NET的大部分特性----垃圾收集,版本控制,线程管理等,都使用了CLR提供的服务
托管代码
 
托管代码(Managed Code)实际上就是中间语言(IL)代码。代码编写完毕后进行编译,此时编译器把代码编译成中间语言(IL),而不是能直接在你的电脑上运行的机器码。程序集(Assembly)的文件负责封装中间语言,程序集中包含了描述所创建的方法、类以及属性的所有元数据。托管代码在公共语言运行库(CLR)中运行。CLR提供了一个实时编译器,用来把IL代码编译为本机机器代码.这样一来,CLR能够使代码变得可移植,因为.NET应用程序的源代码必须被编译为IL代码,这些IL代码可以运行在任何提供CLR服务的平台上.从CLR的角度来看,所有的语言都是平等的,只要有一个能生成IL代码的编译器就行,这就确保了各种语言的互操性.
非托管代码
在公共语言运行库环境的外部,由操作系统直接执行的代码。非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务,它与托管代码不同,后者从公共语言运行库中获得这些服务,而非托管代码是在运行库之外运行的代码。例如COM 组件、ActiveX 接口和 Win32 API 函数都是非托管代码的示例。
区别:
     1、托管代码是一种中间语言,运行在CLR上;
          非托管代码被编译为机器码,运行在机器上。
     2、托管代码独立于平台和语言,能更好的实现不同语言平台之间的兼容;
          非托管代码依赖于平台和语言。
     3、托管代码可享受CLR提供的服务(如安全检测、垃圾回收等),不需要自己完成这些操作;
          非托管代码需要自己提供安全检测、垃圾回收等操作。
.net的堆就是托管堆.没有非托管堆.引用类型的引用目标就是在堆里.
值类型的值就在栈里.
所谓的系统资源.是指:网络连接,数据库连接.文件流.这种东西.
这里的托管就是指被CLR管理,托管堆就是被CLR管理的堆。非托管资源需要手动释放,托管资源由GC帮你打理。
using可以跟踪非托管资源周期内的活动,一旦发现非托管资源生命结束了,就会强制调用dispose方法去释放在该作用域的非托管资源的内存。
C#如何直接调用非托管代码,通常有2种方法:
1.  直接调用从 DLL 导出的函数。
2.  调用 COM 对象上的接口方法
从dll中导出函数:
a.使用 C# 关键字 static 和 extern 声明方法。
b.将 DllImport 属性附加到该方法。DllImport 属性允许您指定包含该方法的DLL 的名称。
c.如果需要,为方法的参数和返回值指定自定义封送处理信息,这将重写 .NET Framework 的默认封送处理。

using System;

using System.Runtime.InteropServices;

    public class MSSQL_ServerHandler

    {

        [DllImport("kernel32.dll")]

        public static extern int GetShortPathName

        (

            string path,

            StringBuilder shortPath,

            int shortPathLength

)

     }

DllImportAttribute 的字段
 




字段


说明




BestFitMapping


启用或禁用最佳匹配映射。




CallingConvention


指定用于传递方法参数的调用约定。默认值为 WinAPI,该值对应于基于 32 位 Intel 的平台的 __stdcall。




CharSet


控制名称重整以及将字符串参数封送到函数中的方式。默认值为 CharSet.Ansi。




EntryPoint


指定要调用的 DLL 入口点。




ExactSpelling


控制是否应修改入口点以对应于字符集。对于不同的编程语言,默认值将有所不同。




PreserveSig


控制托管方法签名是否应转换成返回 HRESULT 并且返回值有一个附加的 [out, retval] 参数的非托管签名。
默认值为 true(不应转换签名)。




SetLastError


允许调用方使用 Marshal.GetLastWin32Error API 函数来确定执行该方法时是否发生了错误。在 Visual Basic 中,默认值为 true;在 C# 和 C++ 中,默认值为 false。




ThrowOnUnmappableChar


控件引发的异常,将无法映射的 Unicode 字符转换成一个 ANSI"?"字符。
 




 
 
StructLayoutAttribute类
在C/C++中,struct类型中的成员的一旦声明,则实例中成员在内存中的布局(Layout)顺序就定下来了,即与成员声明的顺序相同,并且在默认情况下总是按照结构中占用空间最大的成员进行对齐(Align);当然我们也可以通过设置或编码来设置内存对齐的方式.在.net托管环境中,CLR提供了更自由的方式来控制struct中Layout:我们可以在定义struct时,在struct上运用StructLayoutAttribute特性来控制成员的内存布局
 
C#提供了一个StructLayoutAttribute类,通过它你可以定义自己的格式化类型,在受管辖代码中,格式化类型是一个用StructLayoutAttribute说明的结构或类成员,通过它能够保证其内部成员预期的布局信息。布局的选项共有三种:布局选项  描述  LayoutKind.Automatic  为了提高效率允许运行态对类型成员重新排序。  注意:永远不要使用这个选项来调用不受管辖的动态链接库函数。  LayoutKind.Explicit  对每个域按照FieldOffset属性对类型成员排序  LayoutKind.Sequential  对出现在受管辖类型定义地方的不受管辖内存中的类型成员进行排序。
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
 
 
COM interop具体操作:
a. 用atl写com服务程序
b. 使用Tlbimp将atl写的com程序转换成 COM DLL
   用如下命令:
   tlbimp 你写的com.dll
   tlbimp是 .NETFramework SDK中附带的类型库导入程序。用这个命令即是把生成一个非托管com dll的托管包装。
c. 托管客户端非常简单
   直接new一下,然后调用对应的方法即可。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C#.NET频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程