日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# unsafe模式内存操作深入探索

發(fā)布時(shí)間:2025/3/18 C# 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# unsafe模式内存操作深入探索 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C# unsafe模式內(nèi)存操作深入探索

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks;namespace ConsoleApplication1 {class CTile{public CTileData _dat;public int x;}//結(jié)構(gòu)體可能分配在堆上,也可能分配在棧上//1,結(jié)構(gòu)體中無引用類型,則://a:若該結(jié)構(gòu)體類型的變量X是類的內(nèi)部成員,由于類是引用類型,則X分配在堆上//b:若非a的情況,則結(jié)構(gòu)體分配在棧上unsafe struct CTileData//為了避開C#數(shù)組,因?yàn)樗且粋€(gè)引用類型。 {public int var1;public float var2;public fixed sbyte name[6]; //使用C++風(fēng)格的定長(zhǎng)數(shù)組,避免C#風(fēng)格的引用數(shù)組public float var3;}//2,結(jié)構(gòu)體中有引用類型,則該結(jié)構(gòu)體類型的變量分配在堆上struct CTileData2{public int var1;public float var2;public string name;//有引用類型,結(jié)構(gòu)體無論如何都分配在堆上了public float var3;}unsafe class Program{[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]static extern void MemCopy(void* dest, void* src, int count);static void Main(string[] args){unsafe{var tile = new CTile();var dat = new CTileData();//棧上的結(jié)構(gòu)體,可以直接取地址,堆上的則不行,因?yàn)槎焉蠈?duì)象的地址是不定的(原因是內(nèi)存管理)//同理,堆上的任何對(duì)象都不可直接取地址,必須使用fixed才行CTileData* ptd = &dat; var ms = new MemoryStream();var binWr = new BinaryWriter(ms, Encoding.ASCII);binWr.Write(10);binWr.Write(3.2f);binWr.Write("hello");//先寫入1字節(jié)長(zhǎng)度(也就是說字符串長(zhǎng)度最大256???),然后寫入hellobinWr.Write(109.9f);var bts = ms.GetBuffer();fixed (void* pbts = bts)//堆對(duì)象,必須使用fixed語法才能取地址 {var sz = sizeof(CTileData);MemCopy(ptd, pbts, sz);fixed (void* pt = &tile._dat)//堆上的結(jié)構(gòu)體(堆對(duì)象),必須使用fixed語法才能取地址 {MemCopy(pt, pbts, sz);}}var v1 = ptd->var1; //10var v2 = ptd->var2; //3.2var strlen = *(ptd->name); //取一字節(jié),字符串長(zhǎng)度 5var straddr = ptd->name + 1; //跳過一字節(jié),到達(dá)字符串起始地址string name = new string(straddr, 0, strlen); //hellovar v3 = ptd->var3; //這里數(shù)據(jù)不對(duì),原因????//結(jié)論:C#真不適合做內(nèi)存操作,若使用marshal,雖然方便了一些,但要經(jīng)過一次內(nèi)存申請(qǐng)和一次內(nèi)存釋放,一次轉(zhuǎn)換到C#結(jié)構(gòu)的過程,很蹩腳 }}} }

?

posted on 2018-04-06 17:31 時(shí)空觀察者9號(hào) 閱讀(...) 評(píng)論(...) 編輯 收藏

總結(jié)

以上是生活随笔為你收集整理的C# unsafe模式内存操作深入探索的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。