欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#使用StructLayout特性來控制內(nèi)存結(jié)構(gòu)的操作代碼

 更新時(shí)間:2024年10月15日 09:05:36   作者:△曉風(fēng)殘?jiān)漏e  
在C#中,內(nèi)存布局對(duì)于性能優(yōu)化和與非托管代碼的互操作性至關(guān)重要,StructLayout特性允許開發(fā)者控制結(jié)構(gòu)在內(nèi)存中的布局方式,本文給大家介紹了C#使用StructLayout特性來控制內(nèi)存結(jié)構(gòu)的操作,需要的朋友可以參考下

C#在調(diào)用WInAPI函數(shù)時(shí),可能會(huì)看到如下的聲明

[StructLayout(LayoutKind.Sequential)]
         public struct RECT
         {
             public int Left;
             public int Top;
             public int Right;
             public int Bottom;
         }

在類或者結(jié)構(gòu)體前面帶上了

[StructLayout(LayoutKind.Sequential)]

StructLayoutAttribute特性的作用是允許你控制內(nèi)存中類或結(jié)構(gòu)的數(shù)據(jù)字段的物理布局。

平常我們?cè)贑#代碼中使用類或者結(jié)構(gòu)體時(shí),不需要使用此特性。但在與非托管代碼時(shí)交互,需要使用StructLayoutAttribute特性來控制類型的非托管布局。

StructLayoutAttribute常用構(gòu)造函數(shù)是:

StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind)

System.Runtime.InteropServices.LayoutKind是一個(gè)枚舉類型,有三個(gè)取值。

LayoutKind.Sequential

強(qiáng)制按成員的顯示順序?qū)ζ溥M(jìn)行排列。對(duì)于blittable類型,在托管和非托管內(nèi)存中控制布局。對(duì)于non-blittable類型,它會(huì)在將類或者結(jié)構(gòu)體封送到非托管代碼時(shí)控制布局(換言之,如果僅在C#中進(jìn)行調(diào)用,不會(huì)做任何操作,在與非托管代碼交互時(shí),僅控制送入非托管代碼的布局)

LayoutKind.Explicit

控制每個(gè)數(shù)據(jù)成員的精確位置,這會(huì)影響托管和非托管代碼中的布局,不管是blittable類型還是non-blittable類型。,使用LayoutKind.Explicit時(shí),需要使用FieldOffsetAttribute特性指示類型中每個(gè)字段的位置。

默認(rèn)情況下,編譯器會(huì)將LayoutKind.Sequential應(yīng)用到結(jié)構(gòu)體,對(duì)于類,需要顯式應(yīng)用LayoutKind.Sequential值。

到這里也就明白了,以后在調(diào)用API函數(shù)時(shí),如果使用的是結(jié)構(gòu)體,就不再需要下面這句代碼了。

[StructLayout(LayoutKind.Sequential)]

下面用示例代碼說明一下

這里以獲取桌面窗體的寬高為例,需要用到的API函數(shù)是

HWND GetDesktopWindow();

BOOL GetWindowRect(HWND hWnd, LPRECT lpRect );

其中LPRECT是指向RECT結(jié)構(gòu)體的指針,RECT結(jié)構(gòu)聲明如下:

typedef struct tagRECT {
   LONG left;
   LONG top;
   LONG right;
   LONG bottom;
 } RECT, *PRECT, *NPRECT, *LPRECT;

使用結(jié)構(gòu)體時(shí),調(diào)用代碼如下:

using System;
using System.Runtime.InteropServices;
 namespace ConsoleApp10
 {
     public struct RECT
     {
         public int Left;
         public int Top;
         public int Right;
         public int Bottom;
     }
 
     class Program
     {
         [DllImport("user32.dll")]
         private static extern IntPtr GetDesktopWindow();
 
         [DllImport("user32.dll", SetLastError = true)]
         private static extern int GetWindowRect(IntPtr hwnd, out RECT rc);
 
         static void Main(string[] args)
         {
             IntPtr hwnd = GetDesktopWindow();
             RECT rect;
             GetWindowRect(hwnd, out rect);
             Console.WriteLine($"Left:{rect.Left},Top:{rect.Top},Right:{rect.Right},Bottom:{rect.Bottom}");
         }
     }
 }

運(yùn)行結(jié)果如下:

下面我們來看一下,把結(jié)構(gòu)體換成類的情況

 using System;
 using System.Runtime.InteropServices;
 
 namespace ConsoleApp10
 {
     public class RECT
     {
         public int Left;
         public int Top;
         public int Right;
         public int Bottom;
    }
 
     class Program
     {
         [DllImport("user32.dll")]
         private static extern IntPtr GetDesktopWindow();
 
         [DllImport("user32.dll", SetLastError = true)]
         private static extern int GetWindowRect(IntPtr hwnd,RECT rc);
 
         static void Main(string[] args)
         {
             IntPtr hwnd = GetDesktopWindow();
             RECT rect = new RECT();
             GetWindowRect(hwnd, rect);
             Console.WriteLine($"Left:{rect.Left},Top:{rect.Top},Right:{rect.Right},Bottom:{rect.Bottom}");
         }
     }
 }

運(yùn)行結(jié)果如下:

運(yùn)行結(jié)果并不正常

把類修改一下,帶上[StructLayout(LayoutKind.Sequential)]

     [StructLayout(LayoutKind.Sequential)]
     public class RECT
     {
         public int Left;
         public int Top;
         public int Right;
         public int Bottom;
     }

再次運(yùn)行,發(fā)現(xiàn)結(jié)果正常了

最后再看看LayoutKind.Explicit的情況,調(diào)用代碼如下

 using System;
 using System.Runtime.InteropServices;
 
 namespace ConsoleApp10
 {
     [StructLayout(LayoutKind.Explicit)]
     public class RECT
     {
         [FieldOffset(0)]public int Left; //FieldOffset用于指示類或結(jié)構(gòu)的非托管表示形式中字段的物理位置
         [FieldOffset(4)]public int Top;
         [FieldOffset(8)]public int Right;
         [FieldOffset(12)]public int Bottom;
     }
 
     class Program
     {
         [DllImport("user32.dll")]
         private static extern IntPtr GetDesktopWindow();
 
         [DllImport("user32.dll", SetLastError = true)]
         private static extern int GetWindowRect(IntPtr hwnd,[MarshalAs(UnmanagedType.LPStruct)]RECT rc);
 
         static void Main(string[] args)
         {
             IntPtr hwnd = GetDesktopWindow();
             RECT rect = new RECT();
             GetWindowRect(hwnd, rect);
             Console.WriteLine($"Left:{rect.Left},Top:{rect.Top},Right:{rect.Right},Bottom:{rect.Bottom}");
         }
     }
 }

以上就是C#使用StructLayout特性來控制內(nèi)存結(jié)構(gòu)的操作代碼的詳細(xì)內(nèi)容,更多關(guān)于C# StructLayout控制內(nèi)存結(jié)構(gòu)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#異步執(zhí)行任務(wù)的方法

    C#異步執(zhí)行任務(wù)的方法

    這篇文章主要介紹了C#異步執(zhí)行任務(wù)的方法,以一個(gè)簡(jiǎn)單實(shí)例形式分析了C#異步執(zhí)行的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • C#事件用法實(shí)例淺析

    C#事件用法實(shí)例淺析

    這篇文章主要介紹了C#事件用法,以實(shí)例形式分析了C#中事件的定義、觸發(fā)及處理相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Unity 實(shí)現(xiàn)貼花效果的制作教程

    Unity 實(shí)現(xiàn)貼花效果的制作教程

    有些游戲中的戰(zhàn)斗痕跡的效果會(huì)通過貼花來實(shí)現(xiàn)的,貼花的方式多種多樣。而在Unity中,有一種給官方文檔提供代碼的解決方案。本文將這些代碼的基礎(chǔ)上做一個(gè)繪圖的貼花效果,感興趣的童鞋可以參考一下
    2021-11-11
  • C#實(shí)現(xiàn)拼手氣紅包算法

    C#實(shí)現(xiàn)拼手氣紅包算法

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)拼手氣紅包算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C#開發(fā)微信門戶及應(yīng)用(2) 微信消息處理和應(yīng)答

    C#開發(fā)微信門戶及應(yīng)用(2) 微信消息處理和應(yīng)答

    文章主要為大家詳細(xì)介紹了C#開發(fā)微信門戶及應(yīng)用第二篇,微信消息處理和應(yīng)答,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • C# Path類---文件路徑解讀

    C# Path類---文件路徑解讀

    這篇文章主要介紹了C# Path類---文件路徑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • C# MemoryStream類案例詳解

    C# MemoryStream類案例詳解

    這篇文章主要介紹了C# MemoryStream類案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C#中XML基礎(chǔ)用法

    C#中XML基礎(chǔ)用法

    可擴(kuò)展標(biāo)記語言,標(biāo)準(zhǔn)通用標(biāo)記語言的子集,簡(jiǎn)稱XML。是一種用于標(biāo)記電子文件使其具有結(jié)構(gòu)性的標(biāo)記語言。這篇文章介紹了C#中XML基礎(chǔ)的用法,下面的實(shí)例代碼,大家可以看看
    2021-12-12
  • 詳解C#如何計(jì)算一個(gè)實(shí)例占用多少內(nèi)存

    詳解C#如何計(jì)算一個(gè)實(shí)例占用多少內(nèi)存

    我們都知道CPU和內(nèi)存是程序最為重要的兩類指標(biāo),那么有多少人真正想過一個(gè)類型的實(shí)例在內(nèi)存中究竟占多少字節(jié),本文就來用C#計(jì)算一下一個(gè)實(shí)例占用多少內(nèi)存吧
    2023-06-06
  • C#中圖片如何自適應(yīng)pictureBox大小

    C#中圖片如何自適應(yīng)pictureBox大小

    文章描述了如何在C#中實(shí)現(xiàn)圖片自適應(yīng)pictureBox大小,并展示修改前后的效果,修改步驟包括兩步,作者分享了個(gè)人經(jīng)驗(yàn),希望對(duì)大家有所幫助
    2025-01-01

最新評(píng)論