首页 > 编程语言 >C#教程 - 不安全的代码和指针(Unsafe Code and Pointers)

C#教程 - 不安全的代码和指针(Unsafe Code and Pointers)

时间:2022-09-24 09:35:18浏览次数:49  
标签:Code C# Unsafe 代码 unsafe int Test test fixed

更新记录
转载请注明出处:
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]);
}

标签:Code,C#,Unsafe,代码,unsafe,int,Test,test,fixed
From: https://www.cnblogs.com/cqpanda/p/16715167.html

相关文章

  • C#教程 - 元组与解构(Tuples and Deconstruction )
    更新记录转载请注明出处:2022年9月24日发布。2022年9月10日从笔记迁移到博客。元组(tuples)说明注意:C#7.0可用注意:元组不可以声明为静态类型作用:元组常用于传递和......
  • c++ -- 做题思想
    二分思想:比较显然的就是求某一个确定的值,那么看看他是不是单调的,连续的.        其次就是,把问题通过二分来进行转化,之前的不好做,通过二分转化一......
  • CSharp: Facade Patterns
     ///<summary>///SummarydescriptionforDBTable.///外观模式FacadePatterns///20220918///geovindu,GeovinDu,涂聚文///</summ......
  • CentOS7安装Git
    目录参考资料下载地址步骤1.下载包2.git-2.9.5.tar.gz和git-manpages-2.9.5.tar.gz上传服务器3.解压并编译参考资料官网GitProBook安装说明下载地址https://gi......
  • UEC++ 多线程(一) FRunnable
    虚幻官方文档:https://docs.unrealengine.com/5.0/en-US/API/Runtime/Core/HAL/FRunnable/FRunnable“runnable”对象的接口。可运行对象是在任意线程上“运行”的对象......
  • let、const和var的区别(涉及块级作用域)
    let、const和var的区别let、const、var在js中都是用于声明变量的,在没有进行ES6的学习前,我基本只会使用到var关键字进行变量的声明,但在了解了ES6之后就涉及到了块级作用域......
  • Mac系统睡眠掉电问题
    查看Mac休眠模式打开启动台→其他→终端;复制命令:pmset-g,在终端窗口粘贴后回车,如果提示输入「password」,直接输入自己的开机密码,密码是不会显示出来的,直接输入就行,输完......
  • Ubuntu20/mint20安装vnc
    #安装和配置TigerVNCServersudoaptinstalltightvncserver-y#如你没有一个普通用户,则需要建立一个普通用户,用于VNC登录桌面(可选):adduseruservncsu-uservnc......
  • C语言:求1/2,2/3,3/5,5/8,8/13,13/21,21/34...前20项和
    #include<stdio.h>//求1/2,2/3,3/5,5/8,8/13,13/21,21/34...前20项和main(){inta,c=1;doublesum=0,b=1.0,d,e,f=1,g=2;for(a=1;a<=20;a++){......
  • Java学习-第一部分-第三阶段-第四节:JDBC和数据库连接池
    JDBC和数据库连接池笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html)下载会使用到的包JDBC概述基本介绍JDBC为访问不同的数据库提供了统一的接口,为使......