網站首頁 編程語言 正文
固定大小的緩沖區 - Fixed-size buffers
可以使用 fixed
關鍵字創建在數據結構中具有固定大小的數組的緩沖區(buffer
)。當編寫與其他語言或平臺的數據源進行互操作的方法時,固定大小的緩沖區很有用。
在可以使用常規結構成員(regular struct members
)的任何屬性或修飾符上都可以使用fixed-size buffer
。
唯一的限制是數組類型必須為基礎類型 bool、byte、char、short、int, long、sbyte、ushort、uint、ulong、float 或 double。
比如:
private fixed char name[30];
在安全代碼中,包含數組的C#結構不會包含任何數組元素,結構只是包含到元素的引用。
在unsafe
代碼塊中,可以為struct
添加固定大小的數組。
下面 PathArray
struct
的大小不取決于數組元素的數量,因為是pathName
引用變量:
public struct PathArray { public char[] pathName; private int reserved; }
不安全代碼中,struct
結構可以包含嵌入的數組。下面的示例中,fixedBuffer
數組有一個固定大小,使用fixed
語句獲取第一個元素的指針,并通過該指針訪問數組元素。fixed
語句pin實例字段fixedBuffer
到內存中的一個特定位置。
internal unsafe struct Buffer { public fixed char fixedBuffer[128]; } internal unsafe class Example { public Buffer buffer = default; } private static void AccessEmbeddedArray() { var example = new Example(); unsafe { // Pin the buffer to a fixed location in memory. fixed (char* charPtr = example.buffer.fixedBuffer) { *charPtr = 'A'; } // Access safely through the index: char c = example.buffer.fixedBuffer[0]; Console.WriteLine(c); // Modify through the index: example.buffer.fixedBuffer[0] = 'B'; Console.WriteLine(example.buffer.fixedBuffer[0]); } }
128個元素的char
數組大小是256個字節。固定大小的char
緩沖區中每個字符固定占兩個字節,不管采用哪種編碼。
數組的大小是相同的,即使char緩沖區被封送到 API 方法或結構struct
設置為CharSet = CharSet.Auto
/ CharSet = CharSet.Ansi
固定大小的bool
數組,其元素占用的大小固定為1字節。bool
數組不適合創建位數組或緩沖區。
CharSet
固定大小的緩沖區使用 System.Runtime.CompilerServices.UnsafeValueTypeAttribute
進行編譯,指示公共語言運行時 (CLR) 某個類型包含可能溢出的非托管數組。
使用 stackalloc
分配的內存還會在 CLR 中自動啟用緩沖區溢出檢測功能。
unsafe struct
中可以使用固定大小的緩沖區。比如前面的Buffer
:
internal unsafe struct Buffer { public fixed char fixedBuffer[128]; }
編譯器會生成下面帶特性的Buffer
:
internal struct Buffer { [StructLayout(LayoutKind.Sequential, Size = 256)] [CompilerGenerated] [UnsafeValueType] public struct <fixedBuffer>e__FixedBuffer { public char FixedElementField; } [FixedBuffer(typeof(char), 128)] public <fixedBuffer>e__FixedBuffer fixedBuffer; }
固定大小的緩沖區不同于常規數組的幾個方式如下:
- 只能在
unsafe
上下文中使用 - 只能作為結構的實例字段
- 始終是矢量或一維數組。
- 聲明應包括長度,如
fixed char id[8]
,不能使用fixed char id[]
。
如何使用指針復制字節數組
下面的通過unsafe
關鍵字使Copy方法中可以使用指針;fixed
語句用于聲明source
和destination
數組的指針。
fixed
語句pin源和目標數組在內存中的位置不被垃圾收集移動。當fixed
塊執行結束后,數組的內存塊會解除固定(unpinned
)。
該示例使用索引(indices
-指標)而不是第二個非托管指針訪問兩個數組的元素。pSource
和 pTarget
指針的聲明固定數組。
static unsafe void Copy(byte[] source, int sourceOffset, byte[] target, int targetOffset, int count) { // If either array is not instantiated, you cannot complete the copy. if ((source == null) || (target == null)) { throw new System.ArgumentException("source or target is null"); } // If either offset, or the number of bytes to copy, is negative, you // cannot complete the copy. if ((sourceOffset < 0) || (targetOffset < 0) || (count < 0)) { throw new System.ArgumentException("offset or bytes to copy is negative"); } // If the number of bytes from the offset to the end of the array is // less than the number of bytes you want to copy, you cannot complete // the copy. if ((source.Length - sourceOffset < count) || (target.Length - targetOffset < count)) { throw new System.ArgumentException("offset to end of array is less than bytes to be copied"); } // The following fixed statement pins the location of the source and // target objects in memory so that they will not be moved by garbage // collection. fixed (byte* pSource = source, pTarget = target) { // Copy the specified number of bytes from source to target. for (int i = 0; i < count; i++) { pTarget[targetOffset + i] = pSource[sourceOffset + i]; } } }
參考
- Unsafe code, pointer types, and function pointers
原文鏈接:https://juejin.cn/post/7175167895406641189
相關推薦
- 2022-07-26 go通過channel獲取goroutine的處理結果
- 2022-04-12 python關閉print輸出信息詳情_python
- 2022-12-05 Linux系統查看服務器帶寬及網絡使用情況的具體方法_服務器其它
- 2022-04-17 WPF框架Prism中導航Navigation用法介紹_基礎應用
- 2022-08-23 React?Native中實現動態導入的示例代碼_React
- 2022-06-01 AndriodStudio利用ListView和數據庫實現簡單學生管理_Android
- 2022-03-22 C++抽象數據類型介紹_C 語言
- 2022-02-04 ImportError: No module named ‘flask_sqlalchemy‘
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支