C#教程 - 不安全的代码和指针(Unsafe Code and Pointers)
更新记录
转载请注明出处:
2022年9月24日 发布。
2022年9月10日 从笔记迁移到博客。
平台互操作
说明
C#通过4种方式实现直接调用外部代码:
通过平台调用(Platform Invoke,P/Invoke)调用非托管DLL
通过不安全的代码(unsafe code)直接使用C/C++代码访问内存
通过Windows Runtime(WinRT) API调用操作系统函数,仅支持Win8以上系统
通过COM互操作
平台调用(Platform Invoke,P/Invoke)
说明
命名空间
using System.Runtime.InteropServices;
外部函数声明
语法:
为方法添加static extern修饰符
方法不可以包含主体
使用[DllImport]特性指定具体的底层实现
使用DllImport特性的EntryPoint指定底层的函数名
实例:
使用不安全的代码(unsafe code)
说明
C#支持直接使用指针操作内存数据
只需要为代码块标记unsafe和编译时使用/unsafe参数
使用场景:
调用C/C++的代码
对性能要求非常高的代码
指针常用运算符
Operator Meaning
& The address-of operator returns a pointer to the address of a variable
* The dereference operator returns the variable at the address of a pointer
-> The pointer-to-member operator is a syntactic shortcut, in which x->y is equivalent to (*x).y
语法
在type、type member、statement block前使用unsafe关键字即可
实例:
unsafe void BlueFilter (int[,] bitmap)
{
int length = bitmap.Length;
fixed (int* b = bitmap)
{
int* p = b;
for (int i = 0; i < length; i++)
*p++ &= 0xFF;
}
}
fixed语句(The fixed Statement)
如果一个对象的地址在引用时可能发生变化,那么指向该对象是徒劳的
因此fixed语句告诉GC“固定”该对象,不要移动它
这可能会影响运行时的效率,因此应只简单地使用固定块,并且应该避免在固定块中分配堆
实例:使用fixed固定内存,防止被GC回收
Test test = new Test();
unsafe
{
fixed (int* p = &test.x) // Pins test
{
*p = 9;
}
System.Console.WriteLine (test.x);
}
实例:使用指针访问成员
unsafe static void Main()
{
Test test = new Test();
Test* p = &test;
p->x = 9;
System.Console.WriteLine (test.x);
}
分配内存
使用stackalloc关键字进行分配内存
实例:分配一个数组
int* a = stackalloc int [10];
for (int i = 0; i < 10; ++i)
{
Console.WriteLine (a[i]); // Print raw memory
}
实例:配合span<>一起使用
Span<int> a = stackalloc int [10];
for (int i = 0; i < 10; ++i)
{
Console.WriteLine (a[i]);
}
本文来自博客园,作者:重庆熊猫,转载请注明原文链接:https://www.cnblogs.com/cqpanda/p/16715167.html