重庆熊猫 Loading

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]);
}
posted @ 2022-09-24 09:16  重庆熊猫  阅读(220)  评论(0编辑  收藏  举报