为了保证向后兼容性,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. eclipse——JDK安装与环境变量配置步骤

    第一次接触eclipse的时候,让我自己安装jdk和配置环境变量,我是懵逼的,后来百度到找到了一个比较详细的引导,本人测试没问题,截图按步骤如下: JDK安装   步骤1: 步骤2: 配置环境变量 步 ...

  2. Rip配置

    Rip配置 首先建立如图拓扑图 分别配置两台电脑的ip地址和子网掩码和网关.如图所示. 在router0上配置两个端口的IP以及子网掩码 在路由器router0上配置rip2协议.里面的no auto ...

  3. FC游戏 《三国志2-霸王的大陆》攻略

    <三国志2-霸王的大陆>是日本南梦宫公司研发的一款历史战略模拟游戏,于1992年06月10日在红白机平台上发行. 在开始游戏选择君主时(一定要在君主未出现前的画面时进行第二步),按住1P的 ...

  4. apache log4j打印日志源码出口

    Throwable.class: public void printStackTrace(PrintStream s) { synchronized (s) { s.println(this); St ...

  5. Java 8 新特性-菜鸟教程 (7) -Java 8 Nashorn JavaScript

    Java 8 Nashorn JavaScript Nashorn 一个 javascript 引擎. 从JDK 1.8开始,Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java ...

  6. AOP技术基础(转)

    1.引言 2.AOP技术基础 3.Java平台AOP技术研究 4..Net平台AOP技术研究 2.1 AOP技术起源 AOP技术的诞生并不算晚,早在1990年开始,来自Xerox Palo Alto ...

  7. 网络基础知识-TCP/IP协议各层详解

    TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...

  8. SpringMVC+jquery.uploadify 上传文件

    前言 以前用Asp.net MVC+uploadify上传文件,最近学习SpringMVC,所以就用SpringMVC+uploadify做个上传文件的demo. 刚开始用form表单的方式提交,在C ...

  9. Apollo 4 客户端 SDK 设计

    前言 之前聊了客户端的一些功能,例如融入 Spring, @value 注解的自动刷新实现,长轮询等,这次从客户端的整体设计来聊聊. 设计 上图是 client 项目的包结构. 其中,核心包就是 in ...

  10. jquery 截取屏幕

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...