最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#實現(xiàn)Struct結(jié)構(gòu)體與IntPtr轉(zhuǎn)換的示例詳解

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

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

一、代碼概覽

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

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方法接受一個結(jié)構(gòu)體類型的參數(shù)value,首先使用Marshal.AllocHGlobal方法在非托管內(nèi)存中分配足夠的空間,空間大小由Marshal.SizeOf(value)確定,即結(jié)構(gòu)體實例的大小。然后通過Marshal.StructureToPtr方法將結(jié)構(gòu)體實例的值復(fù)制到分配的非托管內(nèi)存中,并返回指向該內(nèi)存的IntPtr。需要注意的是,使用完返回的IntPtr后,必須釋放其占用的內(nèi)存,否則會導(dǎo)致內(nèi)存泄漏。

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

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類型的參數(shù)value,通過Marshal.PtrToStructure方法將IntPtr指向的非托管內(nèi)存中的數(shù)據(jù)轉(zhuǎn)換為指定的結(jié)構(gòu)體類型,并返回轉(zhuǎn)換后的結(jié)構(gòu)體實例。

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

Free方法用于釋放IntPtr所占用的非托管內(nèi)存,通過Marshal.FreeHGlobal方法來實現(xiàn)內(nèi)存的釋放,由于需要修改IntPtr本身,所以參數(shù)使用了ref關(guān)鍵字。

二、使用示例

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

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 };

       // 將結(jié)構(gòu)體轉(zhuǎn)換為IntPtr
       var intPtr = point.ToIntPtr();

       // 將IntPtr轉(zhuǎn)換回結(jié)構(gòu)體
       var newPoint = intPtr.ToStructure<Point>();


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


       // 釋放IntPtr占用的內(nèi)存
       intPtr.Free();
       
       
       var points = { new Point { X = 1, Y = 2 }, new Point { X = 3, Y = 4 } };
       // 將結(jié)構(gòu)體數(shù)組轉(zhuǎn)換為IntPtr
       var arrayIntPtr = points.ToIntPtr();


       // 這里可以添加將數(shù)組數(shù)據(jù)復(fù)制到內(nèi)存的操作

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


}

在這個示例中,我們定義了一個Point結(jié)構(gòu)體,然后分別演示了將結(jié)構(gòu)體和結(jié)構(gòu)體數(shù)組轉(zhuǎn)換為IntPtr,再將IntPtr轉(zhuǎn)換回結(jié)構(gòu)體,以及釋放IntPtr所占用內(nèi)存的整個過程。

三、注意事項

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

.2數(shù)據(jù)一致性:在將結(jié)構(gòu)體數(shù)組轉(zhuǎn)換為IntPtr時,如果需要將數(shù)組數(shù)據(jù)復(fù)制到內(nèi)存中,需要額外編寫代碼實現(xiàn),否則IntPtr指向的內(nèi)存中數(shù)據(jù)是未初始化的。

3.類型安全:在使用ToStructure方法時,要確保IntPtr指向的內(nèi)存中的數(shù)據(jù)與目標(biāo)結(jié)構(gòu)體類型一致,否則可能會導(dǎo)致類型轉(zhuǎn)換錯誤或程序異常。

通過這些實用的擴展方法,我們可以更加便捷地在 C# 中處理結(jié)構(gòu)體與IntPtr之間的數(shù)據(jù)轉(zhuǎn)換和內(nèi)存操作,提高代碼的可讀性和可維護性。

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

相關(guān)文章

  • C#數(shù)據(jù)結(jié)構(gòu)之隊列(Quene)實例詳解

    C#數(shù)據(jù)結(jié)構(gòu)之隊列(Quene)實例詳解

    這篇文章主要介紹了C#數(shù)據(jù)結(jié)構(gòu)之隊列(Quene),結(jié)合實例形式較為詳細的講述了隊列的功能、原理與C#實現(xiàn)隊列的相關(guān)技巧,需要的朋友可以參考下
    2015-11-11
  • c#入門之類型轉(zhuǎn)換詳解

    c#入門之類型轉(zhuǎn)換詳解

    這篇文章主要介紹了c#的類型轉(zhuǎn)換詳解,類型轉(zhuǎn)換分兩種形式:隱式轉(zhuǎn)換、顯示轉(zhuǎn)換,下面是詳細介紹
    2014-04-04
  • unity實現(xiàn)攝像頭跟隨

    unity實現(xiàn)攝像頭跟隨

    把這個腳本賦給你的攝像機,再把游戲角色賦給character變量,之后就能實現(xiàn)攝像機平滑的跟隨player在地球的任一角落了。有需要的小伙伴可以參考下。
    2015-03-03
  • C#組合模式實例詳解

    C#組合模式實例詳解

    這篇文章主要介紹了C#組合模式,實例分析了C#實現(xiàn)組合模式的原理與相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • C#實現(xiàn)在PDF文檔中應(yīng)用多種不同字體

    C#實現(xiàn)在PDF文檔中應(yīng)用多種不同字體

    在PDF文檔中,可繪制不同字體樣式、不同語言的文字,可通過使用Standard字體、TrueType字體、CJK字體或者自定義(私有)等字體類型。本文將具體介紹實現(xiàn)的方法,需要的可以參考一下
    2022-01-01
  • C#程序員應(yīng)該養(yǎng)成的程序性能優(yōu)化寫法

    C#程序員應(yīng)該養(yǎng)成的程序性能優(yōu)化寫法

    工作和生活中經(jīng)??梢钥吹揭恍┏绦蛟?寫代碼的時候只關(guān)注代碼的邏輯性,而不考慮運行效率,其實這對大多數(shù)程序猿來說都是沒有問題的,不過作為一只有理想的CodeMonkey,我還是希望給大家分享一些性能優(yōu)化心得
    2017-08-08
  • C#實現(xiàn)汽車租賃系統(tǒng)項目

    C#實現(xiàn)汽車租賃系統(tǒng)項目

    這篇文章主要為大家詳細介紹了C#實現(xiàn)汽車租賃系統(tǒng)項目,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • c# 圓形識別方案和直線識別方案的參考示例

    c# 圓形識別方案和直線識別方案的參考示例

    這篇文章主要介紹了c# 圓形識別方案和直線識別方案的實現(xiàn)示例,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03
  • C#接口(Interface)用法分析

    C#接口(Interface)用法分析

    這篇文章主要介紹了C#接口(Interface)用法,較為詳細的分析了C#中接口的功能、實現(xiàn)及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • C# 結(jié)合 Javascript 測試獲取天氣信息

    C# 結(jié)合 Javascript 測試獲取天氣信息

    本文將介紹如何使用 C# 并結(jié)合 JavaScript 獲取天氣信息,獲取的數(shù)據(jù)來源于360瀏覽器首頁數(shù)據(jù),對C# 獲取天氣信息示例代碼感興趣的朋友一起看看吧
    2024-08-08

最新評論

南郑县| 尼玛县| 荃湾区| 舞钢市| 富民县| 肥东县| 镇宁| 皋兰县| 山西省| 武夷山市| 惠水县| 衡东县| 泗水县| 常德市| 千阳县| 盐亭县| 普陀区| 珠海市| 若羌县| 工布江达县| 南京市| 凤山县| 黄浦区| 密云县| 阳山县| 汶上县| 前郭尔| 六盘水市| 醴陵市| 砀山县| 齐齐哈尔市| 西峡县| 前郭尔| 太仆寺旗| 崇左市| 金沙县| 舟曲县| 德令哈市| 海盐县| 青川县| 什邡市|