为了保证向后兼容性,C#和.NET可以通过非托管的方式运行旧代码。非托管代码是指没有被.NET运行时管控的代码。非托管代码主要包括:平台调用服务(PlatformInvocation Services)、不安全代码(Unsafe Code)、COM互操作(COM interoperability)。

 

一 平台调用服务

平台调用服务(Platform Invocation Services)也被称作PInvoke,可以使用非托管DLL中的方法、结构甚至是给其传递回调函数。在使用非托管DLL前需事先了解DLL内部方法的参数和返回值。

a)基本使用方法为:

MessageBoxA属于Win32的API,需要先声明一个与MessageBoxA的方法签名一致的方法,然后DllImport导入这个DLL,签名方法必须用static extern修饰。

b)签名方法也可与DLL中的方法不同名,但需在DllImport的EntryPoint指定原始名称。

c)使用CharSet

CharSet可以指定DLL所使用的字符集。比如上述的MessageBoxA实际上对应的是Ansi编码,还有对应Unicode编码的MessageBoxW,除了直接指定调用哪个,还可用下面的写法:

编译器会根据CharSet的类型决定调用哪种MessageBox。这应该需要DLL内部做相应配合,至少需要知道每个MessageBox对应的字符集。

d)回调

不仅C#代码可以调用DLL的方法,DLL方法也可用回调的方式使用C#代码。

这里将PrintWindow作为回调函数传递给了API中的EnumWindows方法。

e)Marshal(排列、整理?)

在前面的例子中,DLL中MessageBox的方法参数为:

C#代码中的方法签名并没有与之完全匹配,但却能正常运行,这是因为编译器自动进行了默认的Marshal,比如将C#的string类型对应为Win32的LPSTR。这个过程也可以手动进行,使用MarshalAs:

如果要Marshal返回值,要标记在方法体上面。

二 编写不安全代码

这里的不安全代码指的是没有被.NET运行时托管的代码,内存的分配、释放、寻址等都不受约束,比如可以在C#代码中使用指针,在有些场合C#指针非常有用,比如需要调用C语言编写的API时、或者需要对内存有完全的控制时。

a)与不安全代码相关的关键字unsafe和fixed

unsafe关键字用来告知.NET运行时,相关的代码块将不受托管。不受托管的代码块可以是方法、属性、或者是一个方法内部的代码片段。

fix关键字用来“钉”(pinning)住某个对象,这样GC就不会尝试对其回收了。但对象在内存的地址不会被固定,地址仍然会被运行时浮动,以避免出现内存碎片。因为地址不固定,所以这时使用指针就要小心了。

b)在C#中使用指针

C#中的指针比较特殊:只能指向值类型、数组、字符串;如果指针指向数组,数组的第一个元素必须是值类型,因为指针实际上要指向的是这个数组的第一个元素;

C#中的指针相关的运算符与C、C++一样:&,取得某个对象的地址; *,取得对象的值; ->,取得对象中某个成员的值。简单示例为:

编译标记为unsafe的代码前,需要在项目属性中设置允许不安全代码。

学习资料:Inside C# by Tom Archer

《Inside C#》笔记(十五) 非托管代码 上的更多相关文章

  1. 《Inside C#》笔记(十五) 非托管代码 下

    二编写不安全代码 a)fixed关键字 代码中体现了fixed的用法:fixed (type* ptr= expression) { …}:type是类似int*这样的非托管类型或void类型,exp ...

  2. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  3. 使用Typescript重构axios(二十五)——文件上传下载进度监控

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  4. 学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. (C/C++学习笔记) 十五. 构造数据类型

    十五. 构造数据类型 ● 构造数据类型概念 Structured data types 构造数据类型 结构体(structure), 联合体/共用体 (union), 枚举类型(enumeration ...

  6. How tomcat works 读书笔记十五 Digester库 上

    Digester库 在前面的几个章节里,我们对tomcat里各个组件的配置完全是使用写硬编码的形式完成的. 如 Context context = new StandardContext(); Loa ...

  7. MySQL学习笔记十五:优化(2)

    一.数据库性能评测关键指标 1.IOPS:每秒处理的IO请求次数,这跟磁盘硬件相关,DBA不能左右,但推荐使用SSD. 2.QPS:每秒查询次数,可以使用show status或mysqladmin ...

  8. 【慕课网实战】Spark Streaming实时流处理项目实战笔记十五之铭文升级版

    铭文一级:[木有笔记] 铭文二级: 第12章 Spark Streaming项目实战 行为日志分析: 1.访问量的统计 2.网站黏性 3.推荐 Python实时产生数据 访问URL->IP信息- ...

  9. (转载)西门子PLC学习笔记十五-(数据块及数据访问方式)

    一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的 ...

随机推荐

  1. 利用nodejs安装并运行express的三个坑

    概述 这是我安装并运行express的三个坑,应该是比较常见的,在此记录一下. 内容 express不是内部或外部命令 输入命令:express -V 报错:'express' 不是内部或外部命令,也 ...

  2. Eclipse上搭建Spring的开发环境

    一.安装Spring Tool Suite插件 如图: 点击Finish之后等待安装,安装完之后弹窗点击yes重启Eclipse,重启后显示如下界面: 二.搭建Spring开发环境 1.导入jar包到 ...

  3. python中匿名函数lambda

    简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命 名一个函数的场合下使用,也就是指匿名函数. 先看它的几个用法: map( lambda x: x*x, [y f ...

  4. Spring Boot整合 Thymeleaf 模板引擎

    什么是Thymeleaf Thymeleaf是一款用于渲染XML.XHTML.HTML5内容的模板引擎.类似Velocity,FreeMaker模板引擎,它也可以轻易的与Spring MVC等Web框 ...

  5. LeetCode--No.007 Reverse Integer

    7. Reverse Integer Total Accepted: 153147 Total Submissions: 644103 Difficulty: Easy Reverse digits ...

  6. python itchat+机器人web api实现个人微信机器人

    模块 itchat 功能 实现微信回复机器人(调用图灵机器人api) 代码 #!/usr/bin/env python3 # -*- coding: utf-8 -*- #Author:Eric im ...

  7. spring boot -thymeleaf-字符串操作

    以下是一些小测试 <span th:text="${#strings.length(hi)}" ></span> <span th:text=&quo ...

  8. 自己动手实现爬虫scrapy框架思路汇总

    这里先简要温习下爬虫实际操作: cd ~/Desktop/spider scrapy startproject lastspider # 创建爬虫工程 cd lastspider/ # 进入工程 sc ...

  9. JavaScript “跑马灯”抽奖活动代码解析与优化(二)

    既然是要编写插件.那么叫做"插件"的东西肯定是具有的某些特征能够满足我们平时开发的需求或者是提高我们的开发效率.那么叫做插件的东西应该具有哪些基本特征呢?让我们来总结一下: 1.J ...

  10. Git学习系列之Windows上安装Git详细步骤(图文详解)

    前言 最初,Git是用于Linux下的内核代码管理.因为其非常好用,目前,已经被成功移植到Mac和Windows操作系统下. 鉴于大部分使用者使用的是Windows操作系统,故,这里详细讲解Windo ...