《Inside C#》笔记(十五) 非托管代码 上
为了保证向后兼容性,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#》笔记(十五) 非托管代码 上的更多相关文章
- 《Inside C#》笔记(十五) 非托管代码 下
二编写不安全代码 a)fixed关键字 代码中体现了fixed的用法:fixed (type* ptr= expression) { …}:type是类似int*这样的非托管类型或void类型,exp ...
- python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...
- 使用Typescript重构axios(二十五)——文件上传下载进度监控
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- (C/C++学习笔记) 十五. 构造数据类型
十五. 构造数据类型 ● 构造数据类型概念 Structured data types 构造数据类型 结构体(structure), 联合体/共用体 (union), 枚举类型(enumeration ...
- How tomcat works 读书笔记十五 Digester库 上
Digester库 在前面的几个章节里,我们对tomcat里各个组件的配置完全是使用写硬编码的形式完成的. 如 Context context = new StandardContext(); Loa ...
- MySQL学习笔记十五:优化(2)
一.数据库性能评测关键指标 1.IOPS:每秒处理的IO请求次数,这跟磁盘硬件相关,DBA不能左右,但推荐使用SSD. 2.QPS:每秒查询次数,可以使用show status或mysqladmin ...
- 【慕课网实战】Spark Streaming实时流处理项目实战笔记十五之铭文升级版
铭文一级:[木有笔记] 铭文二级: 第12章 Spark Streaming项目实战 行为日志分析: 1.访问量的统计 2.网站黏性 3.推荐 Python实时产生数据 访问URL->IP信息- ...
- (转载)西门子PLC学习笔记十五-(数据块及数据访问方式)
一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的 ...
随机推荐
- Java的组合排列问题
从4个人中选2个人参加活动,一共有6种选法. 从n个人中选m个人参加活动,一共有多少种选法?C(m/n)=C((m-1)/(n-1))+C(m/(n-1))数学算法 public class Main ...
- 脚手架vue-cli系列三:vue-cli工程webpack的作用和特点
Vue项目开发过程中,会因为很多不同的实际运用需求不断地对webpack配置进行修改,在此之前,我们需要对webpack有一个基本的认识,了解它到底能为我们做些什么 webpack是一个模块打包的工具 ...
- interface21 - web - Log4jConfigListener(Log4j加载流程)
前言 最近打算花点时间好好看看spring的源码,然而现在Spring的源码经过迭代的版本太多了,比较庞大,看起来比较累,所以准备从最初的版本(interface21)开始入手,仅用于学习,理解其设计 ...
- Kafka项目实战-用户日志上报实时统计之编码实践
1.概述 本课程的视频教程地址:<Kafka实战项目之编码实践> 该课程我以用户实时上报日志案例为基础,带着大家去完成各个KPI的编码工作,实现生产模块.消费模块,数据持久化,以及应用调 ...
- SQL 必知必会·笔记<9>使用子查询
子查询(subquery),即嵌套在其他查询中的查询. 1. 利用子查询进行过滤 SELECT 语句中,子查询总是从内向外处理.示例: SELECT cust_name, cust_contact F ...
- cmd命令窗口连接mysql的命令大全
连接:mysql -h主机地址 -u用户名 -p用户密码 (注:u与root可以不用加空格,其它也一样)断开:exit (回车) 创建授权:grant select on 数据库.* to 用户名@登 ...
- lightswitch Grid 控件添加 CheckBox 多选
ACTIVATING MULTI SELECTION WITH CHECKBOXES IN A LIGHTSWITCH GRID WITH A ONE-LINER 2013/04/02 · by pa ...
- springboot + freemarker 实现国际化
前言 写过一篇springboot+freemarker国际化过程中的细节问题,但没有写过具体的国际化实现过程.正好有人在问,我就把我实现的过程贴出来,即使自己知识的一个备份,如果对别人有点用,那是再 ...
- JWT 从入门到精通
什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...
- ssh隧道的妙用
场景说明:A主机和B主机在同一个园区网,A主机可以出公网,B主机不可以出公网.渗透工程师已经拿下A主机控制权. 一.如何在外网访问到B主机 方案:ssh本地端口映射背景:当我们拿下A主机之后想和B主机 ...