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

为了保障向后包容性,C#和.NET能够由此非托管的点子运营旧代码。非托管代码是指没有被.NET运营时管理控制的代码。非托管代码首要包涵:平台调用服务(PlatformInvocation
Services)、不安全代码(Unsafe Code)、COM互操作(COM
interoperability)。

 


平台调用服务

阳台调用服务(Platform
Invocation
Services)也被称作PInvoke,能够选拔非托管DLL中的方法、结构依旧是给其传递回调函数。在行使非托管DLL前需事先明白DLL内部方法的参数和重回值。

a)基本使用方法为:

 

图片 1

Message博克斯A属于Win32的API,要求先声明一个与MessageBoxA的办法签名一致的点子,然后DllImport导入那些DLL,签名方法必须用static
extern修饰。

 

b)签名方法也可与DLL中的方法差异名,但需在DllImport的EntryPoint钦赐原始名称。

 

 

图片 2

 

c)使用CharSet

CharSet能够钦点DLL所运用的字符集。比如上述的MessageBoxA实际上对应的是Ansi编码,还有对应Unicode编码的MessageBoxW,除了直接钦定调用哪个,还可用上边的写法:

 

图片 3

 

 

编写翻译器会依据CharSet的花色决定调用哪一类MessageBox。那应当要求DLL内部做相应匹配,至少供给通晓各类Message博克斯对应的字符集。

 

d)回调

不仅C#代码能够调用DLL的法门,DLL方法也可用回调的法门使用C#代码。

 

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

 

图片 4

 

e)Marshal(排列、整理?)

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

 

图片 5

 

 

C#代码中的方法签名并不曾与之完全匹配,但却能健康运作,那是因为编写翻译器自动进行了暗中认可的马尔斯hal,比如将C#的string类型对应为Win32的LPST奥迪Q5。那一个进程也得以手动进行,使用马尔斯halAs:

 

图片 6

 

借使要马尔斯hal重临值,要标记在方法体上边。

 


编写不安全代码

此间的不安全代码指的是不曾被.NET运维时托管的代码,内部存款和储蓄器的分配、释放、寻址等都不受约束,比如能够在C#代码中接纳斯达克综合指数针,在多少地方C#指南针万分有用,比如须求调用C语言编写的API时、或许要求对内部存款和储蓄器有完全的操纵时。

a)与不安全代码相关的首要性字unsafe和fixed

unsafe关键字用来告知.NET运营时,相关的代码块将不受托管。不受托管的代码块能够是措施、属性、大概是2个措施内部的代码片段。

fix关键字用来“钉”(pinning)住有些对象,那样GC就不会尝试对其回收了。但指标在内部存款和储蓄器的地址不会被一定,地址依然会被周转时浮动,以免止出现内部存储器碎片。因为地址不稳定,所以那时候使用指针就要小心了。

b)在C#中选用指针

C#中的指针相比奇特:只好指向值类型、数组、字符串;假若指针指向数组,数组的率先个成分必须是值类型,因为指针实际上要指向的是那一个数组的首先个要素;

C#中的指针相关的运算符与C、C++一样:&,取得有些对象的地点;
*,取得对象的值;
->,取得对象中有些成员的值。容易示例为:

 

图片 7

 

 

编写翻译标记为unsafe的代码前,须求在档次性质中设置允许不安全代码。

 

上学资料:Inside C# by Tom Archer

 

相关文章