亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#實現Struct結構體與IntPtr轉換的示例詳解

 更新時間:2025年06月05日 10:25:45   作者:阿蒙Armon  
在 C# 編程的世界里,我們常常會遇到需要與非托管代碼交互,或者進行一些底層內存操作的場景,下面小編就來分享兩段非常實用的 C# 擴展方法代碼,它們實現了結構體與IntPtr之間的轉換等功能

在 C# 編程的世界里,我們常常會遇到需要與非托管代碼交互,或者進行一些底層內存操作的場景。這時,IntPtr類型就顯得尤為重要,它可以表示一個指針或句柄,用來指向非托管內存中的數據。而結構體作為一種常用的數據結構,在與IntPtr進行數據傳遞和轉換時,往往需要一些繁瑣的操作。為了簡化這些操作,提高開發(fā)效率,我們可以通過擴展方法來封裝相關的功能。接下來,就為大家介紹兩段非常實用的 C# 擴展方法代碼,它們實現了結構體與IntPtr之間的轉換等功能。

一、代碼概覽

我們有兩個擴展方法類,分別是StructExtensions和IntPtrExtensions。StructExtensions類主要提供將結構體和結構體數組轉換為IntPtr的方法;IntPtrExtensions類則提供了將IntPtr轉換回結構體、將IntPtr指向的內存數據轉換為字節(jié)數組,以及釋放IntPtr所占用的非托管內存的方法。

1. StructExtensions 類

using System;
using System.Runtime.InteropServices;

public static class StructExtensions
{
    /// <summary>
    /// struct to IntPtr
    /// IntPtr使用完,需釋放
    /// </summary>
    /// <typeparam name="T">struct</typeparam>
    /// <param name="value">struct值</param>
    /// <returns>IntPtr</returns>
    public static IntPtr ToIntPtr<T>(this T value) where T : struct
    {
        var intptr = Marshal.AllocHGlobal(Marshal.SizeOf(value));
        Marshal.StructureToPtr(value, intptr, true);
        return intptr;
    }

    /// <summary>
    /// struct[] to IntPtr
    /// IntPtr使用完,需釋放
    /// </summary>
    /// <typeparam name="T">struct</typeparam>
    /// <param name="value">struct[]值</param>
    /// <returns>IntPtr</returns>
    public static IntPtr ToIntPtr<T>(this T[] value) where T : struct
    {
        var intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)) * value.Length);
        var longPtr = intPtr.ToInt64();
        for (var i = 0; i < value.Length; i++)
        {
            var rectPtr = new IntPtr(longPtr);
            Marshal.StructureToPtr(value[i], rectPtr, false);
            longPtr += Marshal.SizeOf(typeof(T));
        }
        return new IntPtr(longPtr);
    }
}

在這個類中,第一個ToIntPtr方法接受一個結構體類型的參數value,首先使用Marshal.AllocHGlobal方法在非托管內存中分配足夠的空間,空間大小由Marshal.SizeOf(value)確定,即結構體實例的大小。然后通過Marshal.StructureToPtr方法將結構體實例的值復制到分配的非托管內存中,并返回指向該內存的IntPtr。需要注意的是,使用完返回的IntPtr后,必須釋放其占用的內存,否則會導致內存泄漏。

第二個ToIntPtr方法則是針對結構體數組,它根據數組的長度和單個結構體的大小,在非托管內存中分配相應大小的空間,并返回指向該內存的IntPtr。不過,此方法只是分配了內存,并沒有將數組中的數據復制到內存中,如果需要復制數據,還需要進一步的操作。

2. IntPtrExtensions 類

using System;
using System.Runtime.InteropServices;

public static class IntPtrExtensions
{
    public static T ToStructure<T>(this IntPtr value) where T : struct
    {
        return (T)Marshal.PtrToStructure(value, typeof(T));
    }

    public static byte[] ToBytes(this IntPtr value, int size)
    {
        var bytes = new byte[size];
        Marshal.Copy(value, bytes, 0, size);
        return bytes;
    }

    public static void Free(ref this IntPtr value)
    {
        Marshal.FreeHGlobal(value);
    }
}

IntPtrExtensions類中的ToStructure方法,接受一個IntPtr類型的參數value,通過Marshal.PtrToStructure方法將IntPtr指向的非托管內存中的數據轉換為指定的結構體類型,并返回轉換后的結構體實例。

ToBytes方法將IntPtr指向的內存中的數據讀取到一個字節(jié)數組中。它接受一個表示內存大小的參數size,首先創(chuàng)建一個指定大小的字節(jié)數組,然后使用Marshal.Copy方法將IntPtr指向的內存數據復制到字節(jié)數組中,并返回該字節(jié)數組。

Free方法用于釋放IntPtr所占用的非托管內存,通過Marshal.FreeHGlobal方法來實現內存的釋放,由于需要修改IntPtr本身,所以參數使用了ref關鍵字。

二、使用示例

下面我們通過一個簡單的示例來展示這些擴展方法的具體使用:

using System;
using System.Runtime.InteropServices;

struct Point
{
   public int X;
   public int Y;
}


class Program
{
   static void Main()
   {
       var point = new Point { X = 10, Y = 20 };

       // 將結構體轉換為IntPtr
       var intPtr = point.ToIntPtr();

       // 將IntPtr轉換回結構體
       var newPoint = intPtr.ToStructure<Point>();


       Console.WriteLine($"X: {newPoint.X}, Y: {newPoint.Y}");


       // 釋放IntPtr占用的內存
       intPtr.Free();
       
       
       var points = { new Point { X = 1, Y = 2 }, new Point { X = 3, Y = 4 } };
       // 將結構體數組轉換為IntPtr
       var arrayIntPtr = points.ToIntPtr();


       // 這里可以添加將數組數據復制到內存的操作

       // 釋放IntPtr占用的內存
       arrayIntPtr.Free();
   }


}

在這個示例中,我們定義了一個Point結構體,然后分別演示了將結構體和結構體數組轉換為IntPtr,再將IntPtr轉換回結構體,以及釋放IntPtr所占用內存的整個過程。

三、注意事項

1.內存管理:正如前面多次提到的,使用Marshal.AllocHGlobal分配的非托管內存必須手動釋放,否則會造成內存泄漏。在實際應用中,要確保在合適的時機調用Free方法。

.2數據一致性:在將結構體數組轉換為IntPtr時,如果需要將數組數據復制到內存中,需要額外編寫代碼實現,否則IntPtr指向的內存中數據是未初始化的。

3.類型安全:在使用ToStructure方法時,要確保IntPtr指向的內存中的數據與目標結構體類型一致,否則可能會導致類型轉換錯誤或程序異常。

通過這些實用的擴展方法,我們可以更加便捷地在 C# 中處理結構體與IntPtr之間的數據轉換和內存操作,提高代碼的可讀性和可維護性。

到此這篇關于C#實現Struct結構體與IntPtr轉換的示例詳解的文章就介紹到這了,更多相關C# Struct結構體轉IntPtr內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C#連接數據庫的幾種方法

    C#連接數據庫的幾種方法

    這篇文章介紹了C#連接數據庫的幾種方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • 基于C#實現自定義計算的Excel數據透視表

    基于C#實現自定義計算的Excel數據透視表

    數據透視表(Pivot?Table)是一種數據分析工具,通常用于對大量數據進行匯總、分析和展示,本文主要介紹了C#實現自定義計算的Excel數據透視表的相關知識,感興趣的可以了解下
    2023-12-12
  • C# 前端無插件打印導出實現方式詳解

    C# 前端無插件打印導出實現方式詳解

    本文講述了使用C#實現前端無插件的打印和導出功能,介紹了相關技術和方法,適合需要在項目中實現相應功能的開發(fā)者參考
    2024-10-10
  • c#數據綁定之將datatabel的data添加listView

    c#數據綁定之將datatabel的data添加listView

    這篇文章主要介紹了c#將DataTabel的data添加ListView的示例,實現功能是通過響應UI Textbox 的值向ListView 綁定新添加的紀錄。 ,需要的朋友可以參考下
    2014-04-04
  • 利用C#實現分割GIF圖片

    利用C#實現分割GIF圖片

    這篇文章主要為大家詳細介紹了如何利用C#實現分割GIF圖片的功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以了解一下
    2022-12-12
  • 一篇文章說通C#的屬性Attribute

    一篇文章說通C#的屬性Attribute

    這篇文章主要給大家介紹了如何通過一篇文章說通C#的屬性Attribute,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Unity實現簡單虛擬搖桿

    Unity實現簡單虛擬搖桿

    這篇文章主要為大家詳細介紹了Unity實現簡單虛擬搖桿,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C#訪問PostGreSQL數據庫的方法

    C#訪問PostGreSQL數據庫的方法

    這次的項目中的一個環(huán)節(jié)要求我把PostGreSQL數據取出來,然后放到SqlServer里,再去處理分析。
    2013-04-04
  • C# 使用 OleDbConnection 連接讀取Excel的方法

    C# 使用 OleDbConnection 連接讀取Excel的方法

    這篇文章主要介紹了C# 使用 OleDbConnection 連接讀取Excel的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • C#中Winform窗體Form的關閉按鈕變灰色的方法

    C#中Winform窗體Form的關閉按鈕變灰色的方法

    這篇文章主要介紹了C#中Winform窗體Form的關閉按鈕變灰色的方法,對于C#程序界面的設計有一定的借鑒價值,需要的朋友可以參考下
    2014-08-08

最新評論