《Inside C#》笔记(十五) 非托管代码 上
来源:互联网 发布:乐视电视需要网络吗 编辑:程序博客网 时间:2024/06/07 18:42
为了保证向后兼容性,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#》笔记(十五) 非托管代码 下
- 非托管代码,托管代码
- 托管代码&非托管代码
- 《Inside C#》笔记(十三) 多线程 上
- CLR Inside Out: Best Practices for Managed and Native Code Interoperability (托管/非托管代码互通性最佳实践)
- 托管与非托管代码
- 托管和非托管代码
- 代码托管与非托管
- 托管和非托管代码
- .net farmework(c#)安全代码 非安全代码 托管资源 非托管资源
- vs2008上进行托管代码与X64非托管代码调试问题
- 托管代码和非托管代码
- COM接口&托管代码&非托管代码
- 托管代码调用非托管代码
- 托管代码与非托管代码
- 托管代码与非托管代码
- 托管代码和非托管代码
- 深度学习与计算机视觉
- crontab定时任务
- mysql查询库所有表和字段
- 抽象类
- 内存对齐
- 《Inside C#》笔记(十五) 非托管代码 上
- Windows 64位下安装Redis详细教程
- 关于Promise与async/await的例子
- 大创log01(07/18)
- 使用springmvc的MultipartFile实现单文件和多文件上传
- 接口与多态
- c语言中的#号和##号的作用
- zxing二维码生成
- C++排序问题