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

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

 

一致
平台调用服务

阳台调用服务(Platform
Invocation
Services)也深受号称PInvoke,可以使非托管DLL中之艺术、结构还是叫其传递回调函数。在采取非托管DLL前待先了解DLL内部方法的参数与归值。

a)基本用方式吧:

 

C# 1

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

 

b)签名方法也可是和DLL中的计不同名,但得于DllImport的EntryPoint指定原始名称。

 

 

C# 2

 

c)使用CharSet

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

 

C# 3

 

 

编译器会冲CharSet的类别决定调用哪种MessageBox。这应该用DLL内部做相应匹配,至少要明白每个MessageBox对应的字符集。

 

d)回调

不仅C#代码可以调用DLL的道,DLL方法吗可用回调的计使用C#代码。

 

此地拿PrintWindow作为回调函数传递给了API中之EnumWindows方法。

 

C# 4

 

e)Marshal(排列、整理?)

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

 

C# 5

 

 

C#代码中的办法签名并不曾同之了配合,但可能正常运行,这是因编译器自动进行了默认的Marshal,比如以C#的string类型对承诺为Win32底LPSTR。这个过程吧得手动进行,使用MarshalAs:

 

C# 6

 

若一旦Marshal返回值,要记在方法体上面。

 

第二
编写不安全代码

此地的莫安全代码指的是从未被.NET运行时托管的代码,内存的分配、释放、寻址等都不吃拘束,比如可以在C#代码中采取指针,在小场合C#指南针非常有因此,比如要调用C语言编写的API时、或者用对内存有完全的操纵时。

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

unsafe关键字用来告知.NET运行时,相关的代码块用未深受托管。不被托管的代码块好是办法、属性、或者是一个主意中的代码有。

fix关键字用来“钉”(pinning)住某对象,这样GC就未会见尝试对该回收了。但目标在内存的地点不会见叫一定,地址仍然会让运行时转,以避免出现内存碎片。因为地方不固定,所以这时用指针就要小心了。

b)在C#饱受采用指针

C#备受的指针比较独特:只能凭借于值类型、数组、字符串;如果指针指为数组,数组的率先个要素必须是值类型,因为指针实际上只要对的是这个数组的首先只要素;

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

 

C# 7

 

 

编译标记为unsafe的代码前,需要以项目性质被安允许请勿安全代码。

 

上学材料:Inside C# by Tom Archer

 

相关文章